Выкладываю свою версию адаптера рулевых кнопок.
На данный момент устройство работает - спасибо Дмитрию (Demon083)!
Я не претендую на гениальность.
Развивать данный адаптер дальше не буду, так как это временная мера.
Адаптер изготавливался под определенный руль и определенную магнитолу, но это не исключает возможность переделки и использования для других комплектов руль-магнитола.
Итак, поехали!
После установки
руля с медиа-кнопками возник естественный вопрос: «А как его «подружить» с магнитолой?» Конечно, существует великое множество всевозможных адаптеров на любой вкус и кошелёк, но это не для нас.
Поскольку моя магнитола (Kwnwood KDC-6051U) понимает только протокол NEC, была использована имеющаяся
Arduino Nano, немножко резисторов, стабилизатор 7812, пара кондеров и кусок монтажной платы. Всё это хозяйство было собрано на монтажке.

Для снятия кодов был использован самый обычный
ИК-фотодиод, купленный с
известного всем сайта, и родной пульт от магнитолы.
В скетче использовал специально заточенную под это дело библиотеку IRremote.h. На сколько я понял описание этой библиотеки, выход только D3. Его можно даже не прописывать, всё и так работает.
Достоинства:
Дёшево, быстро.
Недостатки:
Подходит только для магнитол с импульсным управлением. Настроить можно только на месте и только с ноутбуком, Нужна модифицированная библиотека:
IRremote.zip.
Рабочий скетч:
PHP код:
#include <IRremote.h>
IRsend irsend;
const int read1 = A0;//левый блок кнопок
const int read2 = A1;//правый блок кнопок
float val1=0;
float val2=0;
float lastval1=0;
float lastval2=0;
int pause1=180;//Задержка после нажатия кнопок
int pause2=200;//Задержка после нажатия кнопrи SRC
// Коды сняты с пульта
//[Влево] 9D6250AF
//[Вправо] 9D62D02F
//[Громкость +] 9D6228D7
//[Громкость –] 9D62A857
//[ + ] 9D62B04F
//[ – ] 9D6230CF
//[SRC] 9D62C837
//Расположение кнопок на блоках и значения
//Громкость + правый 843
//Громкость - правый 894
//Следующий правый 305
//Предыдущий правый 540
//Источник правый 696
//Громковсть + левый 540
//Громкость - левый 843
//+ левый 305
//- левый 696
void setup()
{
pinMode (read1, INPUT);
pinMode (read2, INPUT);
Serial.begin(9600);
}
void loop()
{
val1 = analogRead(read1);
val2 = analogRead(read2);
/////////////////// Обработка правого блока кнопок //////////////////////
if (val1>10 && val1<1000)//фильтр от помех
{
if (val1 != lastval1)//если значение изменилось
// Serial.print("Right ");
// Serial.println(val1);
{
delay (pause1);//задержку подбирал на свой вкус
if (val1>794&&val1<860)//Громкость +
{
Serial.println(" R. Vol +");//Контроль
irsend.sendNEC(0x9D6228D7, 32);
lastval1=val1;
}
if (val1>877&&val1<910)//Громкость -
{
Serial.println(" R. Vol -");//Контроль
irsend.sendNEC(0x9D62A857, 32);
lastval1=val1;
}
if (val1>644&&val1<745)//Выбор источника
{
Serial.println(" R. SRC");//Контроль
irsend.sendNEC(0x9D62C837, 32);
lastval1=val1;
delay (pause2);//дополительная задержка
}
if (val1>225&&val1<383)//Вправо
{
Serial.println(" R. >>");//Контроль
irsend.sendNEC(0x9D62D02F, 32);
lastval1=val1;
}
if (val1>462&&val1<592)//Влево
{
Serial.println(" R. <<");//Контроль
irsend.sendNEC(0x9D6250AF, 32);
lastval1=val1;
}
}
}
/////////////////// Обработка левого блока кнопок //////////////////////
if (val2>10 && val2<1000)//фильтр от помех
{
if (val2 != lastval2)//если значение изменилось
{
// Serial.print("Left ");
// Serial.println(val2);
delay (pause1);//задержку подбирал на свой вкус
if (val2>462&&val2<644)//Громкость +
{
Serial.println(" L. Vol +");//Контроль
irsend.sendNEC(0x9D6228D7, 32);
lastval2=val2;
}
if (val2>794&&val2<910)//Громкость -
{
Serial.println(" L. Vol -");//Контроль
irsend.sendNEC(0x9D62A857, 32);
lastval2=val2;
}
}
if (val2>225&&val2<383)//Вверх
{
Serial.println(" L. +");//Контроль
irsend.sendNEC(0x9D62B04F, 32);
lastval2=val2;
}
if (val2>644&&val2<745)//Вниз
{
Serial.println(" L. -");//Контроль
irsend.sendNEC(0x9D6230CF, 32);
lastval2=val2;
}
}
}
Скетч для снятия данных с кнопок на руле:
PHP код:
const int analogPin1 = A0;// Для левого
const int analogPin2 = A1;// Для правого
float val1 = 0;
float val2 = 0;
void setup()
{
pinMode (analogPin1, INPUT);
Serial.begin(9600);
}
void loop()
{
val1 = analogRead(analogPin1);
val2 = analogRead(analogPin2);
delay (200);
if (val1<=1000)
{
Serial.print("Lefr ");
Serial.println(val1);
}
if (val2<=1000)
{
Serial.print("Right ");
Serial.println(val2);
}
}
Скетч для снятия кодов с пульта (взят из папки examples, которая была вместе с библиотекой):
PHP код:
#include <IRremote.h>
int RECV_PIN = 10;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver
}
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
// decode_results *results = (decode_results *)v
void dump(decode_results *results) {
int count = results->rawlen;
if (results->decode_type == UNKNOWN) {
Serial.print("Unknown encoding: ");
}
else if (results->decode_type == NEC) {
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY) {
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5) {
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6) {
Serial.print("Decoded RC6: ");
}
else if (results->decode_type == PANASONIC) {
Serial.print("Decoded PANASONIC - Address: ");
Serial.print(results->panasonicAddress,HEX);
Serial.print(" Value: ");
}
else if (results->decode_type == JVC) {
Serial.print("Decoded JVC: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
dump(&results);
irrecv.resume(); // Receive the next value
}
}
При изготовлении своего адаптера рулевых кнопок мне стало интересно, почему полученные с пульта у библиотеки IRemote.h (протокол NEC) данные отличаются? Стал копать данную тему и вот что я накопал. Для примера рассмотрим адрес/команду кнопки [Vol+] стандартного пульта автомагнитолы Kenwood. В Ардуине это выглядит так: 9D6228D7, а вот в официальном описании так: адрес:46B9 команда:14. (HEX)
Нужна была программа, которая умеет конвертировать между собой, шестнадцатеричные, десятичные и двоичные числа и первая, которая пришла мне на ум была калькулятор из винды в расширенном виде и обратил внимание на двоичный код и пришло прозрение!
Возьмем наш код из ардуины 9D6228D7, где 9D62-является адресов, а 28D7-командой.
Теперь представим 9D62 в двоичном виде и получим 1101100101100010. А теперь самое интересное. Надо прочитать с конца данный двоичный код 0100011010011011 и преобразовать обратно в HEX. Получаем 469B. Это уже знакомые нам цифры, не так ли?
Теперь команда. С ней немножко сложнее. Её надо разбить на 2 части 28 и D7. Получаем
28 00101000
D7 11010111
Как видим, одно значение инверсно другому. Читаем 28 наоборот и получаем 14.
Теперь обратное преобразование
Возьмем адрес:46B9 и команду:15 [Vol-] и переведем это на язык ардуины.
46B9 -> 0100 0110 1011 1001 ->1001 1101 0110 0010 -> 9D62
15-> 0001 0101 -> 1010 1000 -> A8 (читаем наоборот)
1010 1000
0101 0111 -> 57 (инвертируем)
Складываем всё в кучу и получаем 9D62A857.
Надеюсь кому-нибудь пригодится.