Контролер люстри

  • Час 2-10-2015, 10:19
  • Автор admin
  • Коментарів 0 Комент.
  • Силка url

Дана схема не претендує на яку або новизну і я насмілюся представити на ваш суд схему контролера або блоку управління люстрою з шістьма лампами. Цей пристрій призначений для управління шістьма лампами будь-якого типу. Традиційно схеми такого типу виконувалися з використанням тиристорів або сімісторов, але з появою малогабаритних люмінесцентних ламп (енергозберігаючих) такі схеми стали не придатні. У даній схемі для управління використовуються електромеханічні реле, які управляються напругою 12в за допомогою ключів Т1..Т6, якими в свою чергу управляє процесор АТ89С2051-24PI. Дещо дивний, декому може здатися архаїчний вибір процесора з ядром MCS-51 був обумовлений його наявністю і досить низькою ціною, до того ж для початку освоєння мікроконтролерів він на мій погляд більш підходить ніж AVR контролери, так як він набагато простіше. Тактирование контролера виробляється з використанням вбудованого генератора із зовнішнім кварцом на частоту 8,0 МГц.

Контролер люстри

Для управління контролером використовується стандартний пульт від телевізорів Горизонт 5го покоління з протоколом RC5. На приклад такий як на малюнку нижче. Там же зазначено коди даних переданих пультом.

Контролер люстри

Для прийому сигналів пульта використовується будь-який доступний ІК приймач на частоту 36 або 38кгц. Світлодіод призначений для індикації прийому сигналів пульта керування. Харчується схема від лінійного блоку живлення складається з трансформатора, діодів, двох фільтруючих конденсаторів і мікросхеми стабілізатора. Напруга 12в використовується для живлення реле, 5в для живлення решти схеми. Вимикачі S1 і S2 це вимикачі люстри встановлені на стіні. В даному випадку люстра була підключена з використанням двох вимикачів, що включають кожен свою секцію ламп, після модернізації люстри шляхом установки описуваного контролера логіка роботи вимикачів змінилася і люстра може управлятися тільки ними.

Логіка роботи приладу проста, при включенні обох вимикачів люстра включається, контролер не виконує ні яких дій і чекає команди з пульта, все реле знеструмлені. При надходженні команди з пульта контролер виконує її. Передбачені наступні команди: кнопки 1..6 вимикають відповідну їм лампу, кнопка 9 включає всі лампи, кнопки VBSCT +/- вимикають і включають лампи по одній (зменшують і збільшують світло), кнопка з кодом 38 вимикає всі лампи по черзі (як у кінотеатрі ), кнопка М демонструє біжить вогник, а потім повертає люстру в початковий стан, кнопки Р +/- дозволяють "обертати" джерело світла (досить корисна функція).

Контролером управляє програма написана з використанням середовища Keil uVision2 на мові С.

Текст програми:

