Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил.)

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

alex2103 писал(а):Думаю это так ошибки приема команды от пульта влияют...ТСОП засвечивается мусором и прерывание возникает.
Я пока взял библиотечку от многоуважаемого ARV для работы с пультиком... Код уверенно распознает нажатие кнопок на пульте, но удержание не очень. Во время удержания мой пульт шлет команду полностью. теперь вот тоже думаю как удержание отрабатывать...

все нормально с моим кодом. определять удержание для одинаковых кодов надо в другом месте. я делаю, например, так: сравниваю новый код с предыдущим, если они одинаковы, то еще проверяю флажок автоповтора - если и флажок стоит, то приступаю к обработке принятого кода. если флажок не стоит - запускаю таймер, который этот флажок установит через 1 секунду, код при этом игнорирую. если коды не одинаковы, то останавливаю таймер, сбрасываю флажок, запоминаю код и приступаю к его обработке.
в этом случае получается такое дело:
- каждое нажатие вызывает реакцию немедленно
- если нажато и удерживается, то через 1 секунду задержки начинается быстрый автоповтор

точно такой же принцип надо использовать и при работе с кнопками, если требуется автоповтор.

mr_smit, сдается мне, что ваша проблема в бессистемном подходе к разработке: вы не разрабатываете программу, а латаете дырки. по стилю видно, что общего алгоритма работы вы не продумывли, а пишите "слету", а потом налепляете на написнное всякие примочки, чтобы оно хоть как-то работало. боюсь, что в таком коде никто не станет разбираться, чтобы вам помочь. да и сами вы вскоре (если не уже) будете путаться в нем... как говорил один сантехник "тут все прогнило, всю систему менять надо" :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

ARV писал(а):mr_smit, сдается мне, что ваша проблема в бессистемном подходе к разработке

А откуда этой системе взяться если я не профессиональный программист??? Контроллеры это хобби. Просто всеми силами пытаюсь разобраться.
ARV писал(а):да и сами вы вскоре (если не уже) будете путаться в нем...

Любую строчку могу объяснить. Но почему это в целом не работает мозгов не хватает к сожалению :(
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

да потому и не работает... я уже как-то говорил: в бессистемном коде и ошибки искать сложно. это ведь как на огороде: если у вас все по грядочкам, то вы и урожай соберете хороший, а когда все семена в кучу смешаны и высыпаны по ветру - расти-то оно вырастет, но надеяться на обильный урожай не стоит...

попробуйте просмотреть свой код критическим взглядом и устранить из него все, что покажется вам нелогичным, запутанным, лишним и т.д. - то есть "причешите код". иной раз это приходится делать не один раз. повторяющиеся куски с одинаковыми смысловыми действиями оформите в виде функций, разберитесь с глобальными переменными - часто их гораздо больше, чем необходимо... иногда даже расстановка табуляций позволяет увидеть, что есть не очень удачные куски!

если вам кажется, что из-за обилия функций код станет медленным - этого бояться не стоит. имеет смысл выделять в функцию даже однократный кусок кода, если это позволяет повысить наглядность кода. сравните это:

Код: Выделить всё

int main(void){
unsigned char key = 0;

   if(PINB != 0x255){
      if(PINB.1 = 0){
         key = 1;
      }
      if(PINB.2 = 0){
         key = 2;
      }
      if(PINB.3 = 0){
         key = 3;
      }
   }

   while(1){
      switch(key){
      case 1 : // что-то там
      case 2:
      case 3:
      }
   }
}
и вот это:

Код: Выделить всё

static unsigned char get_keycode(void){
   unsigned char key = 0;
   if(PINB != 0x255){
      if(PINB.1 = 0){
         key = 1;
      }
      if(PINB.2 = 0){
         key = 2;
      }
      if(PINB.3 = 0){
         key = 3;
      }
   }
   return key;
}

int main(void){
   while(1){
      switch(get_keycode()){
         case 1 : // что-то там
         case 2:
         case 3:
      }
   }
}
вроде бы одно и то же, а локальной переменной нет, тело функции main стало прозрачным и понятным, т.к. имя функции get_keycode говорит само за себя. кстати, если я не ошибаюсь, после компиляции второй вариант будет и памяти меньше занимать, не смотря на наличие как бы "лишней" функции. и отлаживать такой код проще, и ошибки искать тоже: если оказалось, что что-то не так с кнопками, то вы прямиком лезете в функцию и разбираетесь с нею и только нею, при этом вы уверены, что нигде и ничто кроме нее не будет затронуто, т.е. нарушено. если размер исходника у вас такой, что на одном "экране" не умещается - вам просто необходимо оптимизировать его! если каждая функция (включая main) умещается от начала до конца на экране без прокрутки - это, можно сказать, идеал, к которому надо стремиться :))) но не доводя все до абсурда, конечно.

