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

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

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

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

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

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

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

  • Плата контроллера LaunchPad MSP-EXP430G2 — 1 шт.
  • RGB — светодиод — 6 шт.
  • Резистор 220 Ом — 6 шт
  • Микросхема 74HC595 — 3 шт
  • Для схемы ИК приемника

  • ИК-приемник TSOP31238 — 1 шт
  • Резистор 100 Ом — 1 шт
  • Конденсатор 10 мкФ 25В — 2 шт.
  • Конденсатор 0.1 мкФ — 2 шт.
  • Для платы LaunchPad MSP-EXP430G2 необходимо питание 1.8 — 3.6 В, в наличии имелись блоки питания на 5В, поэтому  еще детали для стабилизатора питания на 3.3 В

  • Микросхема APU1206H-33
  • Конденсатор 10 мкФ 25В — 2 шт.
  • А также плафон для лампы, клей, новогодние украшения.

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

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

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

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

    И схема

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

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

    const byte MODES[16][8]={
    {0x12,1,0×12,2,0x12,3,0×12,1}, // R
    {0x24,1,0×24,2,0x24,3,0×24,1}, // G
    {0x48,1,0×48,3,0x48,1,0×48,1}, // B
    {0x36,1,0×36,2,0x36,3,0×36,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,0×24,5,0x48,5,0x5A,5}, // prg1 r1b1g1y1
    {0x48,10,0x6C,10,0×48,10,0x6C,10}, // prg2 b3gb1b3gb1
    {0x48,20,0×22,20,0x12,20,0×12,20}, // prg3
    {0x12,1,0×12,1,0x12,1,0×12,1}, // prg4
    {0x48,1,0×22,3,0x12,1,0×12,1}, // prg5
    {0x12,1,0×12,1,0x12,1,0×12,1}, // prg6
    {0x48,1,0×22,3,0x12,1,0×12,1}, // prg7
    {0x12,1,0×12,1,0x12,1,0×12,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,0×12,2,0x12,3,0×12,1}, // R
    {0x24,1,0×24,2,0x24,3,0×24,1}, // G
    {0x48,1,0×48,3,0x48,1,0×48,1}, // B
    {0x36,1,0×36,2,0x36,3,0×36,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,0×24,5,0x48,5,0x5A,5}, // prg1 r1b1g1y1
    {0x48,10,0x6C,10,0×48,10,0x6C,10}, //prg2b3gb1b3gb1
    {0x48,20,0×22,20,0x12,20,0×12,20}, // prg3
    {0x12,1,0×12,1,0x12,1,0×12,1}, // prg4
    {0x48,1,0×22,3,0x12,1,0×12,1}, // prg5
    {0x12,1,0×12,1,0x12,1,0×12,1}, // prg6
    {0x48,1,0×22,3,0x12,1,0×12,1}, // prg7
    {0x12,1,0×12,1,0x12,1,0×12,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-EXP430G21

    Светодиод6
    RGB
    Резистор200 Ом18

    Сдвиговый регистрCD74HC5953
    Схема ИК приемника
    ИК-приемникTSOP31261
    R1
    Резистор100 Ом1
    С2, С3
    Электролитический конденсатор10 мкФ 25В2
    С5, С6
    Конденсатор100 нФ2
    Схема стабилизатора питания
    Линейный регуляторAPU1206H-331
    С1, С2
    Электролитический конденсатор10 мкФ 25В2
    Добавить все

    Скачать список элементов (PDF)

    Прикрепленные файлы:

    Добавить комментарий

    Ваш адрес email не будет опубликован.