Помогите найти причину зависания ардуины

Disastor
Offline
Зарегистрирован: 05.10.2015

Собираю поливальщика по подобию поливальщика "Амперки", все работает часов 10, после чего ардуина повисает, данные на дисплее не обновляются, реле не реагируют. Не могу понять это проблема с железом или проблема с кодом. Я использую funduino nano с платой расширения, датчик влажности DTH11, датчик освещенности GY-30(BH1750) ,блок на  4 реле и дисплей 1602 с i2c модулем.

Код:[code]

#include <BH1750.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1302.h>
#include <DHT.h>
#define DHTPIN 3
#define DHTTYPE DHT11
#define RELAY_PIN0 8
#define RELAY_PIN1 9
#define RELAY_PIN2 10
#define RELAY_PIN3 11
//---------------------------------------------------
LiquidCrystal_I2C lcd(0x3f, 16, 2);
byte buff[2];
DHT dht(DHTPIN, DHTTYPE);
DS1302 rtc(4, 5, 6);
Time time;
BH1750 lightMeter;
//---------------------------------------------------
byte temp[8] = {0b00100,0b01010,0b01010,0b01110,0b01110,0b11111,0b11111,0b01110};//битовая маска иконки термометра
byte hum[8] = {0b00100,0b00100,0b01010,0b01010,0b10001,0b10001,0b10001,0b01110};//битовая маска иконки влажности воздуха
byte illum[8] = {0b00100,0b01110,0b01110,0b01110,0b10101,0b10101,0b10001,0b01110};//битовая маска иконки освещенности
byte water[8] = {0b00100,0b00100,0b01110,0b01110,0b11111,0b11111,0b11111,0b01110};//битовая маска иконки влажности почвы
//---------------------------------------------------
const int moisture_min = 1000;//граница минимального значения влажности(1024-сухо, 0-очень влажно)
const int moisture_med = 600;//граница среднего значения влажности(1024-сухо, 0-очень влажно)
const int moisture_max = 300;//граница максимального значения влажности(1024-сухо, 0-очень влажно)
const int lighting_min = 1000;//граница минимального значения освещенности(в Люксах)
const int time_min = 8;//граница минимального значения времени
const int time_max = 20;//граница максимального значения времени
//---------------------------------------------------
void setup(void)
{
  Serial.begin(9600);
  rtc.halt(false);
  rtc.writeProtect(false);
//rtc.setTime(15, 30, 00);     // Настройка часов в формате 12:00:00 (24 часа)
//rtc.setDate(15, 4, 2016);   // Настройка даты в формате 01.01.2000
  pinMode( 8 , OUTPUT);
  pinMode( 9 , OUTPUT);
  pinMode( 10 , OUTPUT);
  pinMode( 11 , OUTPUT);
  dht.begin();
  Wire.begin();
  lightMeter.begin();
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.createChar(1,temp);
  lcd.createChar(2,hum);
  lcd.createChar(3,illum);
  lcd.createChar(4,water);
}
//---------------------------------------------------
char intDigit(unsigned int val, char pos)//функция преобразования числа в цифры, входные данные: число, позиция
{
  char buf[6];
  sprintf(buf, "%04u", val);
  return buf[3-pos]-'0';
}
//---------------------------------------------------
unsigned int intDigitSet(unsigned int val, char pos, char d)
{
  char buf[6];
  sprintf(buf, "%04u", val);
  buf[3-pos] = '0'+d;
  return atoi(buf);
}
//---------------------------------------------------
unsigned int readMoisture_Sensor(void)//функция чтения сенсора влажности
{
  static unsigned int oldval = 0;
  static unsigned int res = 0;
  static unsigned int stability[4] = { 0, 0, 0, 0 };
  char i;
  unsigned int val = analogRead(A6);
  for(i = 0; i < 4; i++) {
    if(intDigit(oldval, i) != intDigit(val, i)) {
      oldval = intDigitSet(oldval, i, intDigit(val, i));
      stability[i] = 0;
    }
    else {
      if(stability[i] < 10) stability[i]++;
      else res = intDigitSet(res, i, intDigit(val, i));
    }
  }
  return res;
}
//---------------------------------------------------
unsigned int readLighting(void)//функция чтения сенсора влажности
{
  static unsigned int oldval = 0;
  static unsigned int res = 0;
  static unsigned int stability[4] = { 0, 0, 0, 0 };
  char i;
  unsigned int val = lightMeter.readLightLevel();
  for(i = 0; i < 4; i++) {
    if(intDigit(oldval, i) != intDigit(val, i)) {
      oldval = intDigitSet(oldval, i, intDigit(val, i));
      stability[i] = 0;
    }
    else {
      if(stability[i] < 10) stability[i]++;
      else res = intDigitSet(res, i, intDigit(val, i));
    }
  }
  return res;
}
//---------------------------------------------------
unsigned int readHumidity(void)//функция чтения сенсора влажности
{
  static unsigned int oldval = 0;
  static unsigned int res = 0;
  static unsigned int stability[4] = { 0, 0, 0, 0 };
  char i;
  unsigned int val = dht.readHumidity();
  for(i = 0; i < 4; i++) {
    if(intDigit(oldval, i) != intDigit(val, i)) {
      oldval = intDigitSet(oldval, i, intDigit(val, i));
      stability[i] = 0;
    }
    else {
      if(stability[i] < 10) stability[i]++;
      else res = intDigitSet(res, i, intDigit(val, i));
    }
  }
  return res;
}
//---------------------------------------------------
unsigned int readTemperature(void)//функция чтения сенсора влажности
{
  static unsigned int oldval = 0;
  static unsigned int res = 0;
  static unsigned int stability[4] = { 0, 0, 0, 0 };
  char i;
  unsigned int val = dht.readTemperature();
  for(i = 0; i < 4; i++) {
    if(intDigit(oldval, i) != intDigit(val, i)) {
      oldval = intDigitSet(oldval, i, intDigit(val, i));
      stability[i] = 0;
    }
    else {
      if(stability[i] < 10) stability[i]++;
      else res = intDigitSet(res, i, intDigit(val, i));
    }
  }
  return res;
}
//---------------------------------------------------
void loop(void)
{
//  digitalWrite( 8 , HIGH );digitalWrite( 9 , HIGH );digitalWrite( 10 , HIGH );digitalWrite( 11 , HIGH );
  lcd.home();lcd.write(1);lcd.setCursor(8, 0);lcd.write(2);lcd.setCursor(0, 1);lcd.write(3);lcd.setCursor(8, 1);lcd.write(4);//вывод на экран битовых масок
  
  time = rtc.getTime();
  static unsigned long wait = millis() + 60000; 
  static unsigned int oldmoisture = 0;
  static unsigned long stability = 0;
  unsigned int moisture = readMoisture_Sensor(); // читаем сенсор влажности
  if(moisture != oldmoisture) {                  // если отличается от предыдущего измерения
    oldmoisture = moisture;
     if(moisture >= moisture_min) {
     lcd.setCursor(9, 1);lcd.print("ERROR");}//Сенсор находится не в почве, либо не подключен.

     if((moisture < moisture_min) && (moisture >= moisture_med)) {
     lcd.setCursor(9, 1);lcd.print("DRY  ");}//Почва сухая

     if((moisture < moisture_med) && (moisture >= moisture_max)) {
     lcd.setCursor(9, 1);lcd.print("HUMID");}//Почва влажная

     if(moisture < moisture_max) {
     lcd.setCursor(9, 1);lcd.print("WATER");}}//Сенсор в воде
//---------------------------------------------------
  static unsigned int oldlighting = 0;
  unsigned int lighting = readLighting(); // читаем сенсор освещения
  if(lighting != oldlighting) {           // если отличается от предыдущего измерения
    oldlighting = lighting;
  lcd.setCursor(1, 1);lcd.print(readLighting());lcd.print("Lx  ");}
//---------------------------------------------------
  static unsigned int oldHumidity = 0;
  unsigned int Humidity = dht.readHumidity(); // читаем сенсор влажности воздуха
  if(Humidity != oldHumidity) {               // если отличается от предыдущего измерения
    oldHumidity = Humidity;
  lcd.setCursor(9, 0);lcd.print(dht.readHumidity(),0);lcd.print("% ");}
//---------------------------------------------------
  static unsigned int oldTemperature = 0;
  unsigned int Temperature = dht.readTemperature(); // читаем сенсор влажности воздуха
  if(Temperature != oldTemperature) {               // если отличается от предыдущего измерения
    oldTemperature = Temperature;
  lcd.setCursor(1, 0);lcd.print(dht.readTemperature(),0);lcd.print((char)223);lcd.print("C ");}
//---------------------------------------------------
if ((time.hour >= (8)) && (time.hour <= (20)))
 {
  digitalWrite( 11 , HIGH ); Serial.print("Lamp ON");Serial.print(" ");Serial.print(time.hour); Serial.print(":"); Serial.println(time.min);
  }
    else
   {
    digitalWrite( 11 , LOW );Serial.print("Lamp OFF");Serial.print(" ");Serial.print(time.hour); Serial.print(":"); Serial.println(time.min);
   }
//---------------------------------------------------
  if(wait != 0 && wait-millis() > 10) {
    return;
  } else wait = 0;
  if(moisture > moisture_med) {     // если влажность ниже среднего
    digitalWrite( 8 , HIGH );      // включаем реле на 5 сек
    Serial.print("Pomp ON");Serial.print(" ");Serial.print(time.hour); Serial.print(":"); Serial.println(time.min);
    delay(5000);
    digitalWrite( 8 , LOW );
    wait = millis() + 3*60000;
  }
}
 [/code]

 

vde69
Offline
Зарегистрирован: 10.01.2016

у тебя проблемма с

wait = millis() + 3*60000;

подумай, что будет с кодом когда происходит переполнение....

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
static unsigned long wait = millis() + 60000UL;
wait = millis() + 3*60000UL;

Закомментируй строки 201-203, без них будет зависать?

Disastor
Offline
Зарегистрирован: 05.10.2015

Спасибо, попробую! Просто этот участок кода я позаимствовал у амперки. Я сейчас думаю может мне использовать для этого свои модуль часов реального времени.

То есть после срабатывания реле вписывать в память результат time.min(минуты реального времени) и если time.min+3  = wait, проверку повторно.

Пока для теста я по вашим советам подкорректировал код, посмотрим что получится.