//***************************************************************************************************** // // Lamp controller // CPU - AT89C2051 // Clock 8.000 MHz // Six lamp controller. IR control RC-5 // Autor Panda okt 2011 // //****************************************************************************************************** #include #define Lamp_A P1_7 #define Lamp_B P1_6 #define Lamp_C P1_5 #define Lamp_D P1_4 #define Lamp_E P1_3 #define Lamp_F P1_2 #define IR P3_2 // IR Port #define LED P3_4 // LED #define LOW 16 // VBSCT - button #define HI 17 // VBSCT + button + - button is swop. #define SLOW_OFF 38 // Timer off button #define RUN_LIGHT 41 // M button run light. #define SHIFT_R 32 // P + button #define SHIFT_L 33 // P- button #define ORDER 59 // SL button #define ON 0 #define OFF 1 unsigned char _cmd, temp, cnt, MIRROR; unsigned int _addr; // ************************************************ ********************************** // External Interrupt 0 service routine receive command from IR remote control unit // ************************************************** ******************************** void ext_int0_isr (void) interrupt 0 {unsigned char ppp, pin; unsigned int _tmp, tout; EA = 0; // ALL interrupt disable _tmp = 1; LED = ON; for (ppp = 1; ppplt; 14; ppp ++) {for (tout = 100; tout gt; 0; tout--); pin = IR; for (tout = 100; tout gt; 0; tout--) if (pin! = IR) break; if (tout == 0) {EA = 1; // Timeout IE0 = 0; // Clear external interrupt flag LED = 1; return;}; _tmp = _tmp lt; lt; 1; if (! IR) _tmp ++; }; _cmd = _tmp & 0x003F; _addr = _tmp & 0xFFC0; _addr = _addr gt; gt; 6; IE0 = 0; // Clear external interrupt flag EA = 1; LED = OFF; } void main (void) {EA = 1; EX0 = 1; IT0 = 1; // External interrupt 0 activated on falling age LED = 1; // Off led IR = 1; P1 = 0x00; // All lamp on MIRROR = 0x00; LED = ON; _addr = 50000; while (_addr) _addr--; LED = OFF; while (1) {if (_cmd == 1) MIRROR; if (_cmd == 2) MIRROR; if (_cmd == 3) = OFFlt; lt; 5 ;; if (_cmd == 4) MIRROR; if (_cmd == 5) MIRROR; if (_cmd == 6) = OFFlt; lt; 2 ;; if (_cmd == 9) {P1 = 0x00; // All lamp on MIRROR = 0x00;}; if (_cmd == LOW) {temp = MIRROR; for (cnt = 2; cnt lt; = 7; cnt ++) {temp &= (0xFE lt; lt; cnt); if (MIRROR gt; temp) break;}; if (cnt lt; 8) {P1 = temp; MIRROR = temp;}; }; if (_cmd == HI) {temp = MIRROR; for (cnt = 2; cnt lt; = 7; cnt ++) break ;; if (cnt lt; 8) {P1 = temp; MIRROR = temp;}; }; if (_cmd == SLOW_OFF) {for (cnt = 2; cnt lt; = 7; cnt ++) = (1 lt; lt; cnt) ;; }; if (_cmd == SHIFT_R) if ((temp & 0x02) gt; 0); if (_cmd == SHIFT_L) temp; if (_cmd == RUN_LIGHT) {for (temp = 2; temp lt; = 7; temp ++) {P1 = ~ (1 lt; lt; temp); _addr = 50000; while (_addr) _addr--;}; P1 = MIRROR; }; _cmd = 0; }; }

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

Протокол RC-5іспользуемий в багатьох системах управління теле-відео та іншою апаратурою досить докладно описаний тут. Коротко опишу: посилка складається з 14 біт тривалістю 1.778мс кожен і містить два стартових біта які завжди рівні 1, далі йде критичний біт, який змінює свій стан при кожному натисканні клавіші. У простих проектах як цей, його абсолютно не обов'язково обробляти, потім 5 біт адреси і 6 біт даних, потім слідує пауза тривалістю 89мс. Для передачі даних використовується так званий манчестерський код, ще таку кодування називають біфазної. При такому способі передачі даних логічна 1 кодується як перепад сигналу з високого на низький рівень (негативний або задній фронт імпульсу), і логічний 0 кодується перепадом сигналу з низького на високий рівень (позитивний або передній фронт імпульсу). Зміна станів проводиться в середині періоду. Виглядає посилка як показано нижче:

Контролер люстри

Таку посилку можна декодувати кількома способами, найпростіший з яких після прийому першого імпульсу почекати приблизно три чверті періоду - це 1200-1300 мкс, потім протягом часу, що залишився відслідковувати зміну рівня сигналу. Якщо протягом приблизно 700мкс не відбулося зміни сигналу, то прийом пакета переривається і очікуємо наступний. Якщо зміна відбулася, то фіксуємо 0 або 1 (в залежності від стану лінії) і цикл повторюємо ще 13 разів.

