Проблема управления 28 реле
- Войдите на сайт для отправки комментариев
Чт, 31/03/2022 - 23:45
arduino2560 (no origin)
28 реле - 14 на впуск воздуха и 14 на выпуск
Всем привет! У меня все просто таймер считает 1 секунду и потом timerCount2 инкрементирует их.Дальше я сравниваю этот счетчик и управляю нужными портами. Проблема в том, что timerCount2 сбрасывается и у меня цикл не отрабатывает полностью и я не знаю почему
// ports of valves
int valves[] = {22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};
//timer's counter
volatile int timerCount2 = 0; // считаем прерывания таймера одно прерывание в секунду
void setup() {
//valves
pinMode(valves[0], OUTPUT);
pinMode(valves[1], OUTPUT);
pinMode(valves[2], OUTPUT);
pinMode(valves[3], OUTPUT);
pinMode(valves[4], OUTPUT);
pinMode(valves[5], OUTPUT);
pinMode(valves[6], OUTPUT);
pinMode(valves[7], OUTPUT);
pinMode(valves[8], OUTPUT);
pinMode(valves[9], OUTPUT);
pinMode(valves[10], OUTPUT);
pinMode(valves[11], OUTPUT);
pinMode(valves[12], OUTPUT);
pinMode(valves[13], OUTPUT);
pinMode(valves[14], OUTPUT);
pinMode(valves[15], OUTPUT);
pinMode(valves[16], OUTPUT);
pinMode(valves[17], OUTPUT);
pinMode(valves[18], OUTPUT);
pinMode(valves[19], OUTPUT);
pinMode(valves[20], OUTPUT);
pinMode(valves[21], OUTPUT);
pinMode(valves[22], OUTPUT);
pinMode(valves[23], OUTPUT);
pinMode(valves[24], OUTPUT);
pinMode(valves[25], OUTPUT);
pinMode(valves[26], OUTPUT);
pinMode(valves[27], OUTPUT);
digitalWrite(valves[0], HIGH);
digitalWrite(valves[1], HIGH);
digitalWrite(valves[2], HIGH);
digitalWrite(valves[3], HIGH);
digitalWrite(valves[4], HIGH);
digitalWrite(valves[5], HIGH);
digitalWrite(valves[6], HIGH);
digitalWrite(valves[7], HIGH);
digitalWrite(valves[8], HIGH);
digitalWrite(valves[9], HIGH);
digitalWrite(valves[10], HIGH);
digitalWrite(valves[11], HIGH);
digitalWrite(valves[12], HIGH);
digitalWrite(valves[13], HIGH);
digitalWrite(valves[14], HIGH);
digitalWrite(valves[15], HIGH);
digitalWrite(valves[16], HIGH);
digitalWrite(valves[17], HIGH);
digitalWrite(valves[18], HIGH);
digitalWrite(valves[19], HIGH);
digitalWrite(valves[20], HIGH);
digitalWrite(valves[21], HIGH);
digitalWrite(valves[22], HIGH);
digitalWrite(valves[23], HIGH);
digitalWrite(valves[24], HIGH);
digitalWrite(valves[25], HIGH);
digitalWrite(valves[26], HIGH);
digitalWrite(valves[27], HIGH);
//Timers
noInterrupts(); // отключаем все прерывания
TCCR3A = 0;
TCCR3B = 0;
OCR3A = 15624; // счетчик по совпадению 1 секунду отсчитываем
TCCR3B |= (1 << WGM12);
TCCR3B |= (1 << CS10) | (1 << CS12); // 1024 (коэффициент деления предделителя)
TIMSK3 |= (1 << OCIE3A); // устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)устанавливаем бит разрешения прерывания 1ого счетчика по совпадению с OCR1A(H и L)
interrupts();
}
void loop() {
}
void processSections(boolean even, boolean in, boolean out) { // функция принимает первый параметр четные или не четные секции : 2 параметр это вкл впускной клапан 3
if (even) {
for (int i = 2; i < 26; i = i + 4 ) {
processing1Section(in, out, i);
}
}
if (!even) {
for (int i = 4; i < 26; i = i + 4 ) {
processing1Section(in, out, i);
}
}
}
void processing1Section(boolean in, boolean out, int section) {
if (in && !out) {
digitalWrite(valves[section], LOW);
digitalWrite(valves[section + 1], HIGH);
}
if (out && !in) {
digitalWrite(valves[section], HIGH);
digitalWrite(valves[section + 1], LOW);
}
if (!in && !out) {
digitalWrite(valves[section], HIGH);
digitalWrite(valves[section + 1], HIGH);
}
}
//to process interrupt of timers
ISR(TIMER3_COMPA_vect) {
TIMSK3 |= (0 << OCIE3A);
timerCount2++;
hardCode();
TIMSK3 |= (1 << OCIE3A);
}
void hardCode() {
if (timerCount2 == 5) { // первая секция впуск
processing1Section(true, false, 0);
}
if (timerCount2 == 20) { // не четные секции впуск
processSections(false, true, false);
}
if (timerCount2 == 30) {
processSections(true, true, false); // четные секции впуск
processSections(false, false, false); // не четные секции стоп
processing1Section(false, false, 0); // первая секция стоп
}
if (timerCount2 == 40) { // четные секции стоп
processSections(true, false, false);
}
// процесс спуска
if (timerCount2 == 50) { // спускаем четные секции
processSections(true, false, true);
}
if (timerCount2 == 65) { // первая секции выпуск и вкл разгибатель
processing1Section(false, true, 0);
processing1Section(true, false, 26); // разгибатель вкл
}
if (timerCount2 == 70) { // спускаем не четные секции
processSections(false, false, true);
}
if (timerCount2 == 75) { // спускаем не четные секции
processing1Section(false, true, 26); // разгибатель спуск
}
if (timerCount2 == 90) {
processSections(true, false, false); // четные секции стоп
processSections(false, false, false); // не четные секции стоп
processing1Section(false, false, 26); // разгибатель стоп
processing1Section(false, false, 0);
timerCount2 = 0;
}
}
В 15 строке:
не?
Я, наверное, опять вопрос не понял....
Мне кажется, вы слишком много запихнули в прерывание.
128 строку убрать из прерывания, а hardCode() воткнуть в loop()
А еще с 19 строки по 46 проще записать так:
А с 48 по 75 так:
у меня loop пустой наверное без разницы сколько в прерывании кода
а в чем разница между int и uint32/8_t ?
Если есть возможность, добавьте вывод в Serial для отладки.
Например
- сообщение при старте, - может быть МК перезагружается от срабатывания реле.
- Сообщение при сбросе счетчика, чтобы понять когда он сбрасывается
И т.д.
у меня loop пустой наверное без разницы сколько в прерывании кода
Нет, в прерывании много кода - есть очень, очень плохо
А еще с 19 строки по 46 проще записать так:
А с 48 по 75 так:
Думаю где то здесь
Думаю где то здесь
Здесь верхняя и нижняя строка просто лишние (а верхняя и с ошибкой), но вреда от них быть не должно.
а в чем разница между int и uint32/8_t ?
int - 2 байта, знаковый
uint8_t - 1 байт беззнаковый
uint32_t - 4 байта беззнаковый
у меня loop пустой наверное без разницы сколько в прерывании кода
На обработку прерывания, на сколько мне известно, отводится ограниченное время.
"На обработку прерывания, на сколько мне известно, отводится ограниченное время."
Это где написано? И откуда оно берется?
TCCR3B = 0; - таймер остановлен
"На обработку прерывания, на сколько мне известно, отводится ограниченное время."
Это где написано? И откуда оно берется?
это обыкновенный здравый смысл. Даже в "пустом" ардуино коде "за сценой" постоянно выполняются разные процедуры, самый простой пример - обновление миллис
Если код вашего прерывания длится дольше одного периода миллис - системные часы начнут отставать
да и вообще. идея запихать всю программу в прерывание - это худшей степени гавнокод
И в данном случае это именно гавнокод... автор это сделал не из какого-то замысла, а просто от кривых рук... раз он не умеет пользоваться массивами и не понимает разницы между uint32 и uint8
"На обработку прерывания, на сколько мне известно, отводится ограниченное время."
Это где написано? И откуда оно берется?
Вот так и с прерыванием. Это такие же "штаны". У нормальных людей и в нормальных ситуациях на отработку прерываний отводится минимальное время, а основную работу делают в основном цикле. Но если кому-то хочется носить какахи в штанах, так в мире "дерьмократия".
Я на слова "отводится ограниченное время" - спросил сколько? Поскольку такого нет. Учить как писать программы - это хорошо. Но если человеку не надо миллис - у него свое время и если кроме вкл-выкл через некоторые промежутки времени ничего делать не надо - можно и в ISR все вставить. Вам шашечки или ехать? если кто то докажет что этот код работать не будет - сниму шляпу. Какая программа самая лучшая - ответ "работающая"... Боязнь что то пропустить во время ISR - это когда действительно есть что пропустить... А здесь нет. А тем кто претендует на написание НЕ говнокода и гадит снимая штаны - предлагаю выставить здесь ваши работы. Поучимся...
"отводится ограниченное время" это не больше 1% работы процессора, а лучше уложиться в 100 машинных команд. Ведь вам не понравится, если Вы наняли работника. А он вместо работы трендит по мобилке и устраивает перекуры. Прерывания это оно и есть. И если вся работа это сплошные прерывания, то это не правильно построенная работа.
В этой задаче в прерывании нужно взвести флаг, а вот в основном цикле сделать всю операцию и сбросить этот флаг. И штаны будут чистые. И какахи в строго отведенном для этого месте. https://habr.com/ru/post/453276/
ПС: А ТС пусть сначала помигает светодиодиком по таймеру, а потом уже начнет подключать реле по чуть чуть.
Академические знания никто не отменял. Да, если читать лекции по программированию - вы правы. Но только почему не 0.1 и не 50? Да и конкретная реализация не обязательно требует АБСОЛЮТНО придерживаться эмпирических знаний. Мы здесь о конкретной задаче, а не при теорию. Кстати, мне приходилось писать программы в которых main - это halt. Только обработчики прерываний. И ничего - чудненько работали. Ну правда на ассемблере.
А по ссылке - НИКАКИХ флагов не нашел !!!!!!!!!!!!!!!!!!!!!!!!!!
Мы здесь о конкретной задаче, а не при теорию. Кстати, мне приходилось писать программы в которых main - это halt. Только обработчики прерываний. И ничего - чудненько работали. Ну правда на ассемблере.
конкретная задача яйца выеденного не стоит и обсуждать ее смысла нет. Никакие прерывания тут вообще не нужны.
_Igor_, вы зачем-то лезете в бутылку и пытаетесь доказать мысль "говнокод тоже иногда работает". С этим никто не спорит. Но обсуждать подобное на форуме нет ни малейшего смысла. Мы тут не делимся друг с другом "конкретными решениями" задач, ибо это нафик никому не нужно.
Если что и интересно обсудить, то это как ту или иную задачу решить либо ПРАВИЛЬНО, либо КРАСИВО.
Main {
Di
Halt}
На спекки это бы было круто!!!
Я могу говорить только за себя - в среде ардуино «не канает долгое прерывание». Уж не знаю почему, я только учусь и в код иде не лез, но солидарен с утверждением, что прерывание - на то и прерывание, что чтобы сделать сейчас незамедлительно и быстро и вернуться к выполнению основной программы. Я больше чем уверен, что даже в ОС прерывания не выполняют основной код. Нажали кнопку - поехали дальше. Все.
Ну, а если пофантазировать... Или только строем?
Ну, а если пофантазировать... Или только строем?
«Все в твоих руках» ))
"Да чё тут думать! Трясти надо."
Я больше чем уверен, что даже в ОС прерывания не выполняют основной код.
нет, НО ТАМ ЕСТЬ ПРИОРИТЕТЫ, вообще то вся ось от одное сплошное прерывание INT21h )))
А если по-нашему, по деревенски. Так прерывания здесь и вообще не нужны. Скорости не те.
То ТС - Напишите НОРМАЛЬНУЮ программу, которую Вы понимаете, а ни этот шмундяк.
Просто идеально, учитывая, что из hardCode() вызывается функция.
Ой да ладно. Это же МК а не ОС на ББ. Тут собственно крутится одна задача и ей до лампочки где выполныться в основном цикле или в прерывании. Я вобщем тоже за минимум в прерывании и флаги. Но это когда задач много и они боряься за такты процессора. Если задач мало и они не требуют РТ, то можно и постебаться с наполненим разных частей программы. Работает - не трожь! Главное правило.
Дык, не работает жи )))
Дык, не работает жи )))
Дык, не работает жи )))
Почитаю :-)
вообще то вся ось от одное сплошное прерывание INT21h )))
Данунах...
А еще с 19 строки по 46 проще записать так:
А с 48 по 75 так: