我在这个领域还是个新手。我做了一个项目,我需要读取房间(盒子)的温度。我尝试使用 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);
}
感谢您的关注,我确实希望能够找到错误,以便代码能够按我的预期工作。
您发布了太多代码,任何人都无法阅读!
我知道 DHT 传感器的一件事是,你不能太快读取它们,否则你可能会得到 NaN 或垃圾值,我认为读取温度/湿度之间需要等待的最短时间应该至少为 2-3秒(2000-3000 毫秒),我通常至少等待 10 秒。
检查您是否没有试图读得太快。