ІК пульт на 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; } }
- captouch_41.zip (3 Кб)
- irsend_1.zip (1 Кб)