ІК пульт на MSP430 Lanchpad

Проект створення сенсорного частково універсального пульта під певні завдання. Пульт створюється на базі контролера MSP430 Lanchpad, купленого ще по 4.30$ (на даний момент ціна 9.99$) і сенсорного блоку 430BOOST-SENSE1 (ціна 10$).

430BOOST-SENSE1 (Capacitive Touch BoosterPack) - додаткова плата до набору розробника MSP430 Value Line LaunchPad development kit (MSP-EXP430G2). На платі розташовані деякі варіанти ємнісних сенсорних датчиків, включаючи колесо прокрутки, кнопку та датчик наближення. Крім того, на платі встановлені 9 світлодіодів, які забезпечують індикацію взаємодії користувача з ємнісними сенсорними датчиками. 

Додатково до 430BOOST-SENSE1 додається попередньо запрограмований мікроконтролер MSP430G2452IN20 родини MSP430 ValueLine для демонстрації роботи з ємнісними сенсорними датчиками. Таким чином, розробник має можливість ознайомитися з роботою сенсорних датчиків без необхідності програмування мікросхеми.

При об'єднанні з платою LaunchPad kit, плата 430BOOST-SENSE1 пропонує закінчений апаратний та програмний зразок розробки, що дозволяє  швидко і легко замінити будь-які фізичні кнопки елементами на основі ємнісних сенсорних датчиків. 

Вивчення датащита допомогло знайти використовувані виводи MSP430 Lanchpad (див. рис.)

 

З виводів P1.3 - P1.7 будемо керувати світлодіодами, а виходів P2.0 - P2.5 отримувати показання з панелі.

Для програмування використовувалася Arduino-подібна середа програмування EnergiaВикористав бібліотеку CapTouch. Після експериментів з отриманням значень при натисканнях на панель, призначення натискань визначимо наступним.

Одночасне натискання P2.0 (на малюнку червоне) і P2.5 (D0) послідовний перебір поточного пристрою за зростанням,натискання P2.5(D0) перебір поточного пристрою за спаданням,при цьому на світлодіодах відповідна індикація 

Натискання на області P2.1 - P 2.4 і між двома сусідніми областями - відправка коду з бліком світлодіода D0. Натискання двома пальцями P2.0 - перехід в режим сну

Індикція для виводів

P1_0,P1_3,P1_4,P1_5,P1_6,P1_7

наведена в масиві

const boolean LEDS_MODE[11][6]={
   {0,0,0,0,0,0}, // сплячий режим
   {0,0,1,0,0,0}, // вибір пульта 1
   {0,0,1,1,0,0}, // вибір пульта 2
   {0,0,1,1,1,0}, // вибір пульта 3
   {0,0,1,1,1,1}, // вибір пульта 4
   {0,1,0,1,1,1}, // вибір пульта 5
   {0,1,0,0,1,1}, // вибір пульта 6
   {0,1,0,0,0,1}, // вибір пульта 7
   {0,1,0,0,0,0} // вибір пульта 8
   };

В принципі можна створити 16 пультів по 8 клавіш (а задіюючи P_0 в 2 рази більше), але робив для себе для наглядності мені так більш зручно. 

У мене група 1 - світлодіодні стрічки RGB - у мене 2 шт. В друга група - новорічна лампа-нічник  Остального поки немає - але є задумки деякі.

Для відправки кодів через ІК-світлодіоди планував використовувати бібліотеку IRRemote. Здавалося все просто і роботи максимум на робочу тиждень, але виявилося все не так. 

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

#include "CapTouch.h"

const int PINS[]={0,P2_0,P2_1,P2_2,P2_3,P2_4,P2_5};
const int LEDS[]={0,P1_0,P1_3,P1_4,P1_5,P1_6,P1_7};
const boolean LEDS_MODE[11][6]={
                       {0,0,0,0,0,0}, // сплячий режим
                       {0,0,1,0,0,0}, // вибір пульта 1
                       {0,0,1,1,0,0}, // вибір пульта 2
                       {0,0,1,1,1,0}, // вибір пульта 3
                       {0,0,1,1,1,1}, // вибір пульта 4
                       {0,1,0,1,1,1}, // вибір пульта 5
                       {0,1,0,0,1,1}, // вибір пульта 6
                       {0,1,0,0,0,1}, // вибір пульта 7
                       {0,1,0,0,0,0} // вибір пульта 8
                       };
