Новогодняя лампа-ночник из RGB-светодиодов на плате LaunchPad MSP-EXP430, управляемая ИК-пультом

Давно хотелось сделать что-нибудь для дома на RGB-светодиодах. И решил к празднику сделать «новогодний ночник» под елку, как дополнение к приевшимся гирляндам, тем более, что все необходимое имелось в наличии. 

Ночник по замыслу должен гореть разными цветами, плюс несколько программ мигания. Сделано было 2 штуки, один на снимке. Видео — в конце статьи.

В качестве контроллера выбор пал на плату контроллера LaunchPad MSP-EXP430G2. Во-первых цена — плату можно заказать по цене 4.30$ (и бесплатная доставка курьерской службой FedEx) на сайте компании Texas Instruments. Вот ссылка на страницу заказа — купить.

Плата LaunchPad

Во-вторых — среда программирования Energia, очень похожая на IDE Arduino. Для облегчения программирования, также как и в Arduino IDE, среда программирование поставляется с библиотеками, некоторые из которых правда неработоспособны, с чем мне и пришлось столкнуться при написании программы. Тем не менее проект развивается, для поддержки пользователей есть отдельная ветка на форуме TI, посвященная библиотекам для Energia. 

Energia

Для управления ночником решил использовать ИК-пульт. 

Полный список деталей:

  1. Плата контроллера LaunchPad MSP-EXP430G2 — 1 шт.
  2. RGB — светодиод — 6 шт.
  3. Резистор 220 Ом — 6 шт
  4. Микросхема 74HC595 — 3 шт

Для схемы ИК приемника

  1. ИК-приемник TSOP31238 — 1 шт
  2. Резистор 100 Ом — 1 шт
  3. Конденсатор 10 мкФ 25В — 2 шт.
  4. Конденсатор 0.1 мкФ — 2 шт.

Для платы LaunchPad MSP-EXP430G2 необходимо питание 1.8 — 3.6 В, в наличии имелись блоки питания на 5В, поэтому  еще детали для стабилизатора питания на 3.3 В

  1. Микросхема APU1206H-33
  2. Конденсатор 10 мкФ 25В — 2 шт.

mc182-4.png

А также плафон для лампы, клей, новогодние украшения.

Если кто будет использовать библиотеку IRremote, учтите, что не работает функция отправки ir-кода, мне был нужен только прием. Схема подключения ИК-приемника представлена на рисунке. Выход данных TSOP подсоединен ко входу P1_3 платы LaunchPad.

mc182-5.png

Я делал 2 устройства, для одного использовал пульт для контроллера RGB-лент,

launchpad5.jpg

Для другого — пульт Marmitek X10 (рис)

launchpad-2.jpg

Сначала определимся с назначением клавиш пультов для выбора режимов ночника. Для пульта  контроллера RGB-лент достаточно понятно:

(R — R, G — G, B — B, RG — RG, GB — GB, RB — RB, W — WHITE, off — BLACK,   крайние правые 4 (черного цвета) — режимы мигания )

для пульта Marmitek:

(1 — R, 2 — G, 3 — B, 4 — RG, 5 — GB, 6 — RB, 0 — WHITE, 6,7,8 — режимы мигания )

Напишем скетч для «отлова» кодов нажимаемых клавиш пультов (коды выводим в монитор последовательного порта)

 #include "Energia.h" //  #include IRremote.h int RECV_PIN = P1_3; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; byte_ir_kod;  // коды клавиш для режимов R,G,B,RG,GB.RB,WHITE,BLACK,мигание1,... const long IR_CODES[12];  void setup() {   irrecv.enableIRIn(); // Start the receiver   attachInterrupt(RECV_PIN,ext_ir_code,FALLING);     Serial.begin(9600);   Serial.println("start"); } void loop()  {  if(ir_kod>0)    {    Serial.print(ir_kod,HEX);    ir_kod=0;    }  } // получение кода пульта  void ext_ir_code() {   detachInterrupt(RECV_PIN);   if (irrecv.decode(&results)) {     ir_kod=lowByte(results.value);     delay(500);     irrecv.resume(); // Receive the next value   }     attachInterrupt(RECV_PIN,ext_ir_code,FALLING); }  

