ИК пульт на MSP430 Lanchpad

mc246-2

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

mc246-1

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

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

При объединении с платой LaunchPad kit, плата 430BOOST-SENSE1 предлагает законченный аппаратный и программный образец разработки, позволяющий быстро и легко заменить любые физические кнопки элементами на основе емкостных сенсорных датчиков.

mc246-2

Изучение даташита помогло найти используемые выводы MSP430 Lanchpad (см. рис.)

mc246-4

mc246-3
С выводов 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 — переход в режим sleep

Индикация для выводов

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())
{
// get the new byte:
inChar = (int)Serial.read();
stringComplete = true;
}
}

One comment

  1. Precisely how would certainly an individual make use of this solution although create inside the redundancy of an SAN? Can you create two these in addition to make use of VMWare and Microsoft windows functions to help duplicate info throughout the two inside near real-time?

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>