无法从 DHT22 传感器读取温度

问题描述 投票:0回答:1

我在这个领域还是个新手。我做了一个项目,我需要读取房间(盒子)的温度。我尝试使用 DHT22 传感器读取温度,但总是失败。串行监视器显示的是 nan,而不是当前温度。当我尝试使用更简单的代码时,它起作用了。但是当我将其添加到菜单代码中时,它失败了。我不知道出了什么问题。 这是我的菜单代码 `

#include "PinChangeInterrupt.h"
#include "DHT.h"
#include "LiquidCrystal_I2C.h"
#include "Countimer.h"
#include "RBDdimmer.h"
#define DHTPIN 5
#define DHTTYPE DHT22
//#define PWM 9 //output, btw ini harusnya yg power ngga si?

DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
Countimer timer;

//encoder, constants won't change, used to set pin number
const int CLK = 8;
const int DT = 9;
const int SW = 10;
int buzzer = 6;
int fan = 7;

//dimmer setting
const int zeroCrossPin = 2;
const int adcPin = 3;
int MIN_POWER = 0;
int MAX_POWER = 50; //mau berapa terserah
int POWER_STEP = 2; //ini kayaknya gaperlu deh
int power = 0; //ini power yang akan dikeluarkan sabaraha
dimmerLamp adc(adcPin);

//PID variables
float set_temperature = 0; 
float temperature_read = 0.0;
float suhu;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
float PID_value = 0;
int button_pressed = 0;
int menu_activated = 0; //kayaknya ganti, nanti pikirin lagi
float last_set_temperature = 0;

//PID constanta, nilainya tentukan sendiri ngga si?
int kp = 90;
int ki = 30;
int kd = 80;

int PID_p = 0;
int PID_i = 0;
int PID_d = 0;
float last_kp = 0;
float last_ki = 0;
float last_kd = 0;
int PID_values_fix = 0;

int counter = 0;
int currentState;
int initState;
int buahPilih;
int buah;
//int menu;
//int setpoint;
//int error;
//int suhu;

//entah apaa
int buttonState;
int lastButtonState= LOW;
int lastDebounceTime = 0;
long debounceDelay = 50;
long longpressDelay = 500;
//unsigned long bebounceDelay = 0;

unsigned long countdownTime = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  pinMode(CLK, INPUT);
  pinMode(DT, INPUT);
  pinMode(SW, INPUT);
  digitalWrite(SW, HIGH);
  pinMode(buzzer, OUTPUT);
  pinMode(fan, OUTPUT);
  //pinMode(PWM, OUTPUT);
  // Setup Serial Monitor
  Serial.begin(9600);
  dht.begin();
  adc.begin(NORMAL_MODE, ON);
  // Read the initial state of CLK
  initState = digitalRead(CLK);
  //attachInterrupt(0, encoder_value, CHANGE);
  //attachInterrupt(1, encoder_value, CHANGE);
  //attachPCINT(digitalPinToPCINT(SW), button_pressed, CHANGE);
  Serial.println("Main menu: ");
  Serial.println("Pilih buah untuk dikeringkan");
  lcd.setCursor(0, 0);
  lcd.println("Welcome to dehydrator");
  lcd.setCursor(0, 1);
  lcd.println("Pilih buah: ");
  delay(2000);
  geser();
}

void loop() {
  //tampilan
  encoder_value();
  int b = checkButton();
  if (b == 1) clickEvent(); //memilih set point (buahnya yg mana)
  if (b == 2) doubleClickEvent(); //doing the PID dan seabrek pengendalian pokoknya
  if (b == 3) holdEvent(); //reset, mulai awal
  //float suhu = dht.readTemperature();
}

void encoder_value() {
  //read current state of CLK
  currentState = digitalRead(CLK);
  // if last and current are different, we can be sure that the pulse occured
  if (currentState != initState && currentState == 1) {
    //encoder rorate counterclockwise so the counter is decrease
    if (digitalRead(DT) != currentState) {
      counter++;
    } else {
      counter--;
    }
    //print the value
    Serial.print("Counter: ");
    Serial.println(counter);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Counter: ");
    lcd.println(counter);
  }
  //remember last CLK state for the next cycle
  initState = currentState;
}

//button timing variable
int debounce = 20;
int DCgap = 250;
int holdTime = 1000;
int longHoldTime = 3000;

//button variable
boolean buttonVal = HIGH;
boolean buttonLast = HIGH;
boolean DCwaiting = false;
boolean DConUp = false;
boolean singleOK = true;
long downTime = -1;
long upTime = -1;
boolean ignoreUp = false;
boolean waitForUp = false;
boolean holdEventPast = false;
boolean longHoldEventPast = false;

int checkButton() {
  int event = 0;
  buttonVal = digitalRead(SW);
  //button press
  if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce) {
    downTime = millis();
    ignoreUp = false;
    waitForUp = false;
    singleOK = true;
    holdEventPast = false;
    longHoldEventPast = false;
    if ((millis() - upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true;
    else DConUp = false;
    DCwaiting = false;
  }
  //button released
  else if (buttonVal == HIGH && buttonLast == LOW && (millis() - upTime) > debounce) {
    if (not ignoreUp) {
      upTime = millis();
      if (DConUp == false) DCwaiting = true;
      else {
        event = 2;
        DConUp = false;
        DCwaiting = false;
        singleOK = false;
      }
    }
  }
  //test for normal click event: DCgap expired
  if (buttonVal == HIGH && (millis() - upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2) {
    event = 1;
    DCwaiting = false;
  }
  // test for hold
  if (buttonVal == LOW && (millis() - downTime) >= holdTime) {
    //trigger normal hold
    if (not holdEventPast) {
      event = 3;
      waitForUp = true;
      ignoreUp = true;
      DConUp = false;
      DCwaiting = false;
      //downTime = millis();
      holdEventPast = true;
    }
    //trugger long hold
    if ((millis() - downTime) >= longHoldTime) {
      if (not longHoldEventPast) {
        event = 4;
        longHoldEventPast = true;
      }
    }
  }
  buttonLast = buttonVal;
  return event;
}

void clickEvent() {
  delay(100);
  Serial.println("ClickEvent");
  //milih buah duls
  Serial.println("Button pressed, pilih buah: ");
  buahPilih = counter % 40;
  //buah1 = 0<buahPIlih<10
  //buah2 = 11<buahPilih<20
  //buah3 = 21<buahPilih<30
  //buah4 = 31<buahPilih<40
  if (buahPilih <= 10){
    //masukin setpoint, print, dll
    Serial.println("Buah yang dipilih adalah: 1 yaitu buah naga");
    buah = 1;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.println("Buah dipilih naga ");
    lcd.setCursor(0,1);
    lcd.println("Mengeringkan naga");
    //geser();
  }
  else if (buahPilih > 10 && buahPilih <=20){
    //masukin setpoint, print, dll
    Serial.println("Buah yang dipilih adalah: 2 yaitu buah apel ");
    buah = 2;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.println("Buah dipilih apel");
    lcd.setCursor(0,1);
    lcd.println("Mengeringkan apel");
  }
  else if (buahPilih > 20 && buahPilih <=30){
    //masukin setpoint, print, dll
    Serial.print("Buah yang dipilih adalah: 3 yaitu buah lemon");
    buah = 3;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.println("Buah dipilih lemon");
    lcd.setCursor(0,1);
    lcd.println("Mengeringkan lemon");
  }
  else{
    //masukin setpoint, print, dll
    Serial.println("Buah yang dipilih adalah: 4 yaitu buah nanas");
    buah = 4;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.println("Buah dipilih nanas");
    lcd.setCursor(0,1);
    lcd.println("Mengeringkan nanas");
  }
  buah = buah; //maunya store tempnya, sama timer
  //countdownTime = countdownTime; //ini buat apa ya
}

//ini mah harusnya yg nampilin countdown dan suhu, berarti loop countdown disini
void doubleClickEvent() { //agak ragu sebenarnya ini teh bisa apa engga
  //delay(100);
  Serial.println("DoubleClickEvent");
  if (buah == 1){
    set_temperature = 60;
    
    
    timer.setCounter(0,0,10, timer.COUNT_DOWN, onComplete);
    timer.setInterval(refreshClock, 1000);
    refreshClock();
    while (!timer.isCounterCompleted()){
      timer.run();
      timer.start();
      if(timer.isCounterCompleted()){
        break;
      }
    } 
    onComplete();
    return buahPilih;
  }
  else if (buah == 2){
    set_temperature = 60;
    timer.setCounter(7,0,0, timer.COUNT_DOWN, onComplete);
    timer.setInterval(refreshClock, 1000);
    refreshClock();
    while (!timer.isCounterCompleted()){
      timer.run();
      timer.start();
      if(timer.isCounterCompleted()){
        break;
      }
    } 
    onComplete();
    return buahPilih;
  }
  else if (buah == 3){
    set_temperature = 50;
    timer.setCounter(1,0,0, timer.COUNT_DOWN, onComplete);
    timer.setInterval(refreshClock, 1000);
    refreshClock();
    while (!timer.isCounterCompleted()){
      timer.run();
      timer.start();
      if(timer.isCounterCompleted()){
        break;
      }
    } 
    onComplete();
    return buahPilih;
  }
  else if (buah == 4){
    set_temperature = 60;
    timer.setCounter(16,0,0, timer.COUNT_DOWN, onComplete);
    timer.setInterval(refreshClock, 1000);
    refreshClock();
    while (!timer.isCounterCompleted()){
      timer.run();
      timer.start();
      if(timer.isCounterCompleted()){
        break;
      }
    } 
    onComplete();
    return buahPilih;
  }
}

void holdEvent() {
  delay(100);
  Serial.println("HoldEvent");
  int b = checkButton();
  b = 1;
}

void refreshClock(){
  digitalWrite(fan, HIGH);
  digitalWrite(buzzer, LOW);
  Serial.print("Waktu tersisa adalah: ");
  Serial.println(timer.getCurrentTime());
  Serial.print(" ");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Time ");
  lcd.println(timer.getCurrentTime());
  //baca();
  //geser(); //kalo pake ini prosesnya lama euy, mempengaruhi countdownnya, jadi mending engga
  //doing PID thing
  float temperature_read = dht.readTemperature();
  Serial.print("Suhu terbaca ");
  Serial.print(temperature_read);
  Serial.println(" C.");
  PID_error = set_temperature - temperature_read;
  Serial.print("Error terbaca: ");
  Serial.println(PID_error);
  Serial.print(" ");
  //apakah akan bisa? multitask? harusnya bisa
  //bisa kok multitask, countdown sambil ngitung PIDnya
  //cuma masalahnya suhunya ngga kebaca
  //ottoke
  //calculate PID value
  PID_p = kp * PID_error;
  PID_i = PID_i +(ki * PID_error);
  timePrev = Time;
  Time = millis();
  elapsedTime = (Time - timePrev) / 1000;
  PID_d = kd * ((PID_error - previous_error) / elapsedTime);
  PID_value = PID_p + PID_i + PID_d;
  //define PWM range between 0-255
  /*if (PID_value < 0){
    PID_value = 0;
  }
  if (PID_value >255){
    PID_value = 255;
  }*/
  //how to interrupt keluaran PWM dengan PID_value????
  //analogWrite(PWM, 255 - PID_value);
  Serial.print("PID_value adalah ");
  Serial.println(PID_value);
  Serial.print(" ");
  previous_error = PID_error; //remenber to store previous_error
  //delay(1000);
  //how to keluaran PWM jadi input dimmernyo
  power = PID_value;
  if (power<0){
    power = 0;
  }
  else if (power > 70){
    power = 70;
  }
  else if (0<power<70){
    power = power;
  }
  //how to set value on dimmer
  adc.setPower(power);
  Serial.print("lampValue -> ");
  Serial.print(adc.getPower()); // yg diliatin di serial monitor, berapa persen powernya
  Serial.println("%");
  Serial.print(" ");
}

void onComplete(){
  Serial.println("Complete!!");
  digitalWrite(buzzer, HIGH);
  digitalWrite(fan, LOW);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Complete!!!");
  //selesai(); //kalo pake ini completenya ngga keliatan, naha nya
  delay(5000);
  return;
}

void baca(){
  float temperature = dht.readTemperature();
  Serial.print("Suhu yang terbaca adalah ");
  Serial.println(temperature);
  Serial.print(" ");
  lcd.setCursor(0,1);
  lcd.print("Suhu: ");
  lcd.println(temperature);
}

void geser(){
  for(int j =1; j<=16; j++){
    lcd.scrollDisplayLeft();
    delay(500);
  }
}

这里是当我尝试读取 DHT22 时有效的简单代码

#include "DHT.h"
#include "LiquidCrystal_I2C.h"
#define DHTPIN 5
#define DHTTYPE DHT22
#include "RBDdimmer.h"

DHT dht (DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int fan = 7;

const int zeroCrossPin = 2;
const int adcPin = 3;
dimmerLamp adc(adcPin);
int power;
float set_temperature = 31.6;
float temperature_read = 0.0;
float suhu;
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
float PID_value = 0;

int kp = 90;
int ki = 30;
int kd = 80;

int PID_p = 0;
int PID_i = 0;
int PID_d = 0;
float last_kp = 0;
float last_ki = 0;
float last_kd = 0;
int PID_values_fix = 0;

void setup() {
  Serial.begin(9600);
  dht.begin();
  lcd.init();
  lcd.backlight();
  lcd.clear();
  pinMode(fan, OUTPUT);
}

void loop() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  Serial.print("Suhu : ");
  Serial.print(t);
  Serial.println(" C");
  Serial.print(" ");
  Serial.print("Kelembaban : ");
  Serial.print(h);
  Serial.println(" %");
  Serial.print(" ");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Suhu: ");
  lcd.print(t);
  //lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("kelem: ");
  lcd.print(h);
  //PIDnyo 
  
  PID_error = set_temperature - t;
  Serial.print("Error terbaca: ");
  Serial.println(PID_error);
  Serial.print(" ");
  PID_p = kp * PID_error;
  PID_i = PID_i +(ki * PID_error);
  timePrev = Time;
  Time = millis();
  elapsedTime = (Time - timePrev) / 1000;
  PID_d = kd * ((PID_error - previous_error) / elapsedTime);
  PID_value = PID_p + PID_i + PID_d;
  Serial.print("PID_value adalah ");
  Serial.println(PID_value);
  Serial.print(" ");
  previous_error = PID_error; //remenber to store previous_error
  //delay(1000);
  //how to keluaran PWM jadi input dimmernyo
  power = PID_value;
  if (power<0){
    power = 0;
  }
  else if (power > 70){
    power = 70;
  }
  else if (0<power<70){
    power = power;
  }
  //how to set value on dimmer
  adc.setPower(power);
  Serial.print("lampValue -> ");
  Serial.print(adc.getPower()); // yg diliatin di serial monitor, berapa persen powernya
  Serial.println("%");
  Serial.print(" ");
  
  if (t > 31){
    digitalWrite(fan, LOW);
  }
  delay(500);
}

here's the result of this code, the right result is the simple one, and the left is the menu that failed to read DHT22

感谢您的关注,我确实希望能够找到错误,以便代码能够按我的预期工作。

arduino menu temperature dht
1个回答
0
投票

您发布了太多代码,任何人都无法阅读!

我知道 DHT 传感器的一件事是,你不能太快读取它们,否则你可能会得到 NaN 或垃圾值,我认为读取温度/湿度之间需要等待的最短时间应该至少为 2-3秒(2000-3000 毫秒),我通常至少等待 10 秒。

检查您是否没有试图读得太快。

© www.soinside.com 2019 - 2024. All rights reserved.