Трудности программирования Arduino uno для 24-часового цикла

Я пытаюсь запрограммировать плату Arduino Uno на 24-часовой цикл. У меня есть плата Arduino и два реле. Цель; каждые 24 часа реле 1 должно включаться на 5 секунд, а через 1 секунду реле 2 должно включаться на 15 секунд. У меня есть скетч для 12-часового цикла, и он отлично работает, но когда я пытаюсь использовать 24-часовой цикл, изменяя const unsigned int totalTime с 43200 секунд на 86400 секунд, все идет не так.

24-часовой скетч — что не так?

//включаем и выключаем реле в определенное время.
// когда на цифровом выходе высокий уровень, реле выключено.
// когда на цифровом выходе низкий уровень, реле включено.

enum actioEnum {
  RELAY1_ON,
  RELAY1_OFF,
  RELAY2_ON,
  RELAY2_OFF,
};

struct tableStruct{
  unsigned int time;
  actionEnum action;
}
const table [] = {
  {0,RELAY1_ON},
  {5,RELAY1_OFF},
  // осталось 86395, всего 86400.
  {0,RELAY2_OFF}, // не нужен, он уже выключен.
  {6,RELAY2_ON},
  {6+15,RELAY2_OFF},
  // осталось 86379, всего 86400.
};

const unsigned int totalTime = 86400; // общая сумма для последовательности
unsigned int seconds;

unsigned long previousMillis;
const unsigned long interval = 1000; // 1000 мс; // 1000 мс это одна секунда

const int relay1Pin = 2;
const int relay2Pin = 3;

void setup() {
   serial.begin(9600);

  // реле выключено, когда на выводе высокий уровень.
  // перевести выход в высокий уровень перед установкой pinMode.
  // затем выход меняется с плавающего вывода на высокий,
  // и реле не будут активированы.
  digitalWrite (relay1Pin, HIGH);
  pinMode (relay1Pin, OUTPUT);
  digitalWrite (relay2Pin, HIGH);
  pinMode (relay2Pin, OUTPUT);
}

void loop () {
  // односекундный таймер с миллисекундами
  if (millis() - previousMillis >= interval) {
    previousMillis += interval;    
    // сканируем таблицу
    for ( int i = 0; i < int (sizeof(table) / sizeof (tableStruct)); i++) {
      if (table [i] . time == seconds) {
        switch (table [i] . action) {    
          case RELAY1_ON:
            Serial.println("Relay 1 on");
            digitalWrite (relay1Pin, LOW); // низкий уровень реле включено.
            break;
          case RELAY1_OFF:
            Serial.println("Relay 1 off");
            digitalWrite (relay1Pin, HIGH); // высокий - реле выключено.
            break;
          case RELAY2_ON:
            Serial.println("Relay 2 on");
            digitalWrite (relay2Pin, LOW); // низкий уровень реле включено.
            break;
          case RELAY2_OFF:
            Serial.println ("Relay 2 off");
            digitalWrite (relay2Pin, HIGH); // высокий - реле выключено.
            break;    
          default:
            Serial.println ("Error, a bug in the scketch");
        }
      }
    }
    seconds++;
    if (seconds >= totalTime) {
      seconds = 0;
    }
  }
}

, 👍0

Обсуждение

Почему вы не используете модуль RTC?, @ElectronSurf

Uno не самый точный в хронометраже и может отклоняться на несколько минут каждый день. В зависимости от вашего приложения это может не иметь значения. Однако, если это так, используйте RTC, как предложил новичок., @Gerben


1 ответ


5

В Uno unsigned int — это 16-битное число. Это означает, что она может содержать значения от (включительно) от 0 до 65535. Если вы попытаетесь записать большее значение в эту переменную, она удалит старшие биты, так что остальные уместятся в 16 бит. Это дает совершенно другое значение, которое значительно меньше, чем 24 часа.

Решение состоит в том, чтобы использовать более крупный тип переменной для totalTime. Вы можете использовать unsigned long, который имеет 32 бита и может содержать гораздо большие значения (от 0 до 4 294 967 295 (2^32 - 1)). Этого должно быть достаточно для всех ваших дел.

,

Привет, ваше решение состоит в том, чтобы использовать unsigned long вместо totalTime. как изменить это в моем скетче? С уважением, Мартинус., @Jerry

Нет, не вместо totalTime, а как его тип. В своем скетче вы написали const unsigned int totalTime = 86400;, но вместо этого вы должны написать const unsigned long totalTime = 86400;. Это изменяет тип переменной totalTime с unsigned int на unsigned long., @chrisl