Диммер, управляемый через Serial
- Войдите на сайт для отправки комментариев
Вс, 30/03/2014 - 12:15
Добрый день!
Требуется создать диммер, управляющий яркостью лампочки. Яркость задается через com порт через сериал. Окончание числа - пробел (мне так удобнее). Схему собрал согласно статье http://www.instructables.com/id/Arduino-controlled-light-dimmer-The-circ.... Вот сама схемка: http://cdn.instructables.com/FQZ/NYV7/H8CVG9TK/FQZNYV7H8CVG9TK.LARGE.jpg Вот код прошитый в ардуинку (Due):
String Bi = ""; int AC_LOAD = 3; int dimming = 256; void setup() { Serial.begin(9600); pinMode(AC_LOAD, OUTPUT);// Устанавливаем AC Load пин как вывод attachInterrupt(2, ZC, RISING); } void ZC(){ int dimtime = (39*(256-dimming)); // Полное время delayMicroseconds(dimtime); // Ждем digitalWrite(AC_LOAD, HIGH); // Триак посылает сигнал зажечься delayMicroseconds(10); // Триак ждет, для 50 Гц - 10мс digitalWrite(AC_LOAD, LOW); // Триак посылает сигнал потухнуть } void loop() { while (Serial.available() > 0) { char c = Serial.read(); if (c == ' ') { Serial.println(Bi); dimming = Bi.toInt(); Bi = ""; } else { Bi += c; } } }
Посылаю через сериал яркость и пробел: пару значений воспринимает нормально и регулирует яркость, а потом не принимает ничего, а лампочка ведет себя более чем странно: яркость постепенно падает, потом доходит до 0, затем снова на максимум и повторяется :( помогите, пожалуйста!
Неужели никто не знает, где ошибка? (
А что тут знать ?! Как по вашему. Вот поднялось прерывание. Процессор все бросил и начал его отрабатывать. А в нем задержка. А все другие прерывания ? Что с ними ? Что вычитывает процессор с последовательного интерфейса ? Ошибок нет ? Вы уверены ?
т.е. из-за того, что каждый полуцикл в сети у меня включается функция прерывания, у меня не прочитывает данные с serial? Если так, то подскажите, пожалуйста, альтернативу. С другой стороны, вычисления в прерывании простые, и задержки равны микросекундам, что не должно сильно портить ситуацию
Я всего лишь предположил. И это не из-за того, что прерывание происходит 50 раз в секунду, а изза того , что в нем используется тупая задержка, пожирающая ресурсы процессора. Почитайте тему "мигаем без задержки", должно помочь. Для исключения зависания в прерываниях стоит воспользоваться прерыванием от таймера. Не знаю возможно ли это в ардуино, но атмел это может точно.
Кстати максимальное восьмибитное значение это 255, а не 256 :-)
...задержки равны микросекундам, что не должно сильно портить ситуацию
так она, ситуация-то не сильно и испортилась. сами же пишите - кое-как, но работает. так что никаких претензий.
а альтернатива - никаких задержек в прерываниях.
Переправил чуть код. Постарался избавиться от delay... но совсем не работает: лампочка горит постоянно. Подскажите, пожалуйста, в чем ошибка?
Вы не поняли. Вы просто замении одну задержку другой... почитайте тему мигаем без задержек.
Попробуйте считывать значение таймера в прерывании вычислять задержку, a проверять совпадение с задержкой в основном цикле программы и там же отрабатывать его. Выбросте ненужные циклы.
В той статье действительно сравнение в теле цикла Loop...Попытался сделать так же, как описано там. High - это маркер, чтобы не повторять по многу одно и тоже до следующего прерывания... Вот код: на посылку из сериал яркость лампы не реагирует, хотя и воспринемает и отсылает обрптно.
Добавьте перед 38 строкой serial.println(dimming,DEC) ; . Что получается ?
Помимо Вi, выводится димминг. Точно такое же числовое значение, т.е. воспринимается
ВИЖУ !!!
Даже если в теле программы убрать ввод через сериал и оставить постоянное значение димминга, то оно не управляется, после того, как я вынес из прерывания задержки... значит где то в них косяк :(
Перед 22 строкой добавляем сurentMicros=micros(); кроме того переменную curentMicros можно вообще выбросить изменив ее на micros().
То же самое: 0 эмоций лампы
Покажите исправленый скетч.
В прерывании currentMicroc на micros то же попробуйте заменить.
То же самое: ничего не изменилось
Давайте пожалуйста 22 строчку поменяем на вот так
Ну и для красоты расчет из 21 строчки я бы перенес в 41 оставив в 21 только объявление переменной.
Опять не меняется яркость... есть подозрение, что я неудачник :(
Ну тогда я тоже :-)
В любом случае, спасибо за помощь! Если найду как поправить - напишу сюда
Посотрите повнимательнее, может что то с исполнительной схемой приключилось. Попробуйте закоментировать строку где на управляющей ножке поднимается единица. Погаснет лампа или нет ?
Хм..Схема впорядке: прошил старую программу: регулируется пару раз, потом старая проблема.
А вот закомментил строку - действительно не гаснет... Вот код
Ешкин дрын... где
currentMicros = micros();
???
Извините, видимо не сохранил!
Вроде работает! Огромное вам спасибо!
А всего лишь невнимательность :-) Да со всеми бывает. Иной раз зациклишься на какой то мелочи и кукуешь.