Задержка иногда останавливает выполнение навсегда
У меня есть Arduino для управления системой орошения, состоящей из одного насоса (в коде он называется "бомба") и 5 водяных клапанов на 12 В.
Каждый клапан управляет одним ирригационным контуром, и идея состоит в том, чтобы открывать каждый из них последовательно в течение одной минуты, а затем переходить к следующему.
Код такой:
const int TIEMPO_RIEGO = 64; // секунды
const int TRIGGER = 5;
const int BOMBA = 6;
const int CIRCUITO_1 = 8;
const int CIRCUITO_2 = 9;
const int CIRCUITO_3 = 10;
const int CIRCUITO_4 = 11;
const int CIRCUITO_5 = 12;
const int CIRCUITOS_ACTIVOS[] = {
CIRCUITO_1,
CIRCUITO_2,
CIRCUITO_3,
CIRCUITO_4,
CIRCUITO_5,
};
void _abrirValvula(int circuito, int t) {
digitalWrite(circuito, HIGH);
digitalWrite(BOMBA, HIGH);
unsigned long waitTime = t * 1000L;
delay(waitTime);
digitalWrite(BOMBA, LOW);
digitalWrite(circuito, LOW);
}
void cicloRiegoCompleto() {
int numeroDeCircuitos = sizeof(CIRCUITOS_ACTIVOS) / sizeof(CIRCUITOS_ACTIVOS[0]);
for (int i=0; i<numeroDeCircuitos; i++){
_abrirValvula(CIRCUITOS_ACTIVOS[i], TIEMPO_RIEGO);
}
}
void setup() {
pinMode(BOMBA, OUTPUT);
pinMode(CIRCUITO_1, OUTPUT);
pinMode(CIRCUITO_2, OUTPUT);
pinMode(CIRCUITO_3, OUTPUT);
pinMode(CIRCUITO_4, OUTPUT);
pinMode(CIRCUITO_5, OUTPUT);
pinMode(TRIGGER, INPUT);
}
void loop() {
if (digitalRead(TRIGGER) == HIGH) {
cicloRiegoCompleto();
}
}
К контакту 5 (ТРИГГЕР) у меня подключен raspberry pi, который также подключен к Интернету, поэтому, когда я отправляю ему сообщение с телефона, он подает на этот контакт 3,3 В и запускает процесс.
Он отлично работал около месяца, но несколько дней назад насос не остановился, когда должен был, и продолжал работать через несколько часов после запуска.
Я выдергиваю вилку из розетки, и когда я снова включаю ее, она снова исправно работает еще 2 или 3 дня.
Но сегодня это снова не прекратилось. Я проверил, что насос работал около 15 минут, пока я не вытащил пробку, и первый клапан (CIRCUITO_1) был открыт все время, похоже, что петля for
застряла в первом итерация.
Может быть, это какая-то проблема с функцией delay
?
По какой-то причине он ожидает намного больше, чем должен?
Иногда это работает, а иногда нет, поэтому я думаю: может быть, это какая-то странная проблема с переполнением?
@Enuff, 👍2
Обсуждение4 ответа
Он отлично работает уже месяц или около того... это заставляет меня задуматься: может быть, это какая-то странная проблема с переполнением?
Тогда проблема вряд ли связана с программным обеспечением. Ничего в вашем коде не изменится после месяца работы. А если выключить и снова включить питание, то он "забудет" о предыдущем месяце.
Может быть, это какая-то проблема с функцией задержки?
Нет
Я предлагаю посмотреть на аппаратное обеспечение или код на Pi.
В этом есть смысл. Пи-код выглядит нормально, но должен ли я просто проверить часть схемы MOSFET или сам Arduino? Что я имею в виду: может ли Arduino каким-то образом сломаться, чтобы случайно застрять в строке кода? Или, если бы ардуино сломалось, оно бы вообще не работало?, @Enuff
Я сомневаюсь, что он "застрянет" в строке кода. Процессор работает или нет. Я бы использовал измеритель, чтобы проверить, что выходной сигнал настроен так, как вы ожидаете., @Nick Gammon
Основываясь на вашем опыте работы с системой и источнике Nano, лучший и самый быстрый тест, который я могу придумать, — это заменить другой Nano, чтобы выяснить, сохраняется ли проблема или исчезает.
Есть ли у вас резисторы 10 кОм между затвором и землей на полевых МОП-транзисторах? Возможно, вы страдаете от остаточного заряда на затворе MOSFET, удерживая его включенным, когда он должен быть выключен.
Ага, а также обратноходовые диоды на каждом клапане., @Enuff
Возможно, у вас возникла проблема при приведении переменной t к времени ожидания переменной. t — это целое число, а время ожидания — длинное, поэтому при умножении t на 1000L вы можете получить пару дополнительных байтов, используемых другими частями кода:
Например, если t хранится по адресу 0x100:0x101 в ОЗУ, а некоторые другие переменные или случайные данные хранятся по адресу 0x102:0x103, вы передаете 100 функции в переменной t, которая, как вы ожидаете, умножается на время ожидания как 100 000 мс или 100 с, но если данные, хранящиеся по адресу 0x102:0x103, например, имеют случайное значение 0xFFFF, умножение на время ожидания фактически дает (100*65536)+65535 = 6 619 135 мс или 1,83 часа.
Можно либо передать в функцию значение long, либо преобразовать t, чтобы оно соответствовало времени ожидания:
время ожидания = (длительное) t * 1000 л;
Обратите внимание, что порядок байтов зависит от того, как компилятор обрабатывает хранение переменных.
Компиляторы не перезаписывают память только потому, что вы что-то отбрасываете. Это было бы довольно плохим поведением, если бы они это сделали. Возможно, если вы приведете указатель к другому типу указателя, но это обычная переменная., @Nick Gammon
Приведение и умножение почти наверняка выполняются в регистрах, а переменная waitTime
вряд ли когда-либо будет существовать отдельно, так как результат умножения будет оставлен в регистрах или сразу же помещен в стек в качестве аргумента для delay( )
, и больше никогда не упоминается., @JRobert
- Как погасить светодиод за определенное время с помощью FastLED
- Чтение и запись в EEPROM
- Соединение ATTiny85 I2C с Arduino Nano
- Функция random() вообще не случайна
- Возможно ли передавать данные с Arduino Nano на сервер Websocket через USB?
- Кто-нибудь может привести пример извлечения данных из массива char?
- Arduino работает правильно, только когда я прикасаюсь к нему
- Проблема с чтением данных из ELM327
Код кажется мне законным. Можете ли вы войти в систему пи, когда именно она включает и выключает вывод? Просто посмотреть, правильно ли это работает., @chrisl
Когда у вас возникает эта проблема, каково состояние логического выхода Pi?, @Edgar Bonet
pi переводит свой выход в ВЫСОКОЕ состояние только на одну секунду, а затем снова в НИЗКОЕ значение. Но, даже если бы он был ВЫСОКИМ все время, он должен проходить через каждый клапан, а не застревать в первом навсегда., @Enuff
Как вы подключаете насосы к Arduino? Можете выложить схему? А как вы питаете насосы? Они питаются отдельно от Arduino или Arduino получает питание от той же цепи, что и насосы?, @GMc
Клапаны управляются через мосфеты IRL510 (или IRL540? сейчас не помню), помпа с реле ардуино 5В. Питается все от блока питания 15А 12В, используется понижающий для малины и питания реле. Вечером постараюсь скинуть схему., @Enuff
Это дешевый китайский nano за 1 доллар или настоящий Arduino nano?, @Majenko
Купил его на amazon.es в упаковке по 6 штук примерно за 15 евро, так что, вероятно, это китайская версия. Не знаю, как найти отличия, вот фото: https://imgur.com/03C2WyB, @Enuff
Дешевая китайская хрень. Вы знаете, *как* они получают их так дешево? Все просто: микроконтроллеры выходят из мусорного бака. Вместо того, чтобы фабрика в Китае выбрасывала их, они продавали их дешево на местном рынке. Таким образом, вы можете ожидать, что они будут некачественными и случайно выйдут из строя..., @Majenko