в общем, займитесь "красотой" и элегантностью кода - вам точно полегчает! может, не сразу (все-таки, и в этом нужен опыт), но уверяю вас: эффект будет!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Функции я и так сделал где посчитал нужным:

Код: Выделить всё

soft_on ();                      
soft_off ();


А есть у кого нибудь код реального диммера? Как там сделано? Ни одного толкового проекта ПОНЯТНОГО не нашел в инете. Все только жизни учат.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Убавил задержку в прерывании. Было 200 мкс, поставил 75 мкс. Стало плавнее...

Код: Выделить всё

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
  {
  PORTC.5 = 1;    // открыли симистор
  delay_us(75);  // импульс 75 мкс
  PORTC.5 = 0;   // вернулись в режим ожидания
  }


Как подать импульс открытия не используя delay_us(75) я не знаю. Понимаю что в прерывании нельзя использовать задержку. Но а как без неё??????????

Вот, смотрите как всё работает: http://www.youtube.com/watch?v=gSkNSZsmZ8Q
Последняя редакция кода в приложении.

Заметил что:

(cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
(cmd == 0b11011000) { // кнопка "TV" - вкл/выкл диммера

отличаются только 1 битом. Может поэтому иногда при нажатии на увеличение лампа загорается полностью???? Не правильное принятие команды????
dimmer.c
(11.36 КБ) 334 скачивания
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

mr_smit, ну вот поглядите на мой код диммера на тини13 (WinAVR)... я ведь вам советовал взять за основу код из моей статьи - вы проигнорировали... ну кто ж вам теперь виноват?

Код: Выделить всё

/*
 * main.c
 *
 *  Created on: 05.09.2010
 *      Author: Pоман
 */
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <avr_helper.h>
#include "dimmer.h"
#include "rc5.h"

typedef struct{
   uint32_t c1, c2;
}code_t;

#define LOG0_100us         10
#define LOG1_100us         20
#define END_100us         200

#define is_1()            (PINB & _BV(PB0))
#define is_0()            (!is_1())

#define do_nothing()      wdt_reset();

#define MAX_BIT_CNT         32

static uint8_t delta_t(void){
   uint8_t i = END_100us;

   while(is_0()) do_nothing();               // ждем появления 1 в линии
   for( ; i; i--){                        // ждем не более 25,5 мс
      _delay_us(100);                     // кусочками по 100 мкс
      do_nothing();                     // при этом сбрасываем WDT
      if(is_0()) break;                  // как только появился в линии 0 - прекращаем ждать
   }
   return END_100us - i;                  // возвращаем длительность единичного интервала
}


/// счетчик для регулирования фазы
volatile uint8_t    COUNTER;
/// счетчик таймаута перед автоповтором команды пульта
volatile uint8_t    timeout;
/// текущая фаза отпирания симистора
volatile noinit uint8_t   out_phase;
/// заданная фаза отпирания симистора
volatile noinit uint8_t   sel_phase;
/// флажок включения нагрузки
volatile noinit uint8_t   on;
/// значение фазы в момент выключения (запоминается для последующего включения)
static uint8_t   noinit off_phase;

/*
 * РАСПРЕДЕЛЕНИЕ EEPROM
 */
/// признак "чистой" EEPROM
EEMEM uint8_t first;
/// массив запомненных команд
EEMEM code_t cmd[TOTAL_CMD];

/** Прерывание таймера по совпадению канала А.
 * Таймер настроен так, что прерывание возникает 200 раз в полупериод сети.
 * Обработчик реализует виртуальные регистры совпадения для фазового регулирования.
 */
ISR(TIM0_COMPA_vect){
   COUNTER++;
   // виртуальный регистр совпадения для включения импульса
   if(COUNTER == out_phase){
      do_comp_A();
   }
   // виртуальный регистр совпадения для выключения импульса
   if(COUNTER == (out_phase + PULSE_LEN)){
      do_comp_B();
   }
}

/** Прерывание по изменению состояния синхро-пина.
 * Возникает по фронту и спаду синхроимпульса, т.е. 100 раз в секунду
 * Реализует синхронизацию с сетью.
 */
ISR(PCINT0_vect){
   COUNTER = 0;                        // обнуляем счетчик таймера
   OUTPORT   |= OUT_PIN;                     // выключаем на всякий случай выход
   if(on){
      // если включено - плавно приближаем текущую фазу к заданной
      if(sel_phase > out_phase){
         out_phase++;
      } else if(sel_phase < out_phase){
         out_phase--;
      }
   }
   if(timeout) timeout--;                  // отсчитываем таймаут
}

/** Индикатор принятого и обработанного кода.
 *
 */
static void indicate(void){
   PINB |= IND_PIN;
   _delay_ms(20);
   PINB |= IND_PIN;
}

/** Прием кода с пульта
 * Функция ожидает прихода кода с пульта управления.
 * @return принятый код.
 * \note До тех пор, пока код не принят, функция не завершается.
 */
static uint32_t get_ir(void){
   uint32_t code = 0;
   static uint32_t oldcode = 0;

   while(is_1()) do_nothing();               // ждем 0 в линии - синхронизация с началом импульса

   for(uint8_t i = MAX_BIT_CNT; i; i--){      // ввод не более заданного кол-ва битов
      code <<= 1;                        // готовим очередное место бита
      uint16_t delta = delta_t();            // измеряем длительность 1 в линии
      if((delta >= END_100us)) break;         // если слишком долго - конец приема
      if(delta > LOG0_100us) code |= 1;      // если достаточно для приема 1 - заносим в бит 1
   }
   if((code > 0) && (code < 5)) return oldcode;
   oldcode = code;
   return code;                        // возвращаем, что накопилось
}

/** Обучение команде.
 * Функция ожидает команду с пульта и сохраняет ее в EEPROM по указанному адресу.
 * @param adr адрес ячейки в EEPROM для сохранения принятого кода
 */
static void write_ee(const uint16_t *adr){
   code_t cc;
   uint32_t t1;
   // задержка перед приемом кода, чтобы пользователь успел подготовиться
   _delay_ms(500);
   // ожидание корректного кода
   /* Примечание.
    * При испытаниях выяснилось, что имеющийся в наличии TSOP с завидным постоянством спустя 1,5 секунды
    * после приема кода с пульта выдавал на выход импульс низкого уровня с длительностью, соизмеримой с
    * длиной всего RC5-кода, что естественно воспринималось как нормальный прием кода.
    * В результате при "обучении" устройства происходило запоминание этого нереального сигнала, что
    * делало дальнейшую работу невозможной.
    * Разбираться с причинами было недосуг, поэтому в программу был введен контроль принятого кода на
    * корректность: если приняты все единицы (на выходе TSOP код инвертирован) - это недопустимый код,
    * который отбрасывается.
    */
   do{
      t1 = get_ir();         // вводим код
   } while ((t1 != get_ir()) || !t1);                        // и так до тех пор, пока не примется корректный код
   cc.c1 = t1;
   indicate();
   _delay_ms(500);
   do{
      t1 = get_ir();         // вводим код
   } while ((t1 != get_ir()) || !t1);                        // и так до тех пор, пока не примется корректный код
   cc.c2 = t1;

   // сохранение кода в EEPROM
   eeprom_write_block(&cc, adr, sizeof(code_t));
   // индикация приема
   indicate();
}

/** Ожидание команды и поиск ее среди запомненных.
 * Функция ожидает прихода команды с пульта, затем ищет ее среди ранее запомненных кодов,
 * и возвращает результат этого поиска.
 * @return номер запомненной команды
 * \note Функция не возвращает управление до тех пор, пока не будет принята одна из запомненных
 * ранее команд. Кроме того, в зависимости от состояния TOGGLE-бита в принятой команде,
 * функция возвращает либо номер команды в массиве #cmd[], либо этот номер, увеличенный на TOTAL_CMD.
 * Это сделано для того, чтобы можно было отличить долгое удержание кнопки пульта от частого нажимания.
 */
static uint8_t wait_and_search_ir(void){
   uint8_t i;
   uint32_t code;
   while(1){
      code = get_ir();
      i = search_ir(code);
      if(i < (TOTAL_CMD * 2))   return i;
   }
}

/** Поиск команды в массиве "обучения"
 *
 * @param code принятая команда
 * @return номер найденной команды в массиве или заведомо недопустимый номер, если такой команды
 * в массиве нет.
 * \note Возвращаемое значение формируется по правилам, определенным для #wait_and_search_ir()
 */
static uint8_t search_ir(uint32_t code){
   for(uint8_t i = 0; i < TOTAL_CMD; i++){
      if((eeprom_read_dword((void*)&cmd[i].c1) == code) || (eeprom_read_dword((void*)&cmd[i].c2) == code)){
         return i;
      }
   }
   return TOTAL_CMD * 2;
}

AUTOINIT(){
   if(MCUSR & _BV(PORF)){
      // если сброс произошел по включению питания - все переменные инициализируются
      out_phase = PHASE_OFF;
      sel_phase = PHASE_OFF;
      on = 0;
      off_phase = MIN_P;
   }
}

MAIN(){
   uint8_t code, oldcode;

   // настройка периферии
   wdt_enable(WDTO_1S);                  // сторожа разрешим для страховки
   ACSR   = _BV(ACD);                     // компаратор отключается для экономии энергии
   DDRB   = OUT_PIN | IND_PIN;            // выходные пины порта настраиваются на выввд
   PORTB   = OUT_PIN | IND_PIN;
   MCUCR   = _BV(ISC01);                  // запрос прерывания по падающему фронту
   TCCR0A   = _BV(WGM01);                  // режим СТС
   OCR0A   = CTC;                        // порог сброса
   TCCR0B    = TIMER_CLK_DIV(TMR_DIV);         // делитель таймера
   TIMSK0    = _BV(OCIE0A);                  // прерывания таймера
   PCMSK   = _BV(PCINT0);                  // 0-й пин используется для синхронизации с сетью
   GIMSK   = _BV(PCIE);                  // разрешаем прерывание по смене уровня пина

   // временно
#if defined(__AVR_ATtiny2313__)
   DDRD = _BV(PD5);
   PORTD = _BV(PD5) | _BV(PD2);
#endif
   sei();

   if((MCUSR & _BV(EXTRF)) || eeprom_read_byte(&first)){
      // сброс или первое включение - режим "обучения"
      on = 1;
      sel_phase = MAX_P - 30;
      for(uint8_t i=0; i<TOTAL_CMD; i++){
         write_ee((void*)&cmd[i]);         // запоминаем очередную команду
         sel_phase -= 30;               // изменяем яркость нагрузки
         indicate();                     // и индицируем успешное исполнение команды
      }
      // после запоминания всех команд выключаем нагрузку
      sel_phase = PHASE_OFF;
      on = 0;
      // и устанавливаем признак ОБУЧЕННОСТИ
      eeprom_write_byte(&first,0);
      indicate();
   }
   // регистр состояния микроконтроллера обнуляется, чтобы можно было определять вид сброса в будущем
   MCUSR = 0;

   while(1){
      // ждем команды
      code = wait_and_search_ir();
      // если принята команда не такая, как в прошлый раз,
      if((oldcode != code)){
         // то установим таймаут, чтобы автоповтор не начался сразу же
         timeout = 200;
         // и запомним принятую команду на будущее
         oldcode = code;
      } else
         // если же новая команда совпадает со старой, то игнорируем ее пока не истечет таймаут
         if(timeout) continue;

      // обработка принятой команды (каждая команда может быть в 2-х вариантах)
      switch(code){
      case CMD_ONOFF:
         // включить или выключить нагрузку
         if(on){                        // если включено, то выключаем,
            off_phase = sel_phase;         // запоминая текущий уровень яркости,
         m1:
            sel_phase = PHASE_OFF;
            out_phase = PHASE_OFF;
            on = 0;
         } else {                     // а если выключено - включаем,
         m2:
            sel_phase = off_phase;         // устанавливая уровень яркости, который запоминали при выключении
            on = 1;
         }
         indicate();                     // показываем, что принята команда
         timeout = 200;
         break;
      case CMD_HI:
         // увеличение уркости
         if(!on) goto m2;               // если не включено - просто включаем
         // изменение
         if(sel_phase > PHASE_STEP){         // пока не достигнута максимальная яркость
            sel_phase -= PHASE_STEP;      // увеличиваем ее
            indicate();                  // и показываем, что команда обработана
         }
         break;
      case CMD_LO:
         // уменьшение яркости
         if(sel_phase < PHASE_OFF){         // пока не достигнут минимум яркости
            sel_phase += PHASE_STEP;      // уменьшаем ее
            indicate();                  // и показываем, что команда обработана
         } else {                     // а когда минимум достигнут
            off_phase = PHASE_STEP;         // полностью выключаем нагрузку
            goto m1;
         }
      }
   }
}

код гарантированно рабочий, но не пытайтесь его компилировать - он не полный: хидеры свои я пока не показываю (из вредности). просто поглядите, как делал я и попробуйте сделать свою программу по этому принципу.

пояснения: это код диммера с автообучением командам пульта. при запуске с чистой EEPROM диммер ожидает нажатия кнопок для обучения: КНОПКА ВКЛ-ВЫКЛ, КНОПКА МЕНЬШЕ ЯРКОСТЬ, КНОПКА БОЛЬШЕ ЯРКОСТЬ. прием кода кнопки сопровождается морганием светодиода. каждую кнопку надо нажимать 2 раза: нажать и отпустить после мигания светодиода, затем нажать второй раз и отпустить после мигания - и так с каждой кнопкой. во время обучения диммер чуть-чуть подсвечивает лампу (15Вт еле-еле светится спираль). после обучения девайс готов к исполнению команд. при подаче питания всегда выключен. кнопка вкл-выкл всегда включает на тот уровень яркости, что был при выключении. обучаться может почти любым пультам - я настраивал на кнопки управления телетекстом, т.к. телетекста у нас нет в кабельном ТВ. в общем, думайте :))) желаю удачи!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Я на это смотрю:

