Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
25.11.2010, 15:47
|
|
Временная регистрация
Регистрация: 14.09.2009
Сообщений: 87
Сказал спасибо: 6
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Задержки при плавной регулировке. Диммер с ДУ
Здравствуйте. Вот уже который день бьюсь над плавной регулировкой яркости С ПУЛЬТА ДУ. Она регулируется, но почему то "ступенчато". Не пойму где ошибка в программе.
Итак по порядку:
1. Составил таблицу временных задержек для регулировки мощности с шагом 1%
2. При нажатии кнопки происходит плавное включение/выключение (РАБОТАЕТ!!!)
3. Добавил пульт ДУ. Он непонятно чьего производства (был куплен за 250 руб взамен умершего пульта от ТВ тюнера Beholder). К тюнеру подошел. Правда пришлось "обучать" программу тюнера (это предусмотрено). Но всё работает. По ссылке, приведенной выше, видно что пульт для техники Samsung. Я предположил что работает он по протоколу NEC. Взял исходник от статьи "Некоторые протоколы ИК-пультов" для NEC протокола... Не заработало
Взялся за осциллограф. Оказалось что там не совсем NEC протокол... Т.е. единица и ноль кодируются как и в NEC протоколе:
Только вот стартовая последовательность отличается по времени:
~4,5 мс вместо 9 мс. И нет последовательности повтора!!! Т.е. при удержании кнопки посылка отсылается постоянно. Интервал между посылками 44,8 мс, длинна самой посылки 61,6 мс.
В посылке 32 бита: "адрес"+"адрес"+"команда"+"инв. команда"
(это данные с осциллографа!!!)
Адрес передается не инвертированный. Но он нам собственно и не нужен. Команда согласно NEC протоколу. Пришлось править исходник. А именно стартовую последовательность.
4. Я выяснил коды нужных мне кнопок, "вставил" их в программу и сравниваю с переменной cmd. А в OCR1A записываю соответствующую задержку:
Код:
|
/*========================================= УВЕЛИЧЕНИЕ/УМЕНЬШЕНИЕ ЯРКОСТИ =======================================*/
if (cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
TCCR1B=0x02;
status++;
if (status ›= 98) {
TCCR1B=0x00;
status = 98;
PORTC.5 = 1; // полностью включили
}
else {
OCR1A = nagruzka[status]; // увеличиваем яркость
delay_ms(delay_);
}
}
if (cmd == 0b11000000) { // кнопка "Sleep" - уменьшение яркости
TCCR1B=0x02;
status--;
if (status ‹ 1) {
status = 0; // чтобы не уйти в минус
PORTC.5 = 0; // полностью выключили
TCCR1B=0x00;
}
else {
OCR1A = nagruzka[status]; // уменьшаем яркость
delay_ms(delay_);
}
} |
Но вот незадача. При удержании кнопки яркость меняется, но очень странно. Медленно и как бы рывками что ли.
Итак, при нажатии на кнопку вкл/выкл: плавный старт, потом плавное отключение.
При нажатии на кнопку увеличения яркости, яркость должна так же плавно расти как и в предыдущем случае. До тех пор пока не отпустили кнопку. А она как бы замирает, увеличивается, замирает, увеличивается.
Я снял на видео как всё происходит:
Т.е. где то в коде не порядок.
У меня есть предположение: Просто сравнивать с переменной cmd видно нельзя. Вводить флаг повтора? Но посылки то одинаковые!!!. Как быть?
Команду я сбрасываю только если ничего не приходит уже на пин. Т.е. Условие if (cmd == 0b11000000) { должно выполняться при удержании кнопки. Или нет??????
Получается оно выполняется с какими то задержками... или где то команда успевает обнулиться и условие перестает выполняться. Чего то я запутался.
Код:
|
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xFA; //переинициировали таймер - отсчитывает 96 мкс
tick++; //увеличили число тиков
if (tick › 500) { //если прошло более 48 мс (интервал
// между посылками 44,8 мс)
TCCR0=0x00; //сбросили все к исходному состоянию
TCNT0=0x00;
tick = 0;
start_cond = 0;
//repeat_cond = 0;
cmd = 0;
} |
Как в таком случае корректно команду обработать? Вроде всё правильно
Я принял за условие что при удержании кнопки переменная cmd всегда равна коду нажатой кнопки ‹-- может это не правильно???
Пробовал
Код:
|
while (cmd == 0b11111000) {} |
не работает.
Я в отчаянии... Не понимаю почему не работает. Уже столько вечеров убил на это. Не регулируется плавно, хоть об стенку расшибись. Ну вроде всё правильно в коде.
Код в приложении:
Последний раз редактировалось mr_smit; 25.11.2010 в 15:50.
|
|
|
|
25.11.2010, 15:50
|
|
Временная регистрация
Регистрация: 14.09.2009
Сообщений: 87
Сказал спасибо: 6
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ.
Схема:
|
|
|
|
25.11.2010, 17:22
|
|
Гражданин KAZUS.RU
Регистрация: 20.05.2005
Сообщений: 660
Сказал спасибо: 40
Сказали Спасибо 187 раз(а) в 117 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ.
Оптопару надо через резистор включить и зачем так включать-
Цитата:
|
PORTC.5 = 1; // открыли симистор
delay_us(200); // импульс 200 мкс
PORTC.5 = 0; // вернулись в режим ожидания
|
Открыли в нужный момент, на ноле убрали с ноги сигнал, симистор закроется сам.
Видео посмотрел, на вид вроде нелады с синхронизацией...
Надо в отладчике прогнать, посмотреть что и как.
|
|
|
|
25.11.2010, 17:46
|
|
Почётный гражданин KAZUS.RU
Регистрация: 30.06.2005
Сообщений: 3,399
Сказал спасибо: 5
Сказали Спасибо 431 раз(а) в 306 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ.
Сообщение от lyk
|
Оптопару надо через резистор включить и зачем так включать-
Открыли в нужный момент, на ноле убрали с ноги сигнал, симистор закроется сам.
Видео посмотрел, на вид вроде нелады с синхронизацией...
Надо в отладчике прогнать, посмотреть что и как.
|
Правильно у него все сделано. Нельзя близко к 0 убирать
|
|
|
|
25.11.2010, 19:58
|
|
Временная регистрация
Регистрация: 14.09.2009
Сообщений: 87
Сказал спасибо: 6
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ
Правильно то правильно, только не работает. Главное не пойму где затык. Всё вроде гладко
|
|
|
|
25.11.2010, 21:16
|
|
Гражданин KAZUS.RU
Регистрация: 20.05.2005
Сообщений: 660
Сказал спасибо: 40
Сказали Спасибо 187 раз(а) в 117 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ.
Сообщение от Gnider
|
Нельзя близко к 0 убирать
|
Почему? Что в этом плохого?
При большом токе тиристор/симистор после ноля закрывается, скопом смотрел, и при этом ему один хе# хоть пачку импульсов давать, хоть 1 короткий(0,3-1mS), хоть 1 длинный(на весь полупериод), лишь бы он нормально включался в нужный нам момент, а закроется он все одно сам.
зы.У меня на сварочнике(полуавтомат) так сделано ФИУ по вторичке на МК, года 3 молотит, все живое, ничего плохого не заметил.
|
|
|
|
25.11.2010, 21:33
|
|
Временная регистрация
Регистрация: 14.09.2009
Сообщений: 87
Сказал спасибо: 6
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ
Проблема в коде, только вот не пойму где
|
|
|
|
25.11.2010, 22:01
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ
При приеме валидной посылки инвертируйте состояние светодиода. Во время регулировки сможете по равномерности мигания определить равномерно ли принимаются посылки от пульта.
И реакцию на пульт измените как нибудь так:
Код:
|
if(cmd)
{
if(cmd == BRIGHT_UP)
{
// увеличиваем яркость
cmd = NO_COMMAND;
}
if(cmd == BRIGHT_DOWN)
{
// уменьшаем яркость
cmd = NO_COMMAND;
}
// остальные команды аналогично
} // if(cmd) |
|
|
|
|
25.11.2010, 22:02
|
|
Вид на жительство
Регистрация: 21.10.2009
Сообщений: 343
Сказал спасибо: 181
Сказали Спасибо 64 раз(а) в 56 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ
Сообщение от mr_smit
|
Правильно то правильно, только не работает. Главное не пойму где затык. Всё вроде гладко
|
Код:
|
if (cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
TCCR1B=0x02;
status++;
if (status ›= 98) {
TCCR1B=0x00;
status = 98;
PORTC.5 = 1; // полностью включили
}
else {
OCR1A = nagruzka[status]; // увеличиваем яркость
delay_ms(delay_);
}
} |
Зачем здесь
Пришла повторная команда, надо выполнять. У вас похоже, после задержки, какое то время не удается поймать начало посылки.
(Если необходимо замедлить реакцию нп. в три раза применяйте что то типа
Код:
|
OCR1A = nagruzka[status /3]; |
)
Вместо того, чтобы делать прерывания минимально короткими, вы в них применяете задержку. А ведь пока выполняется одно прерывание, то другое прерывание, с более низким приоритетом, будет отложено.
Да на вывод PD2 Zero, не помешало бы поставить стабилитрон так на 4.1 В.(Не стоит на вход подавать напряжение превышающее напряжение питания проца.)
Последний раз редактировалось CodeNameHawk; 25.11.2010 в 23:16.
|
|
|
|
25.11.2010, 23:26
|
|
Временная регистрация
Регистрация: 14.09.2009
Сообщений: 87
Сказал спасибо: 6
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Задержки при плавной регулировке. Диммер с ДУ
Пока победил это так:
Код:
|
bit button_up =0;
...
if ((cmd_1 + cmd_0) == 0xFF) { //проверили правильность приема команды
button_up = no;
cmd = cmd_1;
}
...
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=0xFA; //переинициировали таймер - отсчитывает 96 мкс
tick++; //увеличили число тиков
if (tick › 500) { //если прошло более 48 мс
button_up = yes;
...
}
...
if (cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
TCCR1B=0x02;
while (button_up == no) {
status++;
if (status ›= 98) {
TCCR1B=0x00;
status = 98;
PORTC.5 = 1; // полностью включили
}
else {
OCR1A = nagruzka[status]; // увеличиваем яркость
delay_ms(delay_);
}
}
}
... |
Т.е. если прошло более 48 мс и от TSOPа ничего не пришло, то значит кнопку отпустили button_up = yes; и увеличение яркости в цикле while (button_up == no) прекращается.
Теперь регулируется плавно. Но заметил такую особенность: если нажать кнопку уменьшения яркости, а потом через 0,5-1 или 2-3 сек нажать кнопку увеличения яркости, то яркость продолжает уменьшаться
Подождал. Дальше как надо регулируется.
Достала эта не стабильность ((((((((((((
Последний раз редактировалось mr_smit; 25.11.2010 в 23:28.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 23:26.
|
|