Atmega рандомно зависает.

Cheesus
Offline
Зарегистрирован: 05.02.2021

Доброго дня всем! Собрал устройство для управления подсветкой от ATX блока питания. В процессе работы контроллер рандомно зависает через через разные промежутки времени (30 минут, 6 часов, 2 дня и т.д.). Зависание может произойти и ночью, когда блок выключен, и днем.


#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define DS3231 0x68
LiquidCrystal_I2C lcd(0x27,16,2);
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}
  byte t[7];
  byte temp[2];
  float te = 0;
  
void setup() {
  pinMode(4,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  Wire.begin();
  lcd.init();
}

void getime(){
  int i = 0;
  Wire.beginTransmission(DS3231);
  Wire.write(0);
  Wire.endTransmission(); 
  Wire.requestFrom(DS3231, 7);
  while(Wire.available()) {
    t[i] = bcdToDec(Wire.read());
    i++;
  }
  int k =0;
  Wire.beginTransmission(DS3231);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(DS3231, 2);
    while(Wire.available()) {
    temp[k] = Wire.read();
    k++;
  }
  te = temp[0]; // целая часть
  te += (temp[1]*0.25/100);
}

void loop() {
  if(millis()%1000==0) {
  getime();
  lcd.setCursor(0,0);
  if(t[2]<10) lcd.print("0");
  lcd.print(t[2]);
  lcd.print(":");
  if(t[1]<10) lcd.print("0");
  lcd.print(t[1]);
  lcd.print(":");
  if(t[0]<10) lcd.print("0");
  lcd.print(t[0]);
  lcd.setCursor(0,1);
  lcd.print("Temp: ");
  lcd.print(te);
  lcd.write(0xdf);
  lcd.print("C");
  if(t[2]>=8 && t[2]<23) lcd.setBacklight(HIGH);
  else lcd.setBacklight(LOW);
  }
  if(t[2]>=8 && t[2]<22){
    digitalWrite(4,HIGH);
    digitalWrite(9,HIGH);
    digitalWrite(10,HIGH);
  }
  if(t[2]>=23 || t[2]<7){
    digitalWrite(4,LOW);
    digitalWrite(9,LOW);
    digitalWrite(10,LOW);
  }
  switch(t[2]) //hours
  {
    case 22:
    switch(t[1]){ //minutes
    case 0:
    digitalWrite(4,HIGH);
    analogWrite(9,165);
    analogWrite(10,165);
    break;
    case 15:
    digitalWrite(4,HIGH);
    analogWrite(9,130);
    analogWrite(10,130);
    break;
    case 30:
    digitalWrite(4,HIGH);
    analogWrite(9,90);
    analogWrite(10,90);
    break;
    case 45:
    digitalWrite(4,HIGH);
    analogWrite(9,45);
    analogWrite(10,45);
    break;}
    break;

    case 7:
    switch(t[1]){
    case 0:
    digitalWrite(4,HIGH);
    analogWrite(9,45);
    analogWrite(10,45);
    break;
    case 15:
    digitalWrite(4,HIGH);
    analogWrite(9,90);
    analogWrite(10,90);
    break;
    case 30:
    digitalWrite(4,HIGH);
    analogWrite(9,130);
    analogWrite(10,130);
    break;
    case 45:
    digitalWrite(4,HIGH);
    analogWrite(9,165);
    analogWrite(10,165);
    break;}
    break;
  }
  }

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

wdt?

sadman41
Offline
Зарегистрирован: 19.10.2016

А может и не зависает, а вполне себе работает (код-то с ошибкой) - симптомы же не описаны.

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

и еще я понимаю так - код не тот и схема не моя... (схема с кодом не стыкуется)

Cheesus
Offline
Зарегистрирован: 05.02.2021

Код мой и схема моя. Просто не стал рисовать на схеме плату ds3231 и lcd1602, как видно из кода, обе работают через I2C.

Симптомы: время на экране застывает, подсветка и блок не включаются. При сбросе резетом работа возобновляется.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

вот так не делают

045   if(millis()%1000==0)

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Строка 45. Какова вероятность выполнения условия?

Cheesus
Offline
Зарегистрирован: 05.02.2021

Надо обязательно через unsigned long?

sadman41
Offline
Зарегистрирован: 19.10.2016
Cheesus
Offline
Зарегистрирован: 05.02.2021

Переписал код по аналогии с примером, 5 дней работает без зависаний. Всем спасибо!