const int choice_command[]={0,1,1,1,1,0,1,0,1,1,0,0,1,0,0,0};                      
int mode=0;
int sleep=0;
int base_counts[7];
unsigned int count, base_count,delta_count;
int state = 0;

static const unsigned int threshold = 150;
static const unsigned int threshold2 = 250;
CapTouch touch1;


void setup() {
  Serial.begin(9600);
  for(int i=1;i<7;i++)
   {touch1.add(PINS[i]);
   base_counts[i]=touch1.measure(PINS[i]);
    pinMode(LEDS[i], OUTPUT);
   }
}

void loop()
{
 change_mode(get_pressed());
 establish_leds(mode);
 delay(500);
}

// перевірка touch-клавіш на натискання
int get_pressed()
  {
  int pos=0;
  for(int i=0;i<7;i++)
    {
    count = touch1.measure(PINS[i]);
    if(base_counts[i] < count) 
      {base_counts[i] = (base_counts[i] + count) >> 1;
      delta_count = 0;}
    else 
      {delta_count = base_counts[i] - count;}
    if(delta_count > threshold) 
      {
       uint16_t bitmask = 1;
       if (i >0)
        {for (int j = 0; j < i-1; ++j) 
	    bitmask <<= 1;
        }
       pos=pos+bitmask;
       if(delta_count>280 && i==1)
         sleep=1;
      }

    else 
      {base_count = base_count - 1;}
    delay(10);
   }   
 return pos;
 }
 // встановити світлодіоди для режиму
 void establish_leds(int mode)
   {
   for(int i=1;i<7;i++) 
    digitalWrite(LEDS[i],LEDS_MODE[mode][i-1]);  
   }
 // змінити режим після натискання
 void change_mode(int pos)
   {
   // аналіз натискань
   // перехід в сплячий режим
   if(sleep==1) 
     {mode=0;sleep=0;
     return;}
   // вибір наступного режиму
   if(bitRead(pos,0) && bitRead(pos,5))
     {mode=mode+1;mode=min(8,mode);
      return;} 
   // вибір попереднього режиму
   if(bitRead(pos,5))
     {mode=mode-1;mode=max(1,mode);
      return;} 
   // відправка коду  
   byte bpos;
   bpos=lowByte(pos); 
   bitClear(bitClear(bpos,0),5);
   bpos=bpos>>1; 
   if(mode>0 && choice_command[bpos])
     {send_command(mode,bpos);
     return;}
   } 
// змінити режим після натискання
 void send_command(int high,byte low)
   { 
   byte bsend; 
   bsend=lowByte(high)<<4; 
   bsend+=low;
   Serial.println(bsend,HEX);
   digitalWrite(P1_0,HIGH);
   delay(500); 
   digitalWrite(P1_0,LOW);
   } 

Далі почалися проблеми. При підключенні бібліотеки IRremote, скетч втратив натискання на двох областях, а при спробі відправити код через ІК-світлодіод скетч взагалі не працював. Для відправки кодів використовував другий комплект M430. Два модулі пов'язані по послідовному порту. Приймання байта з послідовного порту, вибір коду з таблиці та відправка через ІК-світлодіод (використовується бібліотека IRremote).

Ось скетч

#include "IRremote.h"

IRsend irsend;
int inChar;
boolean stringComplete = false;
// список кодів
long irkod[128]={
  0x12,0x24,0x36,0x48,0,0x6c,0,0xff,0x5a,0,0,1,0,0,0,0,0, // нічник
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0    
};
void setup()
{
  Serial.begin(9600);
}

void loop() {

  if (stringComplete) {
    //irsend.sendRC5(irkod[inChar], 12); 
    irsend.sendRC5(inChar, 12); 
    stringComplete = false;
  }

}

void serialEvent() {
  while (Serial.available())
   {
    // отримати новий байт:
    inChar = (int)Serial.read(); 
    stringComplete = true;
   }
}
Прикріплені файли:
Top