Управление печкой(нагревателем)
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 01 сен 2023, 15:43
Схема управления нагревателем 220v
через PC814 (датчик нуля - zero crossing) вызываем прерывание на МК, по этому прерыванию плюсуем счетчик проходов через ноль, задача пропускать n количество полуволн переменки, например одну, загоняю в симулятор (в железе тоже) и получаем вот такую фигню
желтый - переменка
красный - "обрезанная" переменка
синий - сигнал от датчика нуля
зеленый управляющий импульс от МК
вопрос - почему происходит обведенное красным, т.е. МК забывает пропустить один импульс при том, что прерывание сработало? И происходит это хаотично.
R9OFG
-
- Сообщения: 365
- Зарегистрирован: 22 окт 2019, 16:06
- Позывной: R2AVB
- Город: Москва
- Имя: Олег
- Благодарил (а): 48 раз
- Поблагодарили: 117 раз
Управление печкой(нагревателем)
Сообщение Oleg » 01 сен 2023, 16:17
Если это она, то следующий вопрос. Вы управляющую программу написали как "скетч" (C++) для среды Arduino или же на чистом C в Atmel Studio?
R2AVB
Oleg
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 01 сен 2023, 16:24
Код: Выделить всё
ISR(INT4_vect)
{
if(zero_crossing_counter == 1)
{
//подаем импульс для включения плиты нагрева
PORTD |= (1 << STOVE);
_delay_us(100);
PORTD &= ~(1 << STOVE);
}
zero_crossing_counter++;
if(zero_crossing_counter > 1) zero_crossing_counter = 0;
}
R9OFG
-
- Сообщения: 365
- Зарегистрирован: 22 окт 2019, 16:06
- Позывной: R2AVB
- Город: Москва
- Имя: Олег
- Благодарил (а): 48 раз
- Поблагодарили: 117 раз
Управление печкой(нагревателем)
Сообщение Oleg » 01 сен 2023, 18:16
Для начала я предлагаю проверить, что переменная zero_crossing_counter не изменяется за пределами подпрограммы обработки прерывания.
Оставьте в подпрограмме только формирование импульса без всяких условий, то есть три строчки.
Тогда управляющие импульсы должны следовать в ответ на каждый импульс на входе внешнего прерывания.
R2AVB
Oleg
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 01 сен 2023, 18:44
Я уже и так сделал, завел объявление этой переменной в функцию с сохранением значения, тут явно она поменяться извне не может
Код: Выделить всё
void On_Power_Stove(int power) //включение плиты нагрева с заданной мощностью
{
//вариант 2: MOC3063 с ZERO-CROSSING, используем внешнее прерывание INT4 на пине PE4
{
static int zero_crossing_counter = 0; //счетчик ZERO CROSSING (проход через ноль)
if(zero_crossing_counter == 1)
{
//подаем импульс для включения плиты нагрева
PORTD |= (1 << STOVE);
//_delay_us(300);
PORTD &= ~(1 << STOVE);
}
zero_crossing_counter++;
if(zero_crossing_counter > 1)
{
zero_crossing_counter = 0;
}
}
}
ISR(INT4_vect)
{
On_Power_Stove(0);
}
Настройка внешнего прерывания на INT4 в main (пробовал настройку и по нарастанию и по смене 0/1)
Код: Выделить всё
//настройка внешнего прерывания INT4 - пин PE4
{
EIMSK = (1<<INT4);
//настройка прерывания по спаду
EICRB = (1<<ISC71)|(0<<ISC70);
}
//разрешаем глобальные прерывания
sei();
уже дым из ушей идет ну не понимаю природу этого бага! Но есть же какая то причина!
Вот к примеру вообще уберем zero_crossing_counter, т.е. включаться будем по каждому переходу через ноль "забывчивость" пропадает и все красиво...
R9OFG
-
- Сообщения: 365
- Зарегистрирован: 22 окт 2019, 16:06
- Позывной: R2AVB
- Город: Москва
- Имя: Олег
- Благодарил (а): 48 раз
- Поблагодарили: 117 раз
Управление печкой(нагревателем)
Сообщение Oleg » 01 сен 2023, 19:44
Так именно это я и имел в виду.
Теперь надо искать, где и что происходит с zero_crossing_counter. В принципе можно оставить её как глобальную переменную, ничего страшного. Надо разобраться.
Если возможно, дайте полный исходник (можно на e-mail). Может что-то в голову придет.
R2AVB
Oleg
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 01 сен 2023, 20:18
Код: Выделить всё
void On_Power_Stove(int power) //включение плиты нагрева с заданной мощностью
{
//вариант 2: MOC3063 с ZERO-CROSSING, используем внешнее прерывание INT4 на пине PE4
{
static volatile int zero_crossing_counter = 0; //счетчик ZERO CROSSING (проход через ноль)
if(zero_crossing_counter == 1)
{
//подаем импульс для включения плиты нагрева
PORTD |= (1 << STOVE);
PORTD &= ~(1 << STOVE);
}
_delay_us(100);
zero_crossing_counter++;
if(zero_crossing_counter > 1)
{
zero_crossing_counter = 0;
}
}
}
ниже картинка пропуска одной полу волны
а вот пропуск каждой второй полу волны
R9OFG
-
- Сообщения: 365
- Зарегистрирован: 22 окт 2019, 16:06
- Позывной: R2AVB
- Город: Москва
- Имя: Олег
- Благодарил (а): 48 раз
- Поблагодарили: 117 раз
Управление печкой(нагревателем)
Сообщение Oleg » 01 сен 2023, 21:08
При чем здесь задержка - непонятно. Здесь какой-то баг.
Никак не может быть "лишней операции". Это же примитивный процессор с одним потоком. Конечно же, надо посмотреть промежуточный код на ассемблере, если будет время.
Ещё один момент. В программе обработки прерывания желательно делать всё быстро - заходим, ставим флажки, несколько быстрых действий с переменными - и всё. Остальное - в основном цикле программы. Ну это так - общий подход для более нагруженных систем.
R2AVB
Oleg
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 02 сен 2023, 04:17
До конца еще не вникал в происходящее, но появилось предположение, что функция выполняется из прерывания иногда не один раз, а два, по подобию эффекта дребезга кнопки, в данном случае помогла задержка перед изменением счетчика проходов через ноль.
Повторюсь, это не конечное заключение, пока предположение!
Этот момент всегда в голове!
R9OFG
- R9OFG
- Сообщения: 1183
- Зарегистрирован: 03 ноя 2019, 22:30
- Позывной: R9OFG, ex R0AEK
- Город: Новосибирск
- Имя: Саша
- Благодарил (а): 182 раза
- Поблагодарили: 276 раз
- Контактная информация:
Управление печкой(нагревателем)
Сообщение R9OFG » 10 сен 2023, 08:50
было
Код: Выделить всё
//настройка внешнего прерывания INT4 - пин PE4
{
EIMSK = (1<<INT4);
//настройка прерывания по спаду
EICRB = (1<<ISC71)|(0<<ISC70);
}
//разрешаем глобальные прерывания
sei();
вот так будет правильно
Код: Выделить всё
//инициализация внешнего прерывания INT4
{
//настройка внешнего прерывания INT4 по спаду
EICRB = (1<<ISC41)|(0<<ISC40);
//внешнее прерывание INT4
EIMSK |= (1<<INT4);
}
R9OFG
Вернуться в «Микроконтроллеры и программирование»
- Обязательно к прочтению
- Аналоговая схемотехника
- ↳ Супергетеродинные приемники и трансиверы
- ↳ Прямое преобразование
- ↳ Прямое усиление
- ↳ Регенераторы
- ↳ Узлы, блоки, модули
- ↳ Усилители мощности
- Цифровая техника
- ↳ SDR приемники
- ↳ SDR приставки
- ↳ SDR трансиверы
- ↳ Микроконтроллеры и программирование
- Теплая лампота
- ↳ Супергетеродины
- ↳ Регенераторы
- ↳ Прямого усиления
- ↳ УНЧ
- ↳ ВЧ усилители мощности
- Источники питания
- ↳ Трансформаторные и линейные
- ↳ Импульсные и преобразователи
- ↳ Гибриды
- ↳ Аккумуляторы и батареи
- ↳ Альтернативные источники
- Антенны
- ↳ Антенны КВ
- ↳ Антенны УКВ
- ↳ Фидеры кабели
- ↳ Антенные приборы и устройства
- ↳ Тюнеры
- Фирменная аппаратура
- ↳ Yaesu
- ↳ Icom
- ↳ Kenwood
- ↳ Прочие
- Мастерская
- ↳ Измерения, приборы и софт
- ↳ Паяльное оборудование
- ↳ Слесарка
- ↳ ЧПУ и 3D принтеры
- Разное
- ↳ Другие радио темы
- ↳ Полевой день
- ↳ Помогите опознать
- ↳ Куплю Продам Магазины Продавцы
- ↳ Флудильня и оффтоп
- Работа форума