NEC protocol Microlab SOLO 6C

Отже в першій частині, чи то нульовій – вступній, ми розібрались із протоколом і данними, які відправляє пульт в акустику. Акустика доречі фірми Microlab, модель Solo 6C

Код писався в AVR Studio 6.1 і відлагоджувався на відладочній платі PinBoard 1.1, частково в Proteus ISIS. Мікроконтролер для відладки ATmega16, частота тактування 8 MHz.

 

 

 

 

Також для тестів і відладки нам знадобляться:

  • Інфра Червоний світлодіод, думаю підійде любий. Свій я брутально видер із ДУ від калорифера, пультом і так ніхто не користувався.
  • Осцилограф, або логічний аналізатор. Краще аналізатор-там детально видно часові періоди в пачці імпульсів.
  • Сам пристрій яким ми будемо керувати.
  • Ну і запастися терпінням і чашкою кави.

Якщо ви уважно читаєте мою писанину, то мали б замітити дивний перехід сюжетної лінії, від мого власного досвіду будування ДУ. До так ніби я розповідаю про побудову пристрою, який знабодився саме вам, для вашої задачі. Впринципі все так і є. Якщо вам знадобиться збирати власноруч свій пристрій дистанційного керування, то прийдеться повторяти всі ті самі кроки, що пройшов і я. Це був ліричний відступ, продовжимо далі сухими фактами.

Першим ділом, потрібно зібрати схему для відладки коду. Бажано це зробити на справжньому залізі і забути на деякий час про всякі там методи віртуальної відладки. Щось я їм не дуже довіряю.

Наголошую, що відлагоджував я свій код на реальному залізі, контролер ATmega16, частково код взятий і портований із ATmega8. Кінцевий пристрій планується на ATtiny45 (тому що вона в мене є і валяється без діла). Із останньою, код запрацював тільки в протеусі, в залізі тести тільки грядуть. Але про це в наступній статті. Як бачите, виходить досить універсальний код і вибір контролера не є тяжкою задачею.

Отже схема підключення ІЧ-діода може виглядати наступним чином:

Підсилювач ІЧ-діода

Це схема так званого включення ІЧ-діода через підсилювач, або підсилювач ІЧ-діода. Схема розрахована на напругу в 5 Вольт. Виходи мікроконтролера видають 5 Вольт, тому тут і стоять пара резисторів, щоб погасити надлишкову потужність. В фінальній схемі пристрою можна обійтись без резисторів, так як схема буде заживлена від 3 Вольтової батарейки. Навіщо так заморочуватись і складати таку схему? Просто при включенні ІЧ-діода на пряму до портів мікроконтролера, буде йти значна просадка напруги і діод не буде світити на повну потужність. В схемі можна використати любий малопотужний n-p-n транзистор. Впринципі можна обійтись і без цього всього і включити діод на пряму до мікроконтролера, але радіус дії, буде досить маленьким.

Для відладки в мікроконтролері використовується два виходи, PB0 і PB3. За генерування частоти буде відповідати Timer 0, запущений в режимі-CTC (Clear Timer on Compare). В ATmega16 – це порт PB3, по ньому буде генеруватись частота 36kHz, а по PB0 ми будемо генерувати затримки, із такою самою довжиною як використовується в протоколі NEC. В фінальній програмі ми відключимо взагалі порт PB0 і всі затримки і генерація несучої частоти буде виконувати порт PB3.

А зараз приведу робочий код для ATmega16. Також в кінці статті прикріплю проект для AVR Studio 6.1

#define F_CPU 8000000
 
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
 
#define IR_PORT 	PORTB                                  //Налаштування портів ІЧ-діда
#define IR_PIN 		PINB
#define IR_DDR 		DDRB
#define IR_HF_Line 	(1<<3)
#define IR_Line 	(1<<0)
 
#define LED_PORT 	PORTD                                   //Налаштування портів відладочного світлодіода
#define LED_PIN 	PIND
#define LED_DDR 	DDRD
#define LED_Line 	(1<<7)
 
#define Btn_PORT PORTC
#define Btn_PIN PINC
#define Btn_DDR DDRC
#define Btn_VOL_Plus    (1<<0)
#define Btn_VOL_Minus   (1<<1)
 
#define DEV		 128					//Назва девайса по протоколу NEC
#define VOL_Plus	 136					//Команди
#define VOL_Minus          8
 
//Об'являємо функції
void TransmitCmnd (char, char);
void TransmitByte (char);
void FreqOn  (void);
void FreqOff (void);
 
