Genelde lm35 yada 1820 ile çalıştığımdan hiç örneğim yoktu. Elimizde bulunsun değilmi. SHT11 gibi PAHALI bir sensörü kullanmaktansa
dht11 kullanılabilir. Bu açıdan iyi bir seçim olduğunu düşünüyorum, fiyatı yaklaşık 1,5usd :). datashit
Sensör one wire çalışıyor. Bilinen onewire da MCU tarafından start bit gönderildiğinde Sensör tarafından bir adres gönderilir. bunda öyle bir durum yok. Mcu tarafından gönderilen start tan sonra Sensör “Veri Gönderimi hazır” anlamında 0-1 den okulan iki sinyal gönderiyor. Ardından 40 bitlik veriyi aynı hattan MCU ya gönderimini sağlıyor. bu 40 bir 8bit Nem,8bit NemOndalık, 8bit Sıcaklık,8Bit SıcaklıkOndalık ve son 8 bit veri doğruluğudur.
VeriDoğruluğu (CheckSum)=Rh+RhDec+Temp+TempDec
şeklinde hesaplanır
MCU ile bağlantısında ise Data ile VCC uçlarının arasına bir pullup direnci konulması gerekir. Sensör 3.3v yada 5 v ile çalışabiliyor.
OW bilindiği üzere sinyalin lojik seviyesinden değil sinyaldeki lojik 1 lerin süresiyle bilginin değerini hesaplıyor. bundan dolayı bu süreleri hesaplamak için bir timer kullanmak gerekti (tim2) bıu timer ı 1mikrosaniye lik sayma peryotlarına ayarldım. bunu yapabilmek için tabiki systemclock un bilmemiz gerekti (168mhz).
[EKLEME]:
Projeyi daha sonra DHT22 ile hazırlayıp SeriBlueTooth (HC05) ile pc ye gönderdim. Proje Kodları için Tıklayınız
Sensör one wire çalışıyor. Bilinen onewire da MCU tarafından start bit gönderildiğinde Sensör tarafından bir adres gönderilir. bunda öyle bir durum yok. Mcu tarafından gönderilen start tan sonra Sensör “Veri Gönderimi hazır” anlamında 0-1 den okulan iki sinyal gönderiyor. Ardından 40 bitlik veriyi aynı hattan MCU ya gönderimini sağlıyor. bu 40 bir 8bit Nem,8bit NemOndalık, 8bit Sıcaklık,8Bit SıcaklıkOndalık ve son 8 bit veri doğruluğudur.
VeriDoğruluğu (CheckSum)=Rh+RhDec+Temp+TempDec
şeklinde hesaplanır
MCU ile bağlantısında ise Data ile VCC uçlarının arasına bir pullup direnci konulması gerekir. Sensör 3.3v yada 5 v ile çalışabiliyor.
OW bilindiği üzere sinyalin lojik seviyesinden değil sinyaldeki lojik 1 lerin süresiyle bilginin değerini hesaplıyor. bundan dolayı bu süreleri hesaplamak için bir timer kullanmak gerekti (tim2) bıu timer ı 1mikrosaniye lik sayma peryotlarına ayarldım. bunu yapabilmek için tabiki systemclock un bilmemiz gerekti (168mhz).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_tim.h" #include "stm32f4xx_usart.h" #include "misc.h" #include "stdio.h" #include "math.h" void DHT11Read(u8 *Rh,u8 *RhDec,u8 *Temp,u8 *TempDec, u8 *ChkSum); float Fahrenheit(u8 celsius); float Kelvin(u8 celsius); double dewPointFast(double celsius, double humidity); void DHT11_delay_us(int us); void DHT11initGPIOasInput(void); void DHT11initGPIOasOutput(void); void DHT11initTIM2(void); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; void DHT11initTIM2(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 84000000-1;//1us TIM_TimeBaseStructure.TIM_Prescaler =84; //1us counter TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_Cmd(TIM2, ENABLE); } void DHT11initGPIOasOutput(void){ /* GPIOD Periph clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure); } void DHT11initGPIOasInput(void){ /* GPIOD Periph clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_Init(GPIOD, &GPIO_InitStructure); } void DHT11_delay_us(int us){ TIM2->CNT = 0; while((TIM2->CNT) <= us); } float Fahrenheit(u8 celsius) { return 1.8 * celsius + 32; } float Kelvin(u8 celsius) { return celsius + 273.15; } double dewPointFast(double celsius, double humidity) { double a = 17.271, b = 237.7, temp ; temp = (a * celsius) / (b + celsius) + log(humidity/100); return (b * temp) / (a - temp);; } void DHT11Read(u8 *Rh,u8 *RhDec,u8 *Temp,u8 *TempDec, u8 *ChkSum){ u8 temp; u8 j; u8 i; u8 Value[5]={0x00,0x00,0x00,0x00,0x00}; DHT11initGPIOasOutput(); GPIO_ResetBits(GPIOD,GPIO_Pin_1); DHT11_delay_us(18000); GPIO_SetBits(GPIOD,GPIO_Pin_1); DHT11_delay_us(40); DHT11initGPIOasInput(); //80us lik presence // while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)){} //52us 0 level //dht11 response and start to send signal 0-1 while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)){} //80us 1 level // for (j = 0; j < 5; ++j) {//5*8 toplam 40 bit Rh,rhdec,temp,tempdec,chksum for (i = 0; i < 8; ++i) { while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)){} //0 olan boş geçiliyor TIM_SetCounter(TIM2,0);//Sayıcıyı Sıfırla while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)){} temp=TIM_GetCounter(TIM2);//sayıcı değerini al (böylelikle zaman hesaplanıyor) if (temp<30) { Value[j]=Value[j]<<1; } else { Value[j]=Value[j]<<1; Value[j] =Value[j]+1; } } } *Rh=Value[0]; *RhDec=Value[1]; *Temp=Value[2]; *TempDec=Value[3]; *ChkSum=Value[4]; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
#include "dht11.h" #define MAX_STRLEN 12 // this is the maximum string length of our string in characters volatile char received_string[MAX_STRLEN+1]; // this will hold the recieved string void init_USART1(uint32_t baudrate){ GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStructure; /* enable APB2 peripheral clock for USART1 * note that only USART1 and USART6 are connected to APB2 * the other USARTs are connected to APB1 */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /* enable the peripheral clock for the pins used by * USART1, PB6 for TX and PB7 for RX */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /* This sequence sets up the TX and RX pins * so they work correctly with the USART1 peripheral */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate! GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain) GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins GPIO_Init(GPIOB, &GPIO_InitStruct); // now all the values are passed to the GPIO_Init() function which sets the GPIO registers GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); /* Now the USART_InitStruct is used to define the * properties of USART1 */ USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard) USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard) USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard) USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard) USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting /* Here the USART1 receive interrupt is enabled * and the interrupt controller is configured * to jump to the USART1_IRQHandler() function * if the USART1 receive interrupt occurs */ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff // finally this enables the complete USART1 peripheral USART_Cmd(USART1, ENABLE); } void USART_puts(USART_TypeDef* USARTx, volatile char *s){ while(*s){ // wait until data register is empty while( !(USARTx->SR & 0x00000040) ); USART_SendData(USARTx, *s); *s++; } } void USART1_IRQHandler(void){ // check if the USART1 receive interrupt flag was set if( USART_GetITStatus(USART1, USART_IT_RXNE) ){ static uint8_t cnt = 0; // this counter is used to determine the string length char t = USART1->DR; // the character from the USART1 data register is saved in t /* check if the received character is not the LF character (used to determine end of string) * or the if the maximum string length has been been reached */ if( (t != 'n') && (cnt < MAX_STRLEN) ){ received_string[cnt] = t; cnt++; } else{ // otherwise reset the character counter and print the received string cnt = 0; USART_puts(USART1, received_string); } } } int main (void) { SystemInit();//168mhz init_USART1(9600); DHT11initTIM2(); USART_puts(USART1, "System is Start rn"); u8 Rh,RhDec,Temp,TempDec,ChkSum; double devPoint; char str[20]; while(1){ DHT11Read(&Rh,&RhDec,&Temp,&TempDec,&ChkSum); devPoint=dewPointFast(Temp,Rh); sprintf(str, "Value= %dRh %d %dC %d %d %fDwP %fFah %fKelrn",Rh,RhDec,Temp,TempDec,ChkSum,devPoint,Fahrenheit(Temp),Kelvin(Temp)); USART_puts(USART1,str); DHT11_delay_us(500000); } } |
[EKLEME]:
Projeyi daha sonra DHT22 ile hazırlayıp SeriBlueTooth (HC05) ile pc ye gönderdim. Proje Kodları için Tıklayınız
Ziyaretci : 2082