Интересует в первую очередь такой момент: 16-тибитный счетчик я уже задействовал. Остались только 8-мибитные. На них можно поднять ДУ ? Я имею ввиду интервалы времени для отслеживания кода посылки можно задать? Вопрос может и глупый, пока к написанию этой части кода не приступал. Но в посылках, насколько я помню, есть интервалы в микросекундах. С 8-мибитным счетчиком кажется к микросекунде не подобраться. Или я ошибаюсь? Вы как делали?
Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил.)
ARV, прошу прощения за наглость. Но мне бы кусочек кода на C.
Интересует в первую очередь такой момент: 16-тибитный счетчик я уже задействовал. Остались только 8-мибитные. На них можно поднять ДУ ? Я имею ввиду интервалы времени для отслеживания кода посылки можно задать? Вопрос может и глупый, пока к написанию этой части кода не приступал. Но в посылках, насколько я помню, есть интервалы в микросекундах. С 8-мибитным счетчиком кажется к микросекунде не подобраться. Или я ошибаюсь? Вы как делали?
Интересует в первую очередь такой момент: 16-тибитный счетчик я уже задействовал. Остались только 8-мибитные. На них можно поднять ДУ ? Я имею ввиду интервалы времени для отслеживания кода посылки можно задать? Вопрос может и глупый, пока к написанию этой части кода не приступал. Но в посылках, насколько я помню, есть интервалы в микросекундах. С 8-мибитным счетчиком кажется к микросекунде не подобраться. Или я ошибаюсь? Вы как делали?
Нельзя всё знать, достаточно понимать.
- Реклама
я делал на единственном 8-битном таймере тини13 одновременно и фазовое регулирование и прием RC5-кода
однако, потом пришел к выводу, что занимался извращениями - если для фазового регулирования смысл в таймере еще есть, то прием кодов ДУ элементарно делается исключительно на программных задержках. код вы можете почерпнуть из моей статьи http://arv.radioliga.com/content/view/219/43/
P.S. о какой наглости вы говорите, mr_smit? по-моему, вы доказали свою самостоятельность, а такому человеку не грех и помочь побольше, чем обычному лентяю. я самостоятельных уважаю.
P.S. о какой наглости вы говорите, mr_smit? по-моему, вы доказали свою самостоятельность, а такому человеку не грех и помочь побольше, чем обычному лентяю. я самостоятельных уважаю.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 877
- Зарегистрирован: Чт фев 18, 2010 13:51:56
Я обычно в случае, если нужно много таймеров настраиваю аппаратный таймер на частоту около 10кГц и в нём декрементирую счётчики программных таймеров. А в основном цикле программы проверяю эти счётчики на равенство нулю.
При этом прерывание выглядит так:
А main так:
При этом в программе нет ни одного вызова delay_ms. Все переменные таймеров очень желательно делать однобайтными для ускорения работы прерывания, а в случае двухбайтных не забывать про неатомарность доступа к ним.
При этом прерывание выглядит так:
Код: Выделить всё
volatile unsigned char longDelayTimer1,timer1,timer2,timer3,timer4;
ISR(TIMER0_OVF0_vect)
{// 10 kHz
if (timer1>0) timer1--;
if (timer2>0) timer2--;
*****
if (longDelayTimer1>0) longDelayTimer1--;
else {
longDelayTimer1 = 255;
if (timer3>0) timer3--;
if (timer4>0) timer4--;
***
}
}
Код: Выделить всё
int main()
{
InitSystem();
sei();
while (1) {
if (!timer1) {
timer1 = 100;
***
}
if (!timer2 && timer2on) {
timer2 = 200;
***
}
*****
}
return 0;
}
Да... долго я отсутствовал... На работе был занят. Вернулся к проекту. И вот уже который день бьюсь над плавной регулировкой яркости С ПУЛЬТА ДУ. Она регулируется, но почему то "ступенчато". Не пойму где ошибка в программе.
Итак по порядку:
1. Составил таблицу временных задержек для регулировки мощности с шагом 1%
2. При нажатии кнопки происходит плавное включение/выключение (РАБОТАЕТ!!!)
3. Добавил пульт ДУ. Он непонятно чьего производства (был куплен за 250 руб взамен умершего пульта от ТВ тюнера Beholder). К тюнеру подошел. Правда пришлось "обучать" программу тюнера (это предусмотрено). Но всё работает. По ссылке, приведенной выше, видно что пульт для техники Samsung. Я предположил что работает он по протоколу NEC. Взял исходник от статьи "Некоторые протоколы ИК-пультов" для NEC протокола... Не заработало
Взялся за осциллограф. Оказалось что там не совсем NEC протокол... Т.е. единица и ноль кодируются как и в NEC протоколе:

