Bu sensörle çalışmaya başladım, örnek olsun. Boş durmayalım, tv de Hürremi seyretmeyelim.
sensör onewire çalışıyor ama biraz farklı adresleme kullanamıyorsunuz sanırım.
http://www.micro4you.com/files/sensor/DHT11.pdf (http://www.micro4you.com/files/sensor/DHT11.pdf)
bazı yerlerde kodlar buldum ama adam öyle bir yazmış ki anlamak mümkün değil (yada ben yetemiyorum adamın günahını almayalım.)
konuşmaya başlayalım.
şimdilik
int main (void)
{
SystemInit();
initGPIOasOutput();
initTIM2();
while(1){
GPIO_ResetBits(GPIOD,GPIO_Pin_12);
delay_us(18000);
GPIO_SetBits(GPIOD,GPIO_Pin_12);
delay_us(40);
initGPIOasInput();
}
}
gibi bir init yazdım, sistemi ayağa kaldırıyor ama nedense hep 0 bilgisi alıyorum.
(http://s30.postimg.cc/43zi1m73x/Ads_z1.jpg) (http://postimg.cc/image/43zi1m73x/)
(http://s23.postimg.cc/j564bb807/Ads_z2.jpg) (http://postimg.cc/image/j564bb807/)
Data hattına pullup direnci eklediniz değil mi?
Son resimi baktım da hepsi 0 olarak gelmemiş. Sağdan 1. ve 3. veri baytlarında lojik 1 seviyesine denk düşen sinyaller var.
Veri kağıdından 26-28µS için lojik 0, 70 µs için lojik 1 tanımlanmış...
evet hocam pul up mevcut
mesaj birleştirme:: 08 Mayıs 2014, 23:54:01
Alıntı yapılan: ambar7 - 08 Mayıs 2014, 23:14:11
Veri kağıdından 26-28µS için lojik 0, 70 µs için lojik 1 tanımlanmış...
Hocam burayı biraz açarmısınız ne demek istediniz ?
1 wire Lojik sinyalleri değerlendirirken zamana göre değerlendiriyoruz zaten bunu biliyorsunuz.
Veri kağıdından
26-28µs için lojik 0
70 µs için lojik 1 tanımlanmış...
Programınız bu değerlendirmeyi yapmıyor sanırım.
nasıl yaptığınızı bilmiyorum,
Okuma için
Ama bunu okunan sinyalin basitçe timer'ı kurar 50µs+80µs için 1 wire inen kenarıda çalıştırırım
timer çalışırken 1 wire sinyalini takip ederim tekrar inen kenar geldiğinde timer durdurur,
sayıcı registerini okur ,
sayıcı registerini sıfırlar
ve timer tekrar çalıştırıım,
bu arada timer değerini incelerim şimdi 100µs altında ise (50+28µ olması durumu oluyor) lojik 0 olarak değerlendiririm,
100µs üzerinde (50+70µs) ise lojik 1 olarak değerlendiririm... (artık sayıcı registerlerde kaça denk geliyorsa)
Hocam Muhtemelen elimdeki Lojik Analizör test edemiyor.
evet şu an gelen bilgi
0x29 0x00 0x19 0x00 0x42 toplamda 40 bit
mesaj birleştirme:: 09 Mayıs 2014, 00:26:49
41rh+25c=66(checksum)
doğru bilgi sanki
Evet Lojik analizör değerlendirmesinde bir sıkıntı var galiba. Çünkü sinyal değişimleri son verdiğiniz resimde görülebiliyor..
evet doğru çalışıyor (gittim su kaynattım :) )
ama anlamadığım rh decimal ile temp decimaller hep 0x00 çıkıyor.
Alıntı yapılan: muhittin_kaplan - 09 Mayıs 2014, 00:49:37
evet doğru çalışıyor (gittim su kaynattım :) )
ama anlamadığım rh decimal ile temp decimaller hep 0x00 çıkıyor.
Sıcaklık ve Nem değerlerinin ondalık hanesinin "0" çıkması normal hocam. Ne kadar DHT11 test ettiysem hepsi öyleydi...
DHT11 picpro ile ccs c ile denemiştim. Örnek xx.00 *C xx.00 nem çıkıyor.
DHT22 de böyle değil.
Veri kağıdındaki
"Detailed Specifications:" başlığı altına bakılırsa;
Humidity Resolution :1%RH (8 bit)
Temperature Accuracy: ±1℃ ile ±2℃ (8bit)
olduğu görülür. Bu da Decimel sayının 0 olmasını gerektirir.
şuan aldığım değerlerin ilk 4 ünü usarttan pc ye gönderiyorum
System is Start
Value= 84 23 24 69 23 değerlerini doğru olarak alıyorum.
initGPIOasInput();
while(1){
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)) //0 olan boş geçiliyor
TIM2->CNT=0;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[0]=TIM_GetCounter(TIM2);
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))//0 olan boş geçiliyor
TIM2->CNT=0;
while (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[1]=TIM_GetCounter(TIM2);
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))//0 olan boş geçiliyor
TIM2->CNT=0;
while (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[2]=TIM_GetCounter(TIM2);
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))//0 olan boş geçiliyor
TIM2->CNT=0;
while (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[3]=TIM_GetCounter(TIM2);
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))//0 olan boş geçiliyo
TIM2->CNT=0;
while (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[4]=TIM_GetCounter(TIM2);
sprintf(str, "Value= %d %d %d %d %d \r\n", deger[0],deger[1],deger[2],deger[3],deger[4]);
USART_puts(USART1,str);
}
}
daha optimize kod yazmak isteyen vaamı ::)
Alıntı Yapdaha optimize kod yazmak isteyen vaamı ::)
while(1){
for (ii=0; ii<MX_DEGER;ii++)
{
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)) //0 olan boş geçiliyor
TIM2->CNT=0;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[ii]=TIM_GetCounter(TIM2);
}
// print...
}
Alıntı yapılan: picusta - 11 Mayıs 2014, 01:02:06
while(1){
for (ii=0; ii<MX_DEGER;ii++)
{
while(!GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1)) //0 olan boş geçiliyor
TIM2->CNT=0;
while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1))
deger[ii]=TIM_GetCounter(TIM2);
}
// print...
}
Öncelikle tebrikler.
Ama kodların ikiside optimize değil, STM32f4 sadece DHT11'e çalışıyor, halbuki DHT11, STM32'ye çalışması lazımdı. En iyi yollardan biri Exti veya capture interrupt. Mesela her düşen kenarda capture ederken yükselen kenarda timer clear edilir veya tersi. İşlemci yükü %1 diyelim.
Mesajı yazarken buldum bundan bile iyisi var, Exti trigger, uart ve dma ile yapılır. Tümünü exti trigger ile DMA okur, okuyunca, DMA transfer complete interrupt'ta, usart dma çalıştırılır. Tümümü basınca istersen haber verir istersen scan yapar. Sanırım bundan daha iyisi yok.
yavaştan adam oluyor. dew point hesaplayalım birde
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};
initGPIOasOutput();
GPIO_ResetBits(GPIOD,GPIO_Pin_1);
delay_us(18000);
GPIO_SetBits(GPIOD,GPIO_Pin_1);
delay_us(40);
initGPIOasInput();
//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];
}
Merhaba buradaki (http://www.expkits.com/?s=exs03_stm32.htm) kodlardan faydalanabilirsiniz sanırım.
#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"
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];
}