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

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

Сообщение ARV »

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

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

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

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

Сообщение mr_smit »

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

Сообщение 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) умещается от начала до конца на экране без прокрутки - это, можно сказать, идеал, к которому надо стремиться :))) но не доводя все до абсурда, конечно.

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

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

Сообщение mr_smit »

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

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

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

Сообщение 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
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18696
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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Вт еле-еле светится спираль). после обучения девайс готов к исполнению команд. при подаче питания всегда выключен. кнопка вкл-выкл всегда включает на тот уровень яркости, что был при выключении. обучаться может почти любым пультам - я настраивал на кнопки управления телетекстом, т.к. телетекста у нас нет в кабельном ТВ. в общем, думайте :))) желаю удачи!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

Сообщение mr_smit »

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

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

typedef struct{
   uint32_t c1, c2;
}code_t;
И понимаю что вы просто издеваетесь. Я не понимаю что в этих 3-х строчках написано. Слишком сложно для меня.
Нельзя всё знать, достаточно понимать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18696
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

Сообщение mr_smit »

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

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

Сообщение ARV »

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

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

Сообщение mr_smit »

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

Сообщение ARV »

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

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

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

Сообщение mr_smit »

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

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

Сообщение ARV »

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

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

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

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

Сообщение mr_smit »

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

Сообщение alex2103 »

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

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

Сообщение 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" - вкл/выкл диммера
Нельзя всё знать, достаточно понимать.
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2253
Зарегистрирован: Пн ноя 01, 2010 12:19:31
Откуда: Серпухов

Сообщение olegators68 »

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

Сообщение 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 в ноль не сбросится.
Нельзя всё знать, достаточно понимать.
Прорезались зубы
Аватара пользователя
Сообщения: 219
Зарегистрирован: Вт сен 18, 2007 16:41:16
Откуда: Украина, г. Запорожье

Сообщение alex2103 »

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

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