Помогите найти причину зависания ардуины
- Войдите на сайт для отправки комментариев
Чт, 21/04/2016 - 08:48
Собираю поливальщика по подобию поливальщика "Амперки", все работает часов 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]
у тебя проблемма с
wait = millis() + 3*60000;
подумай, что будет с кодом когда происходит переполнение....
Закомментируй строки 201-203, без них будет зависать?
Спасибо, попробую! Просто этот участок кода я позаимствовал у амперки. Я сейчас думаю может мне использовать для этого свои модуль часов реального времени.
То есть после срабатывания реле вписывать в память результат time.min(минуты реального времени) и если time.min+3 = wait, проверку повторно.
Пока для теста я по вашим советам подкорректировал код, посмотрим что получится.