Arduino DHT11 okurken hata

Başlatan Cemre., 13 Eylül 2014, 22:52:31

Cemre.

#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <DHT11.h>
#define DHT11PIN 2

dht11 DHT11;

LiquidCrystal lcd (8,9,4,5,6,7);
int valueArray[] = {0,EEPROM.read(1),EEPROM.read(2),EEPROM.read(3),EEPROM.read(4)};
int currentMenuItem = 0;
int changeState = 0;
int lastState = 0;
int valueTemperature = 0;
int valueHumidity = 0;
void setup()
 { // put your setup code here, to run once:
   lcd.begin (16,2);
   lcd.print (" NEM - SICAKLIK ");
 }

void loop()
 {
   int sensorStatus = DHT11.read(DHT11PIN);
   if (sensorStatus == 0){
   valueTemperature = DHT11.temperature;
   valueHumidity = DHT11.humidity;
   mainMenu(); 
   } else {
   lcd.setCursor(0,1);
   lcd.print ("Hata");
   }
 }
 
void mainMenu()
{
   int state = 0;
   int x = analogRead (0);
   
	  if (x < 100){ //sağ - sayfa değiştir
   state = 1;
   } else if (x < 200){ //yukarı - değer artır
   state = 2;
   } else if (x < 400){ //aşağı - değer azalt
   state = 3;
   } else if (x < 600){ //sol - sayfa değiştir
   state = 4;
   } else if (x < 800){ //seç - değer değiştir
   state = 5;
   }
   
   if(currentMenuItem < 0 || currentMenuItem > 4){
      currentMenuItem = 0;
   }
      
   if(state != lastState){
      if (state == 1){ //sağ
	 currentMenuItem = currentMenuItem +1;
	 changeState = 0;  //sayfa değiştiğinde set'i kapat
      } else if (state == 2 && changeState == 1){
	 valueChangeUp(currentMenuItem);
      } else if (state == 3 && changeState == 1){
	 valueChangeDown(currentMenuItem);
      } else if (state == 4){
      	 currentMenuItem = currentMenuItem -1;
	 changeState = 0;  //sayfa değiştiğinde set'i kapat
      } else if (state == 5){
	 if(currentMenuItem == 1 || currentMenuItem == 2){
	    changeState = 1;   //set'i aç
	 }
      }
      displayMenu(currentMenuItem);
      lastState = state;
   }
   delay(5);
}

void displayMenu(int page){
   switch(page){
      case 0:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print(" NEM - SICAKLIK ");
	 lcd.setCursor(0,1);
	 lcd.print((float)valueTemperature, 1); //DHT11 sensörden gelen veriler
	 lcd.print((char)223);
	 lcd.print("C  ");
	 lcd.print((float)valueHumidity, 1);
	 lcd.print("%");
	 break;
      case 1:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("NEM max");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[1]);
	 break;
      case 2:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("NEM min");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[2]);
	 break;
      case 3:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("SICAKLIK max");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[3]);
	 break;
      case 4:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("SICAKLIK min");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[4]);
	 break;
      }
}

void valueChangeUp(int valueNumber){
      if(valueArray[valueNumber] < 50){
	 valueArray[valueNumber] = valueArray[valueNumber] +1;
      } else {
	 valueArray[valueNumber] = 0;
      }
      EEPROM.write(valueNumber,valueArray[valueNumber]);
}

void valueChangeDown(int valueNumber){
     if(valueArray[valueNumber] > 0){
	 valueArray[valueNumber] = valueArray[valueNumber] -1;
      } else {
	 valueArray[valueNumber] = 50;
      }
      EEPROM.write(valueNumber,valueArray[valueNumber]);
}


Yukarıdaki kodları lcd'de menülü bir görüntü oluşturmak için yazdım. lcd'ye görüntü basmak için displayMenu fonksiyonunu kullanıyorum ve fonksiyon şuan için yanlızca butona basıldığında çağırılıyor. Bu nedenle butonlara basılmayan herhangi bir zamanda sensör değeri değiştiğinde lcd'ye yansımıyor. Sensör okuma fonksiyonu da loop içinde olduğundan çok fazla çağırılıyor. 2 saniyede bir sensörü okuyup ekranı butonlardan bağımsız yenilemek için nasıl bir eklenti yapmak gerekir?

Bir de max-min değerleri eeprom'a yazdırmaya çalıştım, bu şekilde her butona basıldığında veriyi eeproma yazıp her defasında eepromdan okuyor, bu sakıncalı bir durum mudur?
Teşekkürler.

Burak B

#1
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <DHT11.h>
#define DHT11PIN 2

dht11 DHT11;

/* Sensorü okumak için kullanılacak zaman sayacımız. */
unsigned long sensor_tick;

LiquidCrystal lcd (8,9,4,5,6,7);
int valueArray[] = {0,EEPROM.read(1),EEPROM.read(2),EEPROM.read(3),EEPROM.read(4)};
int currentMenuItem = 0;
int changeState = 0;
int lastState = 0;
int valueTemperature = 0;
int valueHumidity = 0;
void setup()
 { 
   // put your setup code here, to run once:
   lcd.begin (16,2);
   lcd.print (" NEM - SICAKLIK ");
 
  /* Kart başlangıcından itibaren geçen milisaniye cinsinden süre zaman sayacına yazılıyor. */
  sensor_tick = millis();
 }