Код: Выделить всё

typedef struct{
   uint32_t c1, c2;
}code_t;

И понимаю что вы просто издеваетесь. Я не понимаю что в этих 3-х строчках написано. Слишком сложно для меня.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

mr_smit писал(а):Я на это смотрю:

Код: Выделить всё

typedef struct{
   uint32_t c1, c2;
}code_t;

И понимаю что дальше можно не смотреть. Я не понимаю что в этих 3-х строчках написано. Слишком сложно для меня.
ну вот, опять вам не так... экий вы, однако, капризный, батенька! :) это обычное определение структуры с двумя полями с1 и с2, каждое из которых есть 32-битное беззнаковое число.

смысл вот в чем: девайс умеет обучаться кодам 3-х кнопок. так как некоторые пульты (в частности, настоящие RC5) при каждом нажатии изменяют один из битов кода, то получается, что каждой кнопке соответствует (может соответствовать) как бы 2 разных кода - вот я поэтому 2 раза ловлю коды кнопки и сохраняю их в эту структуру - когда затем при приеме совпадет хотя бы один из двух кодов, я считаю, что принят код нужной кнопки.

вы все-таки постарайтесь разобраться. сложно я написал или нет, но даже по комментариям вы должны понять ЛОГИКУ процессов! как регулировать фазу, длительность импульса на симистор и задержки на ЕДИНСТВЕННОМ 8-битном таймере, как принимать коды БЕЗ ПРЕРЫВАНИЙ, как анализировать коды и отбрасывать неверные... поймете логику - сможете сделать по-своему, не так сложно, как я :)
Последний раз редактировалось ARV Сб ноя 27, 2010 19:07:11, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Код: Выделить всё

