DHT22 Зависает вся программа
В процессе обучения и работы над более крупным проектом я начал с добавления дисплея OLED
(128x64, SPI
). Я написал простой скрипт для обновления каждые 5 секунд, а затем отображения количества секунд как на OLED
, так и на последовательном порту. Это работало просто отлично, и я даже позволил ему работать больше дня. Затем я добавил DHT22
. Вот тут-то и начались проблемы. Arduino
Mega
(клон) питает оба устройства. У меня есть резистор 10 кОм между VCC и сигнальными контактами DHT22
. Теперь код должен обновлять как OLED
, так и на последовательном порту количество секунд, а также температуру и влажность. Это работает некоторое время, а затем вся программа зависает по какой-то странной причине. Время до зависания также имеет случайные интервалы.
Во время моего исследования было предложено добавить конденсатор 10 мкФ между землей и VCC. Поэтому я добавил конденсатор 10 мкФ 50 В, и результаты остались прежними. Изначально в коде был Serial.println(String(....., но я заменил все это, чтобы не использовать String(). Я пробовал добавлять Serial.flush() в конце кода отображения, но результаты были такими же.
Дополнительные исследования также предложили подождать 30 секунд перед попыткой чтения DHT22. Я добавил это 30-секундное ожидание в конце функции настройки, но результаты те же. Я пробовал проверять NaN, не проверять NaN, и ничто не исправило эту проблему.
Я также пробовал программу без OLED. Те же результаты. Я пробовал программу без последовательного выхода, но те же результаты.
Что здесь происходит и есть ли у кого-нибудь предложения, как это исправить?
В настоящее время все это собрано на макетной плате, если это поможет.
Ниже приведен текущий код, который я пробую:
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Библиотеки Adafruit для OLED-дисплеев
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Настройка переменных OLED
#define OLED_MOSI 9 // D1 на OLED
#define OLED_CLK 10 // D0 на OLED
#define OLED_DC 11 // DC на OLED
#define OLED_CS 12 // CS на OLED
#define OLED_RESET 13 // RES на OLED
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
// Глобальные переменные
unsigned long currentMillis;
long previousMillis = 0;
#define interval 5000
float humidity;
float fahrenheit;
void setup(){
// Запустить передачу через последовательный порт
Serial.begin(9600);
// Запустить OLED
display.begin(SSD1306_SWITCHCAPVCC);
dht.begin();
// Очищаем память OLED
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(1,0);
display.println("Madgayrah");
display.display();
while(millis()<2000);
display.setCursor(0,16);
display.println("Arduino");
display.display();
while(millis()<5000);
// пока(millis()<30000);
Serial.println("");
display.clearDisplay();
}
void loop() {
currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
poll_and_display(currentMillis);
}
}
void poll_and_display(long currentMillis){
read_dht22();
Serial.println(previousMillis/1000);
if(!isnan(humidity) && !isnan(fahrenheit)){
Serial.print(fahrenheit, 1);
Serial.print("* ");
Serial.print(humidity, 0);
Serial.println("%");
}
display.clearDisplay();
display.setCursor(0,0);
display.println(currentMillis/1000);
if(!isnan(humidity) && !isnan(fahrenheit)){
display.setCursor(0,16);
display.print(fahrenheit, 1);
display.print("* ");
display.print(humidity, 0);
display.print("%");
}
display.display();
Serial.println("");
Serial.flush();
}
void read_dht22(){
humidity = dht.readHumidity();
fahrenheit = dht.readTemperature(true);
// while (иснан(влажность) || иснан(по Фаренгейту)) {
// unsigned long tempEnteredMillis = millis();
// while (millis() - tempEnteredMillis < 2500);
//
// влажность = dht.readHumidity();
// фаренгейт = dht.readTemperature(true);
//
// Serial.print("Результат цикла NaN = ");
// Serial.print(фаренгейт, 1);
// Серийный.print("* ");
// Serial.print(влажность, 0);
// Serial.println("%");
// }
}
ОБНОВЛЕНИЕ:
Продолжив исследования по этому вопросу, я обнаружил, что у Arduino
есть сторожевой таймер, или, по крайней мере, ДОЛЖЕН быть, и он ДОЛЖЕН обнаруживать зависания и перезапускать Arduino
. Поэтому я попробовал аппаратную версию сторожевого таймера и программную версию, но ни одна из них не работала и/или не исправляла проблему зависания/зависания. Ниже приведены ссылки, которые я использовал для программных и аппаратных версий.
https://circuits4you.com/2018/01/24/tutorial-on-arduino-watchdog-timer-setup/
https://blog.frogslayer.com/creating-an-arduino-watchdog-timer/
Затем я наткнулся на другой пост о другом решении, которое я реализовал, и оно, кажется, работает, но я хочу дать ему еще немного времени, чтобы убедиться. Будут и другие обновления.
@The Duke Of Marshall שלום, 👍1
1 ответ
Вот решение. После вчерашних поисков я наткнулся на этот пост https://forum.arduino.cc/index.php?topic=517608.new . Оказалось, я использовал библиотеку Adafruit
DHT, и, похоже, проблема была в ней. Я переключился на эту библиотеку https://github.com/markruys/arduino-DHT DHT, и она работает уже около 14 часов без каких-либо проблем. Оглядываясь на последовательный вывод, я даже не вижу, чтобы он возвращал NaN, ни разу. Я так рад, что это исправили, и надеюсь, что это поможет кому-то еще, кто столкнулся с этой проблемой.
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Зависание Arduino с OLED-дисплеем
- Объединение кода для нескольких датчиков в одной программе
- Водонепроницаемый датчик температуры SPI.
- Проблема MAX31865 и PT100
- Возникли проблемы с чтением нескольких термисторов с Arduino 2560
- Как разделить входящую строку?
- Как использовать SPI на Arduino?