С кодами клавиш определились, заносим их в массив

 // x10 marmitek const long IR_CODES[12]={0x00,0x08,0x04,0x0C,0x02,0x0A,0x09,0x09,0x06,0x0E,0x01,0x03}; или // для контроллера RGB лент keys24 const long IR_CODES[12]={0xDF,0x9F,0x5F,0xEF,0xAF,0x6F,0x1F,0xBF,0x2F,0x0F,0x37,0x17};

Теперь программа управления свечением RGB-светодиодов.

Экономить выводы LaunchPad для управления 6 RGB-светодиодами будем использовать микросхемы 74HC595 (преобразователь последовательного интерфейса в параллельный), при этом мы можем обойтись 3 выводами контроллера. Используем библиотеку SPI. 

Выводы соединяем следующим образом

 LaunchPad 74HC595
P2_0 — RCK 12
P1_7 — MOSI 14
P1_5 — SCK 11

launchpad3.jpg

И схема

Схема устройства

Т.к. все сделано на макетной плате и соединения проводами, используются выводы Q1-Q6 микросхемы 74HC595.

Создадим в программе двумерный массив, с данными для разных режимов (16 — с запасом, может пригодиться под какой-нибудь пульт).

 const byte MODES[16][8]={                       {0x12,1,0x12,2,0x12,3,0x12,1}, // R                       {0x24,1,0x24,2,0x24,3,0x24,1}, // G                       {0x48,1,0x48,3,0x48,1,0x48,1}, // B                       {0x36,1,0x36,2,0x36,3,0x36,1}, // RG                       {0x6C,1,0x6C,2,0x6C,3,0x6C,1}, // GB                       {0x5A,1,0x5A,3,0x5A,1,0x5A,1},  // BR                       {0xFF,1,0xFF,1,0xFF,1,0xFF,1}, // WHITE                       {0,1,0,2,0,1,0,1}, // BLACK                       {0x12,5,0x24,5,0x48,5,0x5A,5},  // prg1 r1b1g1y1                       {0x48,10,0x6C,10,0x48,10,0x6C,10}, // prg2 b3gb1b3gb1                       {0x48,20,0x22,20,0x12,20,0x12,20},  // prg3                       {0x12,1,0x12,1,0x12,1,0x12,1}, // prg4                       {0x48,1,0x22,3,0x12,1,0x12,1},  // prg5                       {0x12,1,0x12,1,0x12,1,0x12,1}, // prg6                       {0x48,1,0x22,3,0x12,1,0x12,1},  // prg7                       {0x12,1,0x12,1,0x12,1,0x12,1} // prg8                      }; int offset0=0; int offset1 = 1;           // выбранная программа int offset2 = 1;           // фрагмент(кадр) программы int offset3 = 1;           // длительность кадра int my_channel=1; 

Индекс массива — программа свечения, нечетные байты одномерных массивов — последовательные данные(цвет)  отправляемые SPI, четные — длительность в сек. свечения. По прерыванию получаем код с пульта, ищем наличие кода в массиве IR_CODES (процедура ir_code_control()), при наличии выставляем значения переменных 

offset1 — номер режима,

offset2=1, offset3=1 — индекс первых фрагменты последовательностей.

Каждую секунду в цикле loop() вызывается программа process_step(), которая отправляет данные(цвет) по SPI данные в микросхемы 74HC595.

 // 74hc595 - ms430 //   12  - P2_0 //   14  - P1_7 //   11  - P1_5 //   10   - + #include "Energia.h"  #define REG_SELECT  8  // пин, управляющий защёлкой (SS в терминах SPI)  #include IRremote.h int RECV_PIN = P1_3; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results;  // x10 marmitek //const long IR_CODES[12]={0x00,0x08,0x04,0x0C,0x02,0x0A,0x09,0x09,0x06,0x0E,0x01,0x03}; // для контроллера RGB лент keys24 const long IR_CODES[12]={0xDF,0x9F,0x5F,0xEF,0xAF,0x6F,0x1F,0xBF,0x2F,0x0F,0x37,0x17}; const byte MODES[16][8]={                       {0x12,1,0x12,2,0x12,3,0x12,1}, // R                       {0x24,1,0x24,2,0x24,3,0x24,1}, // G                       {0x48,1,0x48,3,0x48,1,0x48,1}, // B                       {0x36,1,0x36,2,0x36,3,0x36,1}, // RG                       {0x6C,1,0x6C,2,0x6C,3,0x6C,1}, // GB                       {0x5A,1,0x5A,3,0x5A,1,0x5A,1},  // BR                       {0xFF,1,0xFF,1,0xFF,1,0xFF,1}, // WHITE                       {0,1,0,2,0,1,0,1}, // BLACK                       {0x12,5,0x24,5,0x48,5,0x5A,5},  // prg1 r1b1g1y1                       {0x48,10,0x6C,10,0x48,10,0x6C,10}, //prg2b3gb1b3gb1                       {0x48,20,0x22,20,0x12,20,0x12,20},  // prg3                       {0x12,1,0x12,1,0x12,1,0x12,1}, // prg4                       {0x48,1,0x22,3,0x12,1,0x12,1},  // prg5                       {0x12,1,0x12,1,0x12,1,0x12,1}, // prg6                       {0x48,1,0x22,3,0x12,1,0x12,1},  // prg7                       {0x12,1,0x12,1,0x12,1,0x12,1} // prg8                      }; int offset0=0; int offset1 = 1;           // выбранная программа int offset2 = 1;           // фрагмент(кадр) прогаммы int offset3 = 1;           // длительность кадра int my_channel=1;  void setup() {   /* Инициализируем шину SPI. Если используется программная реализация,    * то вы должны сами настроить пины, по которым будет работать SPI.    */   SPI.begin();   Serial.begin(9600);   pinMode(REG_SELECT, OUTPUT);   digitalWrite(REG_SELECT, LOW); // выбор ведомого - нашего регистра   SPI.transfer(0); // очищаем содержимое регистра   digitalWrite(REG_SELECT, HIGH);    irrecv.enableIRIn(); // Start the receiver   Serial.println("start");   attachInterrupt(RECV_PIN,ext_ir_code,FALLING);   }   void loop()  {  delay(1000);  process_step();  }   void process_step(){   // получение кода отправки   offset3=offset3-1;   if(offset3==0)     {     offset2=offset2+1;offset2=offset2%4;     offset3=MODES[offset1-1][offset2*2+1];     }  /* Записываем значение в сдвиговый регистр */   digitalWrite(REG_SELECT, LOW);   SPI.transfer(255-MODES[offset1-1][offset2*2]);   SPI.transfer(255-MODES[offset1-1][offset2*2]);   SPI.transfer(255-MODES[offset1-1][offset2*2]);   digitalWrite(REG_SELECT, HIGH);   offset0++;   if(offset0==8) offset0=0; } // получение кода пульта void ext_ir_code() {   detachInterrupt(RECV_PIN);   if (irrecv.decode(&results)) {     byte ir_kod=lowByte(results.value);     // проверка кода     ir_code_control(ir_kod);     delay(500);     irrecv.resume(); // Receive the next value   }     attachInterrupt(RECV_PIN,ext_ir_code,FALLING); } // проверка кода void ir_code_control(byte kod) {    for(int i=0;i<12;i++)    {    if(kod==IR_CODES[i])      {      offset1=i+1;      offset2=1;offset3=1;      return;}    } }

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Список деталей
LaunchPad MSP-EXP430G2 1
Светодиод 6 RGB
Резистор 200 Ом 18
Сдвиговый регистр CD74HC595 3
Схема ИК приемника
ИК-приемник TSOP3126 1
R1 Резистор 100 Ом 1
С2, С3 Электролитический конденсатор 10 мкФ 25В 2
С5, С6 Конденсатор 100 нФ 2
Схема стабилизатора питания
Линейный регулятор APU1206H-33 1
С1, С2 Электролитический конденсатор 10 мкФ 25В 2