PHP код:
#include <OLED_I2C.h>
OLED oled(SDA, SCL, 8);
extern uint8_t SmallFont[];
int IBUSreceiveByte = 0;
byte IBUSbyte[7] = {0,0,0,0,0,0,0};
int ButtonPressed = 0;
int KeyID = 0;
byte MINUS_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x32, 0x10, 0x1E}; // - BUTTON PRESS
byte PLUS_DOWN[7] = {0, 0x50, 0x04, 0x68, 0x32, 0x11, 0x1F}; // + BUTTON PRESS
byte PREV_DOWN1[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x08, 0x0F}; // < BUTTON PRESS 1
byte PREV_DOWN2[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x08, 0xAF}; // < BUTTON PRESS 2
byte NEXT_DOWN1[7] = {0, 0x50, 0x04, 0x68, 0x3B, 0x01, 0x06}; // > BUTTON PRESS 1
byte NEXT_DOWN2[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x01, 0xA6}; // > BUTTON PRESS 2
byte VOICE_DOWN[7] = {0, 0x50, 0x04, 0xC8, 0x3B, 0x80, 0x27}; // VOICE BUTTON PRESS
byte RT_DOWN1[7] = {0, 0x50, 0x04, 0xFF, 0x3B, 0x00, 0x90}; // R/T BUTTON PRESS 1
byte RT_DOWN2[7] = {0, 0x50, 0x04, 0xFF, 0x3B, 0x40, 0xD0}; // R/T BUTTON PRESS 2
void setup() {
Serial1.begin(9600);
oled.begin();
oled.setFont(SmallFont);
oled.print("BMW NEXUS 7", CENTER, 0);
oled.print("Key:", LEFT, 20);
oled.print("In Load Hall 5v", LEFT, 45);
oled.print("OFF OFF OFF OFF", LEFT, 55);
oled.update();
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, INPUT);
pinMode(7, OUTPUT);
digitalWrite(4, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
Keyboard.begin();
Media.begin();
//Remote.begin();
//System.begin();
}
void loop() {
// вход
if (digitalRead(6) == LOW) {
PrintState("ON ", 0);
digitalWrite(5, HIGH); // выход нагрузки
PrintState("ON ", 30);
digitalWrite(7, HIGH); // hall датчик
PrintState("ON ", 60);
digitalWrite(4, HIGH); // выход 5 вольт
PrintState("ON ", 90);
} else {
PrintState("OFF", 0);
digitalWrite(5, LOW); // выход нагрузки
PrintState("OFF", 30);
digitalWrite(7, LOW); // hall датчик
PrintState("OFF", 60);
digitalWrite(4, LOW); // выход 5 вольт
PrintState("OFF", 90);
}
// кнопки руля
if (Serial1.available() && ButtonPressed == 0) {
TryReadIBUSmsg();
}
// нажата кнопка
if (ButtonPressed == 1) {
switch (KeyID) {
case 100: // если клавиша не опознана или есть ошибки в шине при чтении
Media.releaseAll();
Keyboard.releaseAll();
PrintKey("UNKNOWN key");
PrintCode();
break;
case 1:
Media.write(MEDIA_VOLUME_UP);
PrintKey("VOL + key");
PrintCode();
break;
case 2:
Media.write(MEDIA_VOLUME_DOWN);
PrintKey("VOL - key");
PrintCode();
break;
case 11:
Media.write(MEDIA_NEXT);
PrintKey("NEXT TRACK key");
PrintCode();
break;
case 21:
Media.write(MEDIA_PREVIOUS);
PrintKey("PREV TRACK key");
PrintCode();
break;
case 31:
Media.write(MEDIA_PLAY_PAUSE);
PrintKey("VOICE key");
PrintCode();
break;
case 41:
//Media.write(MEDIA_BROWSER_BACK);
Keyboard.press(KEY_LEFT_ALT);
Keyboard.press(KEY_TAB);
Keyboard.release(KEY_TAB);
Keyboard.press(KEY_TAB);
Keyboard.release(KEY_TAB);
PrintKey("R/T key");
PrintCode();
break;
}
ButtonPressed = 0;
Serial1.flush();
}
delay(10);
}
// чтение I-Bus шины
void TryReadIBUSmsg() {
IBUSreceiveByte = Serial1.read();
if (IBUSreceiveByte==0x50) {
IBUSbyte[1]=0x50;
for (int i=2; i<=6; i++) {
IBUSbyte[i] = Serial1.read();
delay(10);
}
KeyID=100;
if(memcmp(IBUSbyte, PLUS_DOWN, 7) == 0) { KeyID=1; }
if(memcmp(IBUSbyte, MINUS_DOWN, 7) == 0) { KeyID=2; }
if(memcmp(IBUSbyte, NEXT_DOWN1, 7) == 0) { KeyID=11; }
if(memcmp(IBUSbyte, NEXT_DOWN2, 7) == 0) { KeyID=11; }
if(memcmp(IBUSbyte, PREV_DOWN1, 7) == 0) { KeyID=21; }
if(memcmp(IBUSbyte, PREV_DOWN2, 7) == 0) { KeyID=21; }
if(memcmp(IBUSbyte, VOICE_DOWN, 7) == 0) { KeyID=31; }
if(memcmp(IBUSbyte, RT_DOWN1, 7) == 0 ) { KeyID=41; }
if(memcmp(IBUSbyte, RT_DOWN2, 7) == 0 ) { KeyID=41; }
ButtonPressed=1;
} else {
ButtonPressed=0;
}
Serial1.flush();
}
// печатаем код из I-Bus
void PrintCode() {
int x=0;
for (int i=1; i<=6; i++) {
oled.print(String(IBUSbyte[i],HEX), x, 30);
x+=20;
}
oled.update();
}
void PrintKey(String text) {
oled.print(text, 30, 20);
oled.update();
}
void PrintState(String text, int x) {
oled.print(text, x, 55);
oled.update();
}
И
PHP код:
#define CHECK_MS 5
#define DOUBLE_MS 400
#define HOLD_MS 1200
#define NO_B 839 //nothing pressed
#define MODE_B 662 // MODE
#define NXTU_B 509 // NEXT UP
#define NXTD_B 380 // NEXT DOWN
#define MUTE_B 273 // MUTE
#define VOLU_B 180 // VOLUME UP
#define VOLD_B 105 // VOLUME DOWN
#define alpPin 7
boolean volUp[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 1,1,0,1,1,0,1,1, 1,1,0,1,0,1,1,0, 1,1,0,1,0,1,0,1};
boolean volDn[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,1,0,1,1,0,1, 1,1,1,1,0,1,1,0, 1,1,0,1,0,1,0,1};
boolean mute[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 1,0,1,0,1,1,0,1, 1,1,1,0,1,1,1,0, 1,1,0,1,0,1,0,1};
boolean pstUp[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 1,0,1,0,1,0,1,1, 1,1,1,0,1,1,1,1, 0,1,0,1,0,1,0,1};
boolean pstDn[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,0,1,0,1,0,1, 1,1,1,1,1,1,1,1, 0,1,0,1,0,1,0,1};
boolean source[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 1,0,1,1,0,1,1,1, 1,1,0,1,1,0,1,1, 0,1,0,1,0,1,0,1};
boolean trkUp[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 1,0,1,1,1,0,1,1, 1,1,0,1,1,0,1,0, 1,1,0,1,0,1,0,1};
boolean trkDn[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,0,1,1,1,0,1, 1,1,1,1,1,0,1,0, 1,1,0,1,0,1,0,1};
boolean power[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,1,1,0,1,1,1, 1,1,1,0,1,0,1,1, 0,1,0,1,0,1,0,1};
boolean entPlay[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,0,1,0,1,1,1, 1,1,1,1,1,1,0,1, 0,1,0,1,0,1,0,1};
boolean bandProg[48] = {1,1,0,1,0,1,1,1, 1,1,0,1,1,0,1,1, 1,0,1,0,1,0,1,1, 0,1,1,0,1,0,1,1, 1,1,1,1,0,1,1,1, 0,1,0,1,0,1,0,1};
boolean spFlag = 0;
boolean dpFlag = 0;
boolean hpFlag = 0;
int button = 0;
int spbutton = 0;
/*
0-none
1-mode
2-track +
3-track -
4-mute
5-vol+
6-vol-
*/
void setup() {
Serial.begin(9600);
pinMode(7, OUTPUT);
}
void loop() {
static unsigned long oldTime = 0;
int switchStatus = 0;
if (millis() >= oldTime + CHECK_MS) {
oldTime = millis();
switchStatus = CheckSwitch();
if (switchStatus == 0) {
//no button press
} else if (switchStatus == 1) {
// single press
switch (spbutton) {
case 0: // no butto, why are wh here
break;
case 1: // mode
modeSend();
break;
case 2: // next up
trkUpSend();
break;
case 3: // next down
trkDnSend();
break;
case 4: // mute
muteSend();
break;
case 5: // vol up
volUpSend();
break;
case 6: // vol down
volDnSend();
break;
}
} else if (switchStatus == 2) {
//double press
switch (spbutton) {
case 0: // no butto, why are wh here
break;
case 1: // mode
sourceSend();
break;
case 2: // next up
trkUpSend();
break;
case 3: // next down
trkDnSend();
break;
case 4: // mute
muteSend();
break;
case 5: // vol up
volUpSend();
break;
case 6: // vol down
volDnSend();
break;
}
} else if (switchStatus == 3) {
//hold
switch (spbutton) {
case 0: // no butto, why are wh here
break;
case 1: // mode
modeSend();
break;
case 2: // next up
trkUpSend();
break;
case 3: // next down
trkDnSend();
break;
case 4: // mute
muteSend();
break;
case 5: // vol up
volUpSend();
break;
case 6: // vol down
volDnSend();
break;
}
}
}
}
// Service routine called by a timer interrupt
int CheckSwitch() {
static uint16_t State = 0; // Current debounce status
static int curTime = 0;
State=(State<<1) | !RawKeyPressed() | 0xe000;
if (!spFlag) {
if (hpFlag) {
if (State == 0xe000) {
return 3;
} else {
hpFlag = 0;
}
}
if (State==0xf000) {
spFlag = 1;
hpFlag = 1;
dpFlag = 1;
curTime = 0;
spbutton = button;
return 0;
}
}
if (hpFlag && State != 0xe000) {
hpFlag = 0;
}
if (spFlag && hpFlag && curTime > HOLD_MS/CHECK_MS) {
spFlag = 0;
dpFlag = 0;
return 3;
} else if (spFlag && dpFlag && State == 0xf000 && curTime < DOUBLE_MS) {
spFlag = 0;
hpFlag = 0;
dpFlag = 0;
return 2;
} else if (spFlag && !hpFlag && curTime > DOUBLE_MS) {
spFlag = 0;
hpFlag = 0;
dpFlag = 0;
return 1;
} else {
curTime = curTime + CHECK_MS;
return 0;
}
}
boolean RawKeyPressed() {
int anaPin = 0;
anaPin = analogRead(0);
if (anaPin > NO_B - 20) {
button = 0;
return 0;
} else if (anaPin > MODE_B - 20 && anaPin < MODE_B + 20 ) {
button = 1;
return 1;
} else if (anaPin > NXTU_B - 20 && anaPin < NXTU_B + 20 ) {
button = 2;
return 1;
} else if (anaPin > NXTD_B - 20 && anaPin < NXTD_B + 20 ) {
button = 3;
return 1;
} else if (anaPin > MUTE_B - 20 && anaPin < MUTE_B + 20 ) {
button = 4;
return 1;
} else if (anaPin > VOLU_B - 20 && anaPin < VOLU_B + 20 ) {
button = 5;
return 1;
} else if (anaPin < VOLD_B + 20 ) {
button = 6;
return 1;
} else {
button = 0;
return 0;
}
}
//-----------SOURCE------------------
void sourceSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (source[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------MODE-----------------------------------------------
void modeSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (entPlay[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------NEXT UP-----------------------------------------------
void trkUpSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (trkUp[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------NEXT DOWN----------------------------------------------
void trkDnSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (trkDn[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------MUTE---------------------------------------------------
void muteSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (mute[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------VOL UP-----------------------------------------------
void volUpSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (volUp[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
//---------VOL DOWN-----------------------------------------------
void volDnSend() {
//first send 8ms high
digitalWrite(alpPin, HIGH);
delay(8);
// send 4.5ms low
digitalWrite(alpPin, LOW);
delayMicroseconds(4500);
for (int i = 0; i <= 47; i++) {
//send bit for 0.5ms
if (volDn[i] == 1 ) {
digitalWrite(alpPin, HIGH);
} else {
digitalWrite(alpPin, LOW);
}
delayMicroseconds(500);
// wait 0.5ms
digitalWrite(alpPin, LOW);
delayMicroseconds(500);
}
// send 41ms low
digitalWrite(alpPin, LOW);
delay(41);
}
Пытаюсь разобраться, читаю вторые сутки инфу по сабжу, но пока пробелов в понимании процесса слишком много.