for (ppp = 1; ppplt; 14; ppp ++) {for (tout = 100; tout gt; 0; tout--); // Очікування 1200мкс pin = IR; for (tout = 100; tout gt; 0; tout--) // Очікування 700-1200мкс, початкове значення tout можна зменшити (для тих кого if (pin! = IR) break; // налякали однакові значення ініціалізіціі tout) if (tout == 0) {EA = 1; // Timeout IE0 = 0; // Clear external interrupt flag LED = 1; return;}; _tmp = _tmp lt; lt; 1; if (! IR) _tmp ++; };

Тут ррр - лічильник імпульсів, tout - лічильник часу очікування приходу імпульсу, pin - мінлива в якій зберігається стан лінії до зміни. У змінну _tmp записуємо прийняту посилку. Щоразу після прийому чергового біта дані в _tmp зсуваються вліво і у випадку коли прийнята лог.1 до неї додається одиниця.

Прийом сигналів ІК пульта здійснюється в процедурі обробки зовнішнього переривання INT0,

// ************************************************ ********************************** // External Interrupt 0 service routine receive command from IR remote control unit // ************************************************** ******************************** void ext_int0_isr (void) interrupt 0

що позбавляє від необхідності постійно опитувати порт в очікуванні сигналу.
В разі успішного прийняття команди, її код записується в глобальну змінну _cmd,

_cmd = _tmp & 0x003F; _addr = _tmp & 0xFFC0; _addr = _addr gt; gt; 6;

А адресу в змінну _addr. Ця змінна надалі не використовується, і поділ пультів за адресою не проводиться, але це досить легко додати. Використовувані пульти працювали обидва на 0м каналі, з цього необхідності їх ділити не було. Подальша обробка команди, виробляється в основному тілі циклу програми:

while (1) {if (_cmd == 1) Lamp_A = OFF ;; if (_cmd == 2) = OFFlt; lt; 6 ;; if (_cmd == 3) = OFFlt; lt; 5 ;; ... ... ... P1 = temp; MIRROR = temp;}; if (_cmd == RUN_LIGHT) {for (temp = 2; temp lt; = 7; temp ++) {P1 = ~ (1 lt; lt; temp); _addr = 50000; while (_addr) _addr--;}; P1 = MIRROR; }; _cmd = 0; };

Після закінчення обробки команди, її код обнуляється.
Ще кілька особливостей програмування з якими стикаються початківці. У програмі є змінна MIRROR, для чого вона? У контролерах серії АТ89СХХХХ звернення до портам введення виведення проводиться за допомогою одного регістра, але запис і читання з порту виробляються в різних регістрах всередині контролера. Тобто коли ви записуєте дані в порт P1 = 0xff; всередині контролера запис проводиться в один регістр не доступні для користувача, при читанні порту aa = P1; читання виробляється з іншого регістра і фактично порт налаштовується на читання даних з ніжок контролера. Таким чином записавши в порт будь-яке число скажімо 0х05, а потім прочитавши стан порту ви отримаєте зовсім інше число. (P1 = 0x05)! = (Aa = P1) a aa! = 0x05; Ця обставина потрібно враховувати при розробці програм.

Хотілося б ще дати одну пораду тепер уже по роботі з середовищем програмування Keil_uVision2. Для вирішили повторити проект, а може бути зробити що то своє з використання ІК управління захочеться адаптувати програму для роботи з іншим кварцовим резонатором. Для цього достатньо буде змінити параметри всього двох циклів програми:

for (ppp = 1; ppplt; 14; ppp ++) {for (tout = 100; tout gt; 0; tout--); // Очікування ~ 1200мкс pin = IR; for (tout = 100; tout gt; 0; tout--) // Очікування ~ 700мкс-1200мкс if (pin! = IR) break; if (tout == 0) {EA = 1; // Timeout IE0 = 0; // Clear external interrupt flag LED = 1; return;}; _tmp = _tmp lt; lt; 1; if (! IR) _tmp ++; };

Зробити це без розрахунків буде досить просто. Середа Keil uVision2 має у своєму складі відладчик і в режимі налагодження завжди можна подивитися поточний процесорний час.

Контролер люстри

Засікаючи час початку і закінчення циклу при покрокової налагодженні легко можна порахувати час роботи циклу. Для того, щоб воно збіглося з реальним, необхідно у властивостях проекту правильно встановити частоту кварцового резонатора.

Контролер люстри

Контролер люстри

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

Тепер про конструкції. Контролер НЕ програмується внутрісхемний, з цього засаджені в панельку, Fuse бітів не має, що сильно спрощує процес програмування. Для програмування використовувався програматор Blow it. Взяти його можна тут, пост # 3. Це дуже простий і надійний програматор, який служить вже без малого 10 років. Питання по программатору можна задати в зазначеному топіку. Контролер АT89C2051-24PI, транзистори Т1..Т6 можна застосувати будь-які малопотужні, структури npn на приклад КТ3102, КТ315. Реле К1..К6 на напругу 12в, здатні комутувати 220в. Струм споживаний одним реле ~ 20мА. Діоди можуть бути будь-якими випрямними на струм до 1А і напругою понад 100в, на приклад 1N1044, 1N1050, 1N1056. Конденсатор С4 повинен бути розрахований на напругу не менше 25в. Випрямляч і трансформатор використані від китайського блоку живлення на струм 300 мА.

Контролер люстри

Контролер люстри

Tags

Коментарі до новини