Только вот стартовая последовательность отличается по времени: ~4,5 мс вместо 9 мс. И нет последовательности повтора!!! Т.е. при удержании кнопки посылка отсылается постоянно. Интервал между посылками 44,8 мс, длинна самой посылки 61,6 мс.
В посылке 32 бита: "адрес"+"адрес"+"команда"+"инв. команда"
(это данные с осциллографа!!!)
Адрес передается не инвертированный. Но он нам собственно и не нужен. Команда согласно NEC протоколу. Пришлось править исходник. А именно стартовую последовательность.
4. Я выяснил коды нужных мне кнопок, "вставил" их в программу и сравниваю с переменной cmd. А в OCR1A записываю соответствующую задержку:
Но вот незадача. При удержании кнопки яркость меняется, но очень странно. Медленно и как бы рывками что ли.
Т.е. где то в коде не порядок.
У меня есть предположение: Просто сравнивать с переменной cmd видно нельзя. Вводить флаг повтора? Но посылки то одинаковые!!!. Как быть?
Команду я сбрасываю только если ничего не приходит уже на пин. Т.е. Условие if (cmd == 0b11000000) { должно выполняться при удержании кнопки. Или нет??????
Получается оно выполняется с какими то задержками... или где то команда успевает обнулиться и условие перестает выполняться. Чего то я запутался.
Как в таком случае корректно команду обработать? Вроде всё правильно
код:
Итак по порядку:
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;
}
код:
Нельзя всё знать, достаточно понимать.
Совсем никаких идей?
Нельзя всё знать, достаточно понимать.
- Реклама
И ещё почему то ИНОГДА при плавном включении (от кнопки) проскакивает несколько морганий... то ли контроллер сбивается, то ли датчик нуля барахлит. Может в нем чего нибудь улучшить? Не особо усложняя конструкцию.
P.S. Вопрос по пульту ДУ остается открытым.
P.S. Вопрос по пульту ДУ остается открытым.
Нельзя всё знать, достаточно понимать.
Вот такая схема у меня получилась:
У кого нибудь есть пример работы с DS1307 с помощью АППАРАТНОГО i2c ? А то во всех примерах программный используется.
Последний раз редактировалось mr_smit Вс ноя 21, 2010 16:10:46, всего редактировалось 1 раз.
Нельзя всё знать, достаточно понимать.
LS020 не подключишь к контроллеру на прямую. он 3х вольтовый.
Уже подключил и РАБОТАЕТ!!!
Как раз только с LS020 это и можно сделать. Дисплеи на других контроллерах сгорают.
Схему посмотрите пожалуйста. Может чего улучшить можно? добавить?
Как раз только с LS020 это и можно сделать. Дисплеи на других контроллерах сгорают.
Схему посмотрите пожалуйста. Может чего улучшить можно? добавить?
Нельзя всё знать, достаточно понимать.
по поводу ДУ непонятно...
Получается что яркость устанавливается только после приема пачки команд а не во время приема?
Думаю строчку
надо куда-то вынести в прерывание - пускай само обрабатывается. В основной программе оперировать только переменной status.
ПС: вернее вообще получается что свет включится только когда status >= 98
Код: Выделить всё
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];ПС: вернее вообще получается что свет включится только когда status >= 98
Нет. Я регулирую яркость от 1% до 99%. Крайние положения выставляю явно, т.е. PORTC.5 = 1 - 100% яркость. Чтобы симистор был полностью открыт. А пока status<98 OCR1A = nagruzka[status];alex2103 писал(а):ПС: вернее вообще получается что свет включится только когда status >= 98
Переменной cmd присваивается код команды только после того как команда полностью принята.
Я принял за условие что при удержании кнопки переменная cmd всегда равна коду нажатой кнопки <-- может это не правильно???
Поэтому в основной программе и сравниваю cmd с заранее известным кодом кнопки. Т.е. пока команда не равна нулю (пока кнопку не отпустили) увеличивать переменную status и изменять значение OCR1A.
Просто я никак не пойму по какому условию мне фиксировать что кнопка удерживается нажатой???
Получается что
Код: Выделить всё
if (cmd == 0b11111000) {}Нельзя всё знать, достаточно понимать.
Действительно...что-то я вчера недоглядел
cmd формируется в прерывании...почему бы тогда вместо
не сделать
Я вот тоже на днях займусь диммером. Специально даже пультик небольшой с RC5 прикупил на 8 кнопок 
cmd формируется в прерывании...почему бы тогда вместо
Код: Выделить всё
if (cmd == 0b11111000) {}Код: Выделить всё
while (cmd == 0b11111000) {}Потому что не работает. Пробовал 
Код: Выделить всё
while (cmd == 0b11111000) {}Нельзя всё знать, достаточно понимать.
Я в отчаянии...
Не понимаю почему не работает. Уже столько вечеров убил на это. Не регулируется плавно, хоть об стенку расшибись. 
Нельзя всё знать, достаточно понимать.
Итак, при нажатии на кнопку вкл/выкл: плавный старт, потом плавное отключение.
При нажатии на кнопку увеличения яркости, яркость должна так же плавно расти как и в предыдущем случае. До тех пор пока не отпустили кнопку. А она как бы замирает, увеличивается, замирает, увеличивается.
Я снял на видео как всё происходит: http://www.youtube.com/watch?v=7xy9u1OUq9s
И ещё, ИНОГДА, при плавном старте проскакивает мигание лампы. Иногда всё нормально. Иногда несколько миганий. Откуда берутся эти мигания не понятно. В видео, мигание на 6-ой секунде.
При нажатии на кнопку увеличения яркости, яркость должна так же плавно расти как и в предыдущем случае. До тех пор пока не отпустили кнопку. А она как бы замирает, увеличивается, замирает, увеличивается.
Я снял на видео как всё происходит: http://www.youtube.com/watch?v=7xy9u1OUq9s
И ещё, ИНОГДА, при плавном старте проскакивает мигание лампы. Иногда всё нормально. Иногда несколько миганий. Откуда берутся эти мигания не понятно. В видео, мигание на 6-ой секунде.
Нельзя всё знать, достаточно понимать.
Думаю это так ошибки приема команды от пульта влияют...ТСОП засвечивается мусором и прерывание возникает.
Я пока взял библиотечку от многоуважаемого ARV для работы с пультиком... Код уверенно распознает нажатие кнопок на пульте, но удержание не очень. Во время удержания мой пульт шлет команду полностью. теперь вот тоже думаю как удержание отрабатывать...
Я пока взял библиотечку от многоуважаемого ARV для работы с пультиком... Код уверенно распознает нажатие кнопок на пульте, но удержание не очень. Во время удержания мой пульт шлет команду полностью. теперь вот тоже думаю как удержание отрабатывать...
В программировании не силен, но смею предположить что не выполняются условия отсчета времени задержки включения, т.е. "плывет" начальное значение отсчета таймера (сбой привязки) или сбой таймера - вызванные прерываниями.mr_smit писал(а): Откуда берутся эти мигания не понятно.
Лучше умному тупить, чем тупому умничать
Пока победил это так:
Т.е. если прошло более 48 мс и от TSOPа ничего не пришло, то значит кнопку отпустили button_up = yes; и увеличение яркости в цикле while (button_up == no) прекращается.
Теперь регулируется плавно. Но заметил такую особенность: если нажать кнопку уменьшения яркости, а потом через 0,5-1 или 2-3 сек нажать кнопку увеличения яркости, то яркость продолжает уменьшаться
Подождал. Дальше как надо регулируется.
Достала эта не стабильность
((((
Код: Выделить всё
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_);
}
}
}
else if (cmd == 0b11000000) { // кнопка "Sleep" - уменьшение яркости
TCCR1B=0x02;
while (button_up == no) {
status--;
if (status < 1) {
status = 0; // чтобы не уйти в минус
PORTC.5 = 0; // полностью выключили
TCCR1B=0x00;
}
else {
OCR1A = nagruzka[status]; // уменьшаем яркость
delay_ms(delay_);
}
}
}
Теперь регулируется плавно. Но заметил такую особенность: если нажать кнопку уменьшения яркости, а потом через 0,5-1 или 2-3 сек нажать кнопку увеличения яркости, то яркость продолжает уменьшаться
Подождал. Дальше как надо регулируется.
Достала эта не стабильность
Нельзя всё знать, достаточно понимать.
Попытался синхронизироваться по импульсам от ДУ. Т.е. по приходу команды выполнять действие. Как раз разница между посылками вроде и должна дать задержку на плавность:
Нет эффекта. Так же ступенчато. Хоть об стену расшибись
Мой код то почти что рабочий. Думаю где то надо просто или прерывания отключать или ещё что. Но не хватает мозгов сообразить где.
как только люди яркость регулируют
Код: Выделить всё
...
if (b_cnt == 32) { //если приняли уже 4 байта
if ((cmd_1 + cmd_0) == 0xFF) { //проверили правильность приема команды
cmd = cmd_1;
if (cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
TCCR1B=0x02;
OCR1A = nagruzka[status];
status++;
if (status >= 98) {
TCCR1B=0x00;
status = 97;
PORTC.5 = 1; // полностью включили
}
}
Мой код то почти что рабочий. Думаю где то надо просто или прерывания отключать или ещё что. Но не хватает мозгов сообразить где.
как только люди яркость регулируют
Нельзя всё знать, достаточно понимать.
Не смотрел программу. Высший приоритет сделай у подпрограммы регулировки яркости и запихни ее в прерывания по переходу через ноль.
Лучше умному тупить, чем тупому умничать