// виртуальный регистр совпадения для включения импульса


ахренеть
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

mr_smit писал(а):И понимаю что вы просто издеваетесь.
а, так вот как вы заговорили?!
ок, не буду издеваться. спасибо за внимание.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Уважаемый ARV, вы написали уйму текста (помимо кода) который к теме никак не относится. И никак мне не помог. Это раз. Во-вторых вы пытаетесь объяснить мне свой код, я пытаюсь объяснить вам свой. Оба друг друга не понимаем. Поэтому продолжать диалог и так нет смысла, а не потому что я как то там заговорил.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

я все понял. вы считаете, что если кто-то головой пытается пробить стену, то помочь ему можно только одним способом - став рядом и начав биться своей башкой. а я считаю, что в данном случае помочь - это указать на открытую дверь рядом.

продолжайте биться, я больше не стану пытаться вас вразумить. успехов вам!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Вы вот тоже поймите, что как человек слабо разбирающийся в программировании может уловить принцип в таком сложно написанном коде. Я так и не понял где вы в своём коде фиксируете что кнопка удерживается????

В данном случае это не указать на дверь, а подогнать бульдозер и сказать: "Разберешься с управлением, потом сможешь любые стены сносить". Но надо хотя бы пару рычагов показать газ/тормоз. А уж как ковшом работать методом тыка дойти. А вы вообще ничего не объяснили. Только и говорите: "смотри мой код, там всё понятно". И объяснили как ваш девайс работает:
ARV писал(а):девайс умеет обучаться кодам 3-х кнопок...
Нельзя всё знать, достаточно понимать.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение ARV »