void loop()
 {
   /* Sensör zaman sayacını son güncellememizden bu yana 2sn geçti mi ?*/
    if (millis()-sensor_tick>2000){

    /* Sensor zaman sayacını güncelle. */
    sensor_tick=millis(); 

    valueTemperature = DHT11.temperature;
    valueHumidity = DHT11.humidity;

   } 
   /* Ana menü sensörden bağımsız olarak sürekli çağrılır. */
    mainMenu(); 

 }
 
void mainMenu()
{
   int state = 0;
   int x = analogRead (0);
   
      if (x < 100){ //sağ - sayfa değiştir
   state = 1;
   } else if (x < 200){ //yukarı - değer artır
   state = 2;
   } else if (x < 400){ //aşağı - değer azalt
   state = 3;
   } else if (x < 600){ //sol - sayfa değiştir
   state = 4;
   } else if (x < 800){ //seç - değer değiştir
   state = 5;
   }
   
   if(currentMenuItem < 0 || currentMenuItem > 4){
      currentMenuItem = 0;
   }
      
   if(state != lastState){
      if (state == 1){ //sağ
     currentMenuItem = currentMenuItem +1;
     changeState = 0;  //sayfa değiştiğinde set'i kapat
      } else if (state == 2 && changeState == 1){
     valueChangeUp(currentMenuItem);
      } else if (state == 3 && changeState == 1){
     valueChangeDown(currentMenuItem);
      } else if (state == 4){
      	 currentMenuItem = currentMenuItem -1;
     changeState = 0;  //sayfa değiştiğinde set'i kapat
      } else if (state == 5){
     if(currentMenuItem == 1 || currentMenuItem == 2){
        changeState = 1;   //set'i aç
     }
      }
      displayMenu(currentMenuItem);
      lastState = state;
   }
   delay(5);
}

void displayMenu(int page){
   switch(page){
      case 0:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print(" NEM - SICAKLIK ");
     lcd.setCursor(0,1);
     lcd.print((float)valueTemperature, 1); //DHT11 sensörden gelen veriler
     lcd.print((char)223);
     lcd.print("C  ");
     lcd.print((float)valueHumidity, 1);
     lcd.print("%");
     break;
      case 1:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("NEM max");
     lcd.setCursor(0,1);
     lcd.print(valueArray[1]);
     break;
      case 2:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("NEM min");
     lcd.setCursor(0,1);
     lcd.print(valueArray[2]);
     break;
      case 3:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SICAKLIK max");
     lcd.setCursor(0,1);
     lcd.print(valueArray[3]);
     break;
      case 4:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SICAKLIK min");
     lcd.setCursor(0,1);
     lcd.print(valueArray[4]);
     break;
      }
}

void valueChangeUp(int valueNumber){
      if(valueArray[valueNumber] < 50){
     valueArray[valueNumber] = valueArray[valueNumber] +1;
      } else {
     valueArray[valueNumber] = 0;
      }
      EEPROM.write(valueNumber,valueArray[valueNumber]);
}

void valueChangeDown(int valueNumber){
     if(valueArray[valueNumber] > 0){
     valueArray[valueNumber] = valueArray[valueNumber] -1;
      } else {
     valueArray[valueNumber] = 50;
      }
      EEPROM.write(valueNumber,valueArray[valueNumber]);
}


Yukarıdaki şekilde yaparsan sensör 2sn de bir okunur. Ayrıca programın akışı aksamaz ve lcd sürekli olarak ölçüm gösterebilir. EEPROM' a bu sıklıkta yazma yaparsan kısa sürede arızalanır.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

Kabil ATICI

timer kesmesi kullanabilirsin. Örnek uygulamalarda delay fonkisyonu kullanılmadan led söndür uygulamalarında olacak...

Yada arkadaşlar yapılmış uygulamayı göndermiş olacaklar
ambar7

Cemre.

EEPROM için ne gibi bir şey yapılabilir? Yazma işini değeri değiştirip set butonuna basınca yapsak, ama okumayı hep eepromdan yapsak sorun olur mu yine de?
Yanıtlarınız için teşekkürler..

Kabil ATICI

En son ayarları bitince yazdır.
Normalde bu tür okuma işleri 1 kez kite enerji verildiği zaman yaparsın bir daha okumaya ihtiyaç duymazsın.
Okuma işlemini her seferinde eepromdan yaptırmak hız açısından sınırlar.
ambar7

Cemre.

#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <DHT11.h>
#define DHT11PIN 2

dht11 DHT11;

LiquidCrystal lcd (8,9,4,5,6,7);
int valueArray[] = {0,EEPROM.read(1),EEPROM.read(2),EEPROM.read(3),EEPROM.read(4)};
int currentMenuItem = 0;
int changeState = 0;
int lastState = 0;
int valueTemperature = 0;
int valueHumidity = 0;
unsigned long sensor_tick;
void setup()
 { // put your setup code here, to run once:
   lcd.begin (16,2);
   lcd.print (" NEM - SICAKLIK ");
   sensor_tick = millis();
 }

