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/

Затем я наткнулся на другой пост о другом решении, которое я реализовал, и оно, кажется, работает, но я хочу дать ему еще немного времени, чтобы убедиться. Будут и другие обновления.

, 👍1


1 ответ


1

Вот решение. После вчерашних поисков я наткнулся на этот пост https://forum.arduino.cc/index.php?topic=517608.new . Оказалось, я использовал библиотеку Adafruit DHT, и, похоже, проблема была в ней. Я переключился на эту библиотеку https://github.com/markruys/arduino-DHT DHT, и она работает уже около 14 часов без каких-либо проблем. Оглядываясь на последовательный вывод, я даже не вижу, чтобы он возвращал NaN, ни разу. Я так рад, что это исправили, и надеюсь, что это поможет кому-то еще, кто столкнулся с этой проблемой.

,