mr_smit писал(а):Я так и не понял где вы в своём коде фиксируете что кнопка удерживается????
если вы умеете читать, то должны были прочесть это:

Код: Выделить всё

      // ждем команды
      code = wait_and_search_ir();
      // если принята команда не такая, как в прошлый раз,
      if((oldcode != code)){
         // то установим таймаут, чтобы автоповтор не начался сразу же
         timeout = 200;
         // и запомним принятую команду на будущее
         oldcode = code;
      } else
         // если же новая команда совпадает со старой, то игнорируем ее пока не истечет таймаут
         if(timeout) continue;
разве не понятно из комментариев и самой программы, что тут идет получение кода кнопки и реализация алгоритма "удержания"? автоповтор - это ни о чем вам не говорит? более того, в начале этой страницы я уже рассказывал про то, как реагировать на удержание. вы читали? в чем сложность кода моего? лично для меня ваш код выглядит куда более сложным и запутанным!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Код не мой, а пользователя Aheir из его статьи: "Некоторые протоколы ИК пультов" которая есть на этом сайте.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
alex2103
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение alex2103 »

mr_smit, ARV истину глаголит :) Я вот тоже алгоритм где-то так представлял как в коде ARV ...ну за исключением всяких фенечек типа готового автоповтора, обучения и т.п.