//Основна програма
int main (void)
{
Btn_DDR&=~(Btn_VOL_Plus)&~(Btn_VOL_Minus);		//Вхід на кнопку
Btn_PORT|= (Btn_VOL_Plus)|(Btn_VOL_Minus);		//Підтяжка кнопки відсутня, зовнішня підтяжка
 
IR_DDR |= (IR_Line | IR_HF_Line);
IR_PORT |= IR_Line;
 
LED_DDR |= LED_Line;
 
FreqOff();
 
while (1){
 
if (~Btn_PIN&(Btn_VOL_Plus))				//Button VOL+
{
while(Btn_PIN&(Btn_VOL_Plus)) _delay_ms(20);
_delay_ms(20);
TransmitCmnd(DEV, VOL_Plus);				
}
 
if (~Btn_PIN&(Btn_VOL_Minus))				//Button VOL-
{
while(Btn_PIN&(Btn_VOL_Minus)) _delay_ms(20);
_delay_ms(20);
TransmitCmnd(DEV, VOL_Minus);		
}
 
}
}
 
//Вивід команди по ІЧ-каналу
//device - Номер пристрою
//command - Номер команди
void TransmitCmnd (char device, char command)
{
LED_PORT |= LED_Line;				        //Увімкнути відладочний світлодіод
 
//стартовий біт
IR_PORT &= ~IR_Line;				        //Вимкнути прямий вихід
FreqOn ();						//Увімкнути частоту 36000Гц
_delay_us (9000);					//Чекаємо 9 мс
 
IR_PORT |= IR_Line;					//Увімкнути прямий вихід
FreqOff ();						//Вимкнути частоту 36000
_delay_us (4400);					//Чекаємо 4,4 мс
 
//передача команди
TransmitByte (device);				        //Пряма адреса пристрою
TransmitByte (~device);				        //Інвертована адреса пристрою
TransmitByte (command);				        //Пряма команда
TransmitByte (~command);			        //Інвертована команда
 
//завершаючий імпульс
IR_PORT &= ~IR_Line;				        //Вимкнути прямий вихід
FreqOn ();						//Увімкнути частоту 36000Гц
_delay_us (660);					//Чекаємо 0,66 мс
 
IR_PORT |= IR_Line;					//Увімкнути прямий вихід
FreqOff ();						//Вимкнути частоту 36000Гц
 
LED_PORT &= ~LED_Line;				        //Вимкнути відладочний світлодіод
}
 
//вивід данних по каналу IR
//byte - байт даних
void TransmitByte (char byte)
{
for (char i=0; i<8; i++){
 
IR_PORT &= ~IR_Line;			        //Вимкнути прямий вихід
FreqOn ();					//Увімкнути частоту 36000Гц
_delay_us (660);				//Чекаємо 0,66 мс
 
IR_PORT |= IR_Line;				//Увімкнути прямий вихід
FreqOff ();					//Вимкнути частоту 36000Гц
if (byte & 0x80)				//Чекаємо
_delay_us (1580);			        //Якщо біт = 1 то 1,58 мс
else
_delay_us (460);			        //Якщо біт = 0 то 0,46 мс
 
byte <<= 1;					//Здвигаємо біт
}
}
 
//генерація частоти 36000 Hz
void FreqOn (void)
{
TCCR0 = (1<<FOC2)					//принудительное изменение состояния вывода при совпадении
|(1<<CS00)|(0<<CS01)|(0<<CS02)		                //Тактування від генератора
|(1<<COM00)|(0<<COM01)				        //Стан виходу міняється на протилежне
|(0<<WGM00)|(1<<WGM01); 			        //Режим CTC (скидання при співпадінні)
 
TCNT0 = 0; 						//Обнуляємо регістр
OCR0 = 111; 					//При досягненні значення 111, в регістрі буде скидання і переключення ОС2
}
 
//вимкнення генерації 36000 Hz
void FreqOff (void)
{
TCCR0 = 0;						//Вимкнути генератор 36000 Hz
IR_PORT &= ~IR_HF_Line;				        //Вимкнути порт виходу частоти
}

Код я писав не зовсім сам, його основну частину я підглянув на форумі радіокотів. Приклад із частиною коду знайшов чисто випадково, в пошуках пояснень до самого протоколу. Так що тема досить не нова і заїзджена. Код є достатньо прокоментованим, щоб зараз не писати якихось пояснень. Основними функціями які тут використовуються для задання керуючого сигналу є TransmitCmnd, TransmitByte і генерація частоти FreqOn, FreqOff. Щоб це все перенести на якийсь інший мікроконтролер, потрібно лише поміняти імена регістрів таймера і підправити виходи портів.

Взагалі тут можна реалізувати не тільки протокол NEC, а й якийсь інший поширений в електроніці. Або взагалі придумати свій із блекджеком і сеньоритами.

На цьому, думаю, можна закінчити статтю. В наступній публікації розкажу про вже готовий пристрій, який я планую материлізувати найближчим часом. Прошу залишати коментарі до статті, буду радий відповісти на всі питання.

Файли до статті: IR_NEC_transmitter

Comments:

Написати відповідь

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

вимагається