void loop()
 { // put your main code here, to run repeatedly:
   if (millis()-sensor_tick > 1000){
   sensor_tick = millis();
   if (currentMenuItem > 0){
   } else {
   int sensorStatus = DHT11.read(DHT11PIN);
      if (sensorStatus == 0){
      valueTemperature = DHT11.temperature;
      valueHumidity = DHT11.humidity;
	 lcd.setCursor(0,1);
      	 lcd.print((float)valueTemperature, 1);
	 lcd.print((char)223);
	 lcd.print("C  ");
	 lcd.print((float)valueHumidity, 1);
	 lcd.print("%");
      } else {
      lcd.setCursor(0,1);
      lcd.print ("SENS OKUMA HATA");
      }
   }
   }
   mainMenu();
 }
 
void mainMenu()
{
   int state = 0;
   int x = analogRead (0);
   
	  if (x < 100){ //sağ - sayfa değiştir
   state = 1;
   } else if (x < 200){ //yukarı - değer artır
   state = 2;
   } else if (x < 400){ //aşağı - değer azalt
   state = 3;
   } else if (x < 600){ //sol - sayfa değiştir
   state = 4;
   } else if (x < 800){ //seç - değer değiştir
   state = 5;
   }
   
   if(currentMenuItem < 0 || currentMenuItem > 4){
      currentMenuItem = 0;
   }
      
   if(state != lastState){
      switch(state){
      case 1:
	 if(changeState == 1){
	    if(currentMenuItem < 4){
	    currentMenuItem = currentMenuItem +1;
	    } else {
	    currentMenuItem = 1;
	    }
	 }
	 break;
      case 2:
	 if(currentMenuItem != 0){
	 valueChangeUp(currentMenuItem);
	 }
	 break;
      case 3:
	 if(currentMenuItem != 0){
	 valueChangeDown(currentMenuItem);
	 }
	 break;
      case 4:
	 if(changeState == 1){
	    if(currentMenuItem > 0){
	    currentMenuItem = currentMenuItem -1;
	    } else {
	    currentMenuItem = 4;
	    }
	 }
	 break;
      case 5:
	 if(changeState == 0){
	    changeState = 1;   //set'i aç
	    currentMenuItem = 1;
	 } else {
	    changeState = 0;
	    currentMenuItem = 0;
	    EEPROM.write(1,valueArray[1]);
	    EEPROM.write(2,valueArray[2]);
	    EEPROM.write(3,valueArray[3]);
	    EEPROM.write(4,valueArray[4]);
	 }
	 break;
      }
      displayMenu(currentMenuItem);
      lastState = state;
   }
   delay(5);
}

void displayMenu(int page){
   switch(page){
      case 0:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print(" NEM - SICAKLIK ");
	 lcd.setCursor(0,1);
	 lcd.print((float)valueTemperature, 1); //DHT11 sensörden gelen veriler
	 lcd.print((char)223);
	 lcd.print("C  ");
	 lcd.print((float)valueHumidity, 1);
	 lcd.print("%");
	 break;
      case 1:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("NEM max");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[1]);
	 break;
      case 2:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("NEM min");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[2]);
	 break;
      case 3:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("SICAKLIK max");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[3]);
	 break;
      case 4:
	 lcd.clear();
	 lcd.setCursor(0,0);
	 lcd.print("SICAKLIK min");
	 lcd.setCursor(0,1);
	 lcd.print(valueArray[4]);
	 break;
      }
}

void valueChangeUp(int valueNumber){
      if(valueArray[valueNumber] < 100){
	 valueArray[valueNumber] = valueArray[valueNumber] +1;
      } else {
	 valueArray[valueNumber] = 0;
      }
}

void valueChangeDown(int valueNumber){
     if(valueArray[valueNumber] > 0){
	 valueArray[valueNumber] = valueArray[valueNumber] -1;
      } else {
	 valueArray[valueNumber] = 100;
      }
}


Önerilerinizle bu hale getirdim, şuan okuma ve yazdırma konusunda sıkıntı yok ancak, değer değiştirilen sayfalara yanlızca set butonuna basıldığında gitmesi gerekirken bazen sağ bazen sol bazen de aşağı tuşa bastığımda gidiyor, set tuşu normal görevini yapıyor, bunun dışında butonlar normal görevlerini yapıyor, acaba ADC kısmında mı bir sıkıntı var şuan yoksa değiştirdiğim kısımlarda mı?

mehmet

Buton okuduğunuz analog sinyalin
üst değerlerini de sınırlamanız
gerekmekte...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

Cemre.

case 4:
     if(changeState == 1){
        if(currentMenuItem > 0){ // currentMenuItem>1 olması gerekiyordu, hata yapmışım.
        currentMenuItem = currentMenuItem -1;
        } else {
        currentMenuItem = 4;
        }
     }
     break;