Управление симистором еще вчера сделал один в один как сегодня у ARV увидел. Правда прерывания 100 раз за полупериод. В общем есть чему поучится разбирая приведенный код. :idea:
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Да не могу я код ARV понять, думаете не пытался что ли. Для меня он не логичен.
Другого кода диммера ни о кого нет? Мне бы пример ещё один.

Пока избавился от delay в прерывании таким образом:

Код: Выделить всё

...
OCR1A = nagruzka[status];
OCR1B = nagruzka[status]+200;        // импульс 100 мкс
...
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
  {
  PORTC.5 = 1;    // открыли симистор
  }
 
// Timer 1 output compare B interrupt service routine
interrupt [TIM1_COMPB] void timer1_compb_isr(void)
{
PORTC.5 = 0;    // вернулись в режим ожидания
}

По совпадению А включили, по совпадению В выключили (через 100 мкс). На текущей яркости проблем нет. Стабильно горит на заданной яркости. Проблемы именно при регулировании. Иногда, когда полностью выключено, нажатие кнопки увеличения яркости приводит к плавному включению на 100%. Как будто команды путаются...

(cmd == 0b11111000) { // кнопка "Display" - увеличение яркости
(cmd == 0b11011000) { // кнопка "TV" - вкл/выкл диммера
Нельзя всё знать, достаточно понимать.
Аватара пользователя
olegators68
Поставщик валерьянки для Кота
Сообщения: 2253
Зарегистрирован: Пн ноя 01, 2010 12:19:31
Откуда: Серпухов

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение olegators68 »

Ув. mr_smit в программировании я дуб, но собрал диммер отсюда:
http://progcode.narod.ru/project/power_reg.html, работает хорошо, но сначала у меня и без сигнала открывалась МОСька (МОС3022 400 вольтовая),как динистор работала, по причине отсутствия других, пришлось поставить 2-е, в послед, может и у вас вся байда от глючной МОСьки?
Вот блин, опять в галерее картину малевича вверх ногами повесили.
Аватара пользователя
mr_smit
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн мар 23, 2009 09:25:58
Откуда: Самара

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение mr_smit »

Вот он корень зла!!!!!!!!!!!!!

Код: Выделить всё

if ((cmd_1 + cmd_0) == 0xFF) {           //проверили правильность приема команды             
  cmd = cmd_1;
  b_cnt = 0;                             //обнулили счетчик битов
  start_cond = 0;                        //сбросили стартовое условие


Надо добавить:
b_cnt = 0;
start_cond = 0;


Теперь всё нормально!!! А то b_cnt так и считал дальше 33,34,35... И новая команда не принималась пока start_cond в ноль не сбросится.
Нельзя всё знать, достаточно понимать.
Аватара пользователя
alex2103
Прорезались зубы
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье
Контактная информация:

Re: Диммер, чертовщина на выходе MOC (имеется 2-х кан. осцил

Сообщение alex2103 »

mr_smit, на твоей схемке из протеуса есть LS020. Это просто рисунок или реально работающая модель? Тоже хочу побаловаться с этим экранчиком да курочить телефон пока жалко :))
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»