Arduino прекращает регистрацию данных примерно через 32761 секунду.

Я сделал небольшую настройку для регистрации температуры на SD-карте, все работает гладко, пока время регистрации не достигнет 9:06:01, что составляет 32761 секунду. Я знаю, что это примерно соответствует максимальному значению целого числа. Но я сделал все свои переменные беззнаковыми. Вот код в цикле и условие if для регистрации или нет. Таймер вычисляется с помощью currentTime (длинное значение без знака) и startTime (длинное значение без знака). Таким образом, даже если logCount*freq оба являются целыми числами, они должны достичь максимального значения через 32761 секунду, тогда условие if всегда должно быть истинным.

void loop() { 
 String date;
 unsigned long timer;
 int freq = 60;

 sensors.requestTemperatures();
 tempC1 = printTemperature(insideThermometer, 18);
 tempC2 = printTemperature(outsideThermometer, 19);

 // запускаем последовательный порт
 Serial.begin(9600);

 mainMenuDraw();
 operateMainMenu();

 CurrentTime = millis();
 timer=(CurrentTime - StartTime)/1000;
 date = TimeShowFormatted(CurrentTime - StartTime);

 if (timer > logCount * freq and StopStatus == 0) {
  logCount += 1;
  LastLoggedDate=date;
  DataLogg(date);

 }
}

, 👍0

Обсуждение

Что такое «StartTime»? Добавьте остальную часть вашего кода, чтобы я мог его смоделировать, пожалуйста., @Filip Franik

Чтобы увеличить переменную, используйте logCount++;, @SBF

@FilipFranik StartTime — это беззнаковое длинное значение, которое инициализируется нулем при запуске Arduino или повторно инициализируется нулем при перезапуске регистрации (через меню на ЖК-экране), @Vincent


1 ответ


Лучший ответ:

1

Вместо сравнения абсолютного времени следует использовать следующее:

unsigned long now = millis();

if(now - time_last_log >= freq){
    logCount += 1;
    LastLoggedDate=date;
    DataLogg(date);
    time_last_log = now; 
    // или если вам действительно нужны фиксированные интервалы
    // time_last_log += частота;
}

Это гарантирует защиту от переполнения.

,

Этот код также может привести к сбою. Возможно, что time_last_log будет близок к максимальному значению unsigned long, и тогда он никогда не будет обновляться, потому что now всегда меньше. Я предлагаю добавить || now < time_last_log в if, чтобы выйти из этого бесконечного цикла., @Filip Franik

@FilipFranik: Нет, это не произойдет, если time_last_log приблизится к ULONG_MAX. Благодаря правилам модульной арифметики этот код безопасен при опрокидывании. Попробуйте сами, если вы не уверены., @Edgar Bonet

@EdgarBonet Ты сломал мне мозг. Ты прав., @Filip Franik

@EdgarBonet Спасибо за полезную информацию. Всегда здорово чему-то научиться! Сегодня я проверю решение и подтвержу ответ, если все в порядке., @Vincent

@EdgarBonet, все работает хорошо, 21 час регистрации и все еще работает. Большое спасибо, @Vincent