1. 三菱電機:機型 GE25NA / 遙控器 KM10D
#define Tolerance_scope 4
#define MARK_EXCESS_Factor 2
#include <IRremote.h>
#include <EEPROM.h>
#define recvPin 2
#define Pin9_SW 9
#define Recv_Enable_LED_Pin 10
#define LED_Buzzer_Pin 11
#define khz 38
#define SMax 10
#define IR_NUM_SIZE 11
#define N00 0x80BFE11E
#define N01 0x80BF49B6
#define N02 0x80BFC936
#define N03 0x80BF33CC
#define N04 0x80BF718E
#define N05 0x80BFF10E
#define N06 0x80BF13EC
#define N07 0x80BF51AE
#define N08 0x80BFD12E
#define N09 0x80BF23DC
#define N10 0x80BF738C
struct NUM_MAP {
unsigned long IR_CODE;
byte INDEX_NUM;
};
struct NUM_MAP IR_MAP[IR_NUM_SIZE] = {{N00, 0}, {N01, 1}, {N02, 2}, {N03, 3}, {N04, 4}, {N05, 5}, {N06, 6}, {N07, 7}, {N08, 8}, {N09, 9}, {N10, 10}};
struct IR_RAW_type {
char RAW_TYPE;
unsigned int RAW_HDR_MARK ;
unsigned int RAW_HDR_SPACE ;
unsigned int RAW_BIT_MARK ;
unsigned int RAW_ONE_SPACE ;
unsigned int RAW_ZERO_SPACE ;
unsigned int rawData_Bits ;
unsigned int rawHole[8][3] ;
byte rawHole_Count ;
byte rawData_Count ;
byte rawData[39] ;
};
struct IR_RAW_type IR_RAW;
bool EnterSetup = false;
byte SetupIndex = 0;
byte IR_MAP_Index;
IRrecv irrecv(recvPin);
IRsend irsend;
decode_results results;
void ST_LED_Buzzer (int Send_Status) {
while ( Send_Status > 0 ) {
if (Send_Status >= 5) {
digitalWrite(LED_Buzzer_Pin, HIGH);
digitalWrite(13, HIGH);
delay(400);
digitalWrite(LED_Buzzer_Pin, LOW);
digitalWrite(13, LOW);
delay(400);
Send_Status = Send_Status - 5;
} else {
digitalWrite(LED_Buzzer_Pin, HIGH);
digitalWrite(13, HIGH);
delay(150);
digitalWrite(LED_Buzzer_Pin, LOW);
digitalWrite(13, LOW);
delay(150);
Send_Status = Send_Status - 1;
}
}
}
void SONYIRSend(byte SendRAWData[], unsigned int SendRAWData_Bits) {
unsigned long SONYIRCode;
SONYIRCode = ( (((unsigned long)SendRAWData[0]) << 24) | (((unsigned long)SendRAWData[1]) << 16) | (((unsigned long)SendRAWData[2]) << 8) | (((unsigned long)SendRAWData[3])) );
irsend.sendSony(SONYIRCode , SendRAWData_Bits);
}
void RAWIRSend(byte SendRAWData[], byte SendRAWData_Len, unsigned int SendRAWData_Bits, byte hz) {
unsigned int rawData_Bits_Count =0;
byte Mask = 1;
byte rawHole_ind = 0;
irsend.enableIROut(hz);
irsend.space(max(IR_RAW.RAW_HDR_MARK,IR_RAW.RAW_HDR_SPACE));
irsend.mark(IR_RAW.RAW_HDR_MARK);
irsend.space(IR_RAW.RAW_HDR_SPACE);
for (unsigned int i = 0; i < SendRAWData_Len; i++) {
for (Mask = B10000000; Mask > 0; Mask >>= 1) {
if (rawData_Bits_Count < SendRAWData_Bits) {
if ((rawHole_ind < IR_RAW.rawHole_Count) && (rawData_Bits_Count == IR_RAW.rawHole[rawHole_ind][0])){
irsend.mark(IR_RAW.rawHole[rawHole_ind][1]);
irsend.space(IR_RAW.rawHole[rawHole_ind][2]);
rawHole_ind ++ ;
} else {
if (SendRAWData[i] & Mask) {
irsend.mark(IR_RAW.RAW_BIT_MARK);
irsend.space(IR_RAW.RAW_ONE_SPACE);
}
else {
irsend.mark(IR_RAW.RAW_BIT_MARK);
irsend.space(IR_RAW.RAW_ZERO_SPACE);
}
}
rawData_Bits_Count++;
}
}
}
irsend.space(max(IR_RAW.RAW_HDR_MARK,IR_RAW.RAW_HDR_SPACE));
}
unsigned int Probability[SMax], Temporary[SMax];
void Shift_Val(unsigned int Val){
byte i,j;
for(i = 0; i < SMax; i++) {
if ((i>0) && (Val == Probability[i-1])) break;
if (Val > Probability[i]) {
for(j = SMax-1; j >= i+1; j--) {
Probability[j] = Probability[j-1];
Temporary[j] = Temporary[j-1];
}
Probability[i] = Val;
Temporary[j] = 0;
break;
}
}
for(i = 0; i<SMax; i++) {
if (Val == Probability[i]) {
Temporary[i]++;
break;
}
}
}
unsigned int FindMaxCount(decode_results *results, int StartPos, unsigned int Check_RAW_BIT_MARK, unsigned int MAX_RAW_ZERO_SPACE) {
unsigned int Return_MAX_Value = 0;
for (byte i=0 ; i < SMax ; i++) {
Probability[i]=0;
Temporary[i]=0;
}
for (int i = StartPos; i < results->rawlen; i+=2) {
if ((Check_RAW_BIT_MARK == 0) || (results->rawbuf[i-1] == Check_RAW_BIT_MARK)){
if ((MAX_RAW_ZERO_SPACE == 0) || (results->rawbuf[i] > MAX_RAW_ZERO_SPACE)){
Shift_Val(results->rawbuf[i]);
}
}
}
unsigned int Last_Count = 0;
for (int i = SMax-1; i>=0; i--) {
if ((Probability[i] >= Tolerance_scope) && (Temporary[i] > 0)) {
if (Return_MAX_Value == 0) {
Return_MAX_Value = Probability[i];
Last_Count = Temporary[i];
} else {
if ((Probability[i] - Probability[i+1]) <= Tolerance_scope) {
if (Temporary[i] >= Last_Count) {
Return_MAX_Value = Probability[i];
Last_Count = Temporary[i];
}
} else {
break;
}
}
}
}
return Return_MAX_Value;
}
void EncodeRAWCode (decode_results *results) {
IR_RAW.rawData_Count = 0;
IR_RAW.rawHole_Count = 0 ;
IR_RAW.RAW_TYPE = results->decode_type;
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.print(F("IR Struct Size (byte) : "));
Serial.println(sizeof(IR_RAW),DEC);
Serial.print(F("IR TYPE : "));
Serial.println(IR_RAW.RAW_TYPE,DEC);
#endif
if (IR_RAW.RAW_TYPE == SONY) {
IR_RAW.RAW_HDR_MARK = 2400;
IR_RAW.RAW_HDR_SPACE = 600;
IR_RAW.RAW_BIT_MARK = 600;
IR_RAW.RAW_ZERO_SPACE = 600;
IR_RAW.RAW_ONE_SPACE = 1200;
IR_RAW.rawData_Bits = results->bits;
IR_RAW.rawData_Count = 4;
IR_RAW.rawData[0] = (byte)((results->value & 0xff000000) >> 24);
IR_RAW.rawData[1] = (byte)((results->value & 0x00ff0000) >> 16);
IR_RAW.rawData[2] = (byte)((results->value & 0x0000ff00) >> 8);
IR_RAW.rawData[3] = (byte)((results->value & 0x000000ff));
} else {
IR_RAW.rawData_Bits = (results->rawlen-3)/2;
IR_RAW.RAW_HDR_MARK = results->rawbuf[1];
IR_RAW.RAW_HDR_SPACE = results->rawbuf[2];
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.println(F("// My Data Start , Mark & Ctrl-C Copy ---------------"));
Serial.println(F(""));
Serial.print(F("#define RAW_HDR_MARK "));
Serial.print(IR_RAW.RAW_HDR_MARK * USECPERTICK - MARK_EXCESS/MARK_EXCESS_Factor, DEC);
Serial.println(F(""));
Serial.print(F("#define RAW_HDR_SPACE "));
Serial.print(IR_RAW.RAW_HDR_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor, DEC);
#endif
IR_RAW.RAW_BIT_MARK = FindMaxCount(results , 3, 0, 0);
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.print(F("#define RAW_BIT_MARK "));
Serial.print(IR_RAW.RAW_BIT_MARK * USECPERTICK - MARK_EXCESS/MARK_EXCESS_Factor, DEC);
Serial.print(F(" // "));
for(byte i = 0; i < SMax; i++) {
if (Probability[i] > 0 ) {
Serial.print(F("( "));
Serial.print(Probability[i] * USECPERTICK, DEC);
Serial.print(F(" , "));
Serial.print(Temporary[i] , DEC);
Serial.print(F(" ), "));
}
}
Serial.print(F(" times."));
#endif
IR_RAW.RAW_ZERO_SPACE = FindMaxCount(results , 4, IR_RAW.RAW_BIT_MARK, 0);
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.print(F("#define RAW_ZERO_SPACE "));
Serial.print(IR_RAW.RAW_ZERO_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor, DEC);
Serial.print(F(" // "));
for(byte i = 0; i < SMax; i++) {
if (Probability[i] > 0 ) {
Serial.print(F("( "));
Serial.print(Probability[i] * USECPERTICK, DEC);
Serial.print(F(" , "));
Serial.print(Temporary[i] , DEC);
Serial.print(F(" ), "));
}
}
Serial.print(F(" times. (in RAW_BIT_MARK)"));
#endif
unsigned int MAX_RAW_ZERO_SPACE = IR_RAW.RAW_ZERO_SPACE + Tolerance_scope;
IR_RAW.RAW_ONE_SPACE = FindMaxCount(results , 4, IR_RAW.RAW_BIT_MARK, MAX_RAW_ZERO_SPACE);
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.print(F("#define RAW_ONE_SPACE "));
Serial.print(IR_RAW.RAW_ONE_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor, DEC);
Serial.print(F(" // "));
for(byte i = 0; i < SMax; i++) {
if (Probability[i] > 0 ) {
Serial.print(F("( "));
Serial.print(Probability[i] * USECPERTICK, DEC);
Serial.print(F(" , "));
Serial.print(Temporary[i] , DEC);
Serial.print(F(" ), "));
}
}
Serial.print(F(" times. (in RAW_BIT_MARK)"));
#endif
byte rawTemp = 0;
byte Bits_Count = 0;
MAX_RAW_ZERO_SPACE = (IR_RAW.RAW_ONE_SPACE + IR_RAW.RAW_ZERO_SPACE) / 2;
for (int i = 4; i < results->rawlen; i+=2) {
Bits_Count++;
rawTemp = rawTemp << 1;
if (results->rawbuf[i] > MAX_RAW_ZERO_SPACE) rawTemp = rawTemp | 1;
if (Bits_Count==8) {
IR_RAW.rawData[IR_RAW.rawData_Count] = rawTemp;
Bits_Count = 0;
IR_RAW.rawData_Count ++;
rawTemp = 0;
}
}
if (Bits_Count != 0) {
for (byte i = (Bits_Count+1); i <= 8; i++) {
rawTemp = rawTemp << 1;
}
IR_RAW.rawData[IR_RAW.rawData_Count] = rawTemp;
IR_RAW.rawData_Count ++;
}
byte Max_rawHole = sizeof(IR_RAW.rawHole)/sizeof(unsigned int)/3;
for (int i = 3; i < results->rawlen-1; i++) {
if(i%2==1){
if (!((results->rawbuf[i]>=IR_RAW.RAW_BIT_MARK-Tolerance_scope) && (results->rawbuf[i]<=IR_RAW.RAW_BIT_MARK+Tolerance_scope))) {
if (IR_RAW.rawHole_Count >= Max_rawHole) {
results->overflow = true;
break;
}
IR_RAW.rawHole[IR_RAW.rawHole_Count][0] = (i-3)/2;
IR_RAW.rawHole[IR_RAW.rawHole_Count][1] = results->rawbuf[i] * USECPERTICK;
IR_RAW.rawHole[IR_RAW.rawHole_Count][2] = results->rawbuf[i+1] * USECPERTICK;
IR_RAW.rawHole_Count++;
i++;
}
} else {
if (results->rawbuf[i]>(IR_RAW.RAW_ONE_SPACE + Tolerance_scope)) {
if (IR_RAW.rawHole_Count >= Max_rawHole) {
results->overflow = true;
break;
}
IR_RAW.rawHole[IR_RAW.rawHole_Count][0] = (i-4)/2;
IR_RAW.rawHole[IR_RAW.rawHole_Count][1] = results->rawbuf[i-1] * USECPERTICK;
IR_RAW.rawHole[IR_RAW.rawHole_Count][2] = results->rawbuf[i] * USECPERTICK;
IR_RAW.rawHole_Count++;
}
}
}
IR_RAW.RAW_HDR_MARK = IR_RAW.RAW_HDR_MARK * USECPERTICK - MARK_EXCESS/MARK_EXCESS_Factor;
IR_RAW.RAW_HDR_SPACE = IR_RAW.RAW_HDR_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor;
IR_RAW.RAW_BIT_MARK = IR_RAW.RAW_BIT_MARK * USECPERTICK - MARK_EXCESS/MARK_EXCESS_Factor;
IR_RAW.RAW_ONE_SPACE = IR_RAW.RAW_ONE_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor;
IR_RAW.RAW_ZERO_SPACE = IR_RAW.RAW_ZERO_SPACE * USECPERTICK + MARK_EXCESS/MARK_EXCESS_Factor;
}
#ifdef MPG_DEBUG
Serial.println(F(""));
Serial.println(F(""));
Serial.print(F("int rawData_Bits = "));
Serial.print(IR_RAW.rawData_Bits, DEC);
Serial.print(F(" ;"));
Serial.println(F(""));
Serial.print(F("byte rawData["));
Serial.print(IR_RAW.rawData_Count, DEC);
Serial.print(F("] = { "));
for (byte i = 0; i < IR_RAW.rawData_Count; i++) {
Serial.print(F("0x"));
Serial.print(IR_RAW.rawData[i], HEX);
if ( i < IR_RAW.rawData_Count-1 ) Serial.print(F(", "));
}
Serial.println(F(" };"));
Serial.print(F("unsigned int rawHole["));
Serial.print(IR_RAW.rawHole_Count, DEC);
Serial.print(F("][3] = { "));
for (byte i = 0; i < IR_RAW.rawHole_Count; i++) {
Serial.print(F("{ "));
for (byte j = 0; j < 3; j++) {
Serial.print(IR_RAW.rawHole[i][j], DEC);
if ( j < 2 ) Serial.print(F(", "));
}
Serial.print(F(" } "));
if ( i < IR_RAW.rawHole_Count-1 ) Serial.print(F(", "));
}
Serial.println(F("};"));
Serial.println(F(""));
Serial.println(F("// My Data End --------------- By MGP."));
Serial.println(F(""));
#endif
}
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
SetupIndex = 0;
IR_RAW.rawData_Count = 0;
if ((EEPROM.read(1022) != IR_NUM_SIZE) || (EEPROM.read(1023) != sizeof(IR_RAW))) {
Serial.println(F("Wait for initial EEPROM ..."));
for(int i =0; i<1022; i++) EEPROM.write(i,0);
EEPROM.write(1022,IR_NUM_SIZE);
EEPROM.write(1023,sizeof(IR_RAW));
}
pinMode(Pin9_SW, INPUT);
pinMode(Recv_Enable_LED_Pin, OUTPUT);
pinMode(LED_Buzzer_Pin, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(Recv_Enable_LED_Pin, HIGH);
digitalWrite(LED_Buzzer_Pin, LOW);
digitalWrite(13, LOW);
ST_LED_Buzzer (1);
Serial.println(F("MPG IR-Translator is Ready."));
}
void loop() {
#ifdef MPG_SOLDER
if (digitalRead(Pin9_SW) == LOW) {
Serial.println(sizeof(IR_RAW));
delay(100);
ST_LED_Buzzer (1);
RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
irrecv.enableIRIn();
delay(100);
}
#endif
if (irrecv.decode(&results)) {
IR_MAP_Index = IR_NUM_SIZE;
if (results.decode_type == NEC) {
#ifdef MPG_DEBUG
Serial.print(F("NEC Code : "));
Serial.print(results.value, HEX);
#endif
for (byte i = 0; i < IR_NUM_SIZE; i++) {
if (results.value == IR_MAP[i].IR_CODE) {
IR_MAP_Index = IR_MAP[i].INDEX_NUM;
break;
}
}
#ifdef MPG_DEBUG
Serial.print(F(" Map Index : "));
Serial.println(IR_MAP_Index, DEC);
#endif
if (IR_MAP_Index < IR_NUM_SIZE) {
delay(100);
switch (IR_MAP_Index) {
case 0:
if(EnterSetup) {
ST_LED_Buzzer (10);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 1:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 2:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 3:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 4:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 5:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 6:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 7:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 8:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 9:
if(EnterSetup) {
ST_LED_Buzzer (IR_MAP_Index);
SetupIndex = IR_MAP_Index;
} else {
#ifdef MPG_SendHit
ST_LED_Buzzer (1);
#endif
EEPROM_readAnything(IR_MAP_Index*sizeof(IR_RAW), IR_RAW);
if (IR_RAW.RAW_TYPE == SONY) SONYIRSend(IR_RAW.rawData, IR_RAW.rawData_Bits);
else RAWIRSend(IR_RAW.rawData, IR_RAW.rawData_Count, IR_RAW.rawData_Bits, khz);
#ifdef MPG_DEBUG
show_RAW_IR();
#endif
}
break;
case 10:
if(EnterSetup) {
ST_LED_Buzzer (20);
EnterSetup = false;
} else {
ST_LED_Buzzer (15);
EnterSetup = true;
}
break;
}
irrecv.enableIRIn();
}
}
if (IR_MAP_Index == IR_NUM_SIZE) {
if(EnterSetup) {
if (results.overflow) {
#ifdef MPG_DEBUG
dumpInfo(&results);
dumpRaw(&results);
show_RAW_IR();
#endif
} else {
#ifdef MPG_DEBUG
dumpInfo(&results);
dumpRaw(&results);
#endif
EncodeRAWCode(&results);
if ((IR_RAW.RAW_BIT_MARK >0) && (IR_RAW.RAW_ONE_SPACE >0) && (IR_RAW.RAW_ZERO_SPACE >0) && (results.overflow == false)) {
EEPROM_writeAnything(SetupIndex*sizeof(IR_RAW), IR_RAW);
ST_LED_Buzzer(2);
}
}
}
}
irrecv.resume();
delay(100);
}
}
template <class T> int EEPROM_writeAnything(int ee, const T& value) {
const byte* p = (const byte*)(const void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value) {
byte* p = (byte*)(void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
void show_RAW_IR(){
Serial.println(F(""));
Serial.println(F("// My Data Start , Mark & Ctrl-C Copy ---------------"));
Serial.println(F(""));
Serial.print(F("#define RAW_HDR_MARK "));
Serial.print(IR_RAW.RAW_HDR_MARK, DEC);
Serial.println(F(""));
Serial.print(F("#define RAW_HDR_SPACE "));
Serial.print(IR_RAW.RAW_HDR_SPACE, DEC);
Serial.println(F(""));
Serial.print(F("#define RAW_BIT_MARK "));
Serial.print(IR_RAW.RAW_BIT_MARK, DEC);
Serial.print(F(" // "));
Serial.print(Probability[0] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[0] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[1] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[1] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[2] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[2] , DEC);
Serial.print(F(" times."));
Serial.println(F(""));
Serial.print(F("#define RAW_ONE_SPACE "));
Serial.print(IR_RAW.RAW_ONE_SPACE, DEC);
Serial.print(F(" // "));
Serial.print(Probability[0] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[0] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[1] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[1] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[2] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[2] , DEC);
Serial.print(F(" times."));
Serial.println(F(""));
Serial.print(F("#define RAW_ZERO_SPACE "));
Serial.print(IR_RAW.RAW_ZERO_SPACE, DEC);
Serial.print(F(" // "));
Serial.print(Probability[0] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[0] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[1] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[1] , DEC);
Serial.print(F(" times. "));
Serial.print(Probability[2] * USECPERTICK, DEC);
Serial.print(F(" -> "));
Serial.print(Temporary[2] , DEC);
Serial.print(F(" times."));
Serial.println(F(""));
Serial.println(F(""));
Serial.print(F("int rawData_Bits = "));
Serial.print(IR_RAW.rawData_Bits, DEC);
Serial.print(F(" ;"));
Serial.println(F(""));
Serial.print(F("byte rawData["));
Serial.print(IR_RAW.rawData_Count, DEC);
Serial.print(F("] = { "));
for (byte i = 0; i < IR_RAW.rawData_Count; i++) {
Serial.print(F("0x"));
Serial.print(IR_RAW.rawData[i], HEX);
if ( i < IR_RAW.rawData_Count-1 ) Serial.print(F(", "));
}
Serial.println(F(" };"));
Serial.print(F("unsigned int rawHole["));
Serial.print(IR_RAW.rawHole_Count, DEC);
Serial.print(F("][3] = { "));
for (byte i = 0; i < IR_RAW.rawHole_Count; i++) {
Serial.print(F("{ "));
for (byte j = 0; j < 3; j++) {
Serial.print(IR_RAW.rawHole[i][j], DEC);
if ( j < 2 ) Serial.print(F(", "));
}
Serial.print(F(" } "));
if ( i < IR_RAW.rawHole_Count-1 ) Serial.print(F(", "));
}
Serial.println(F("};"));
Serial.println(F(""));
Serial.println(F("// My Data End --------------- By MGP."));
Serial.println(F(""));
Serial.println(F(""));
}
void encoding (decode_results *results)
{
switch (results->decode_type) {
default:
case UNKNOWN: Serial.print(F("UNKNOWN")); break ;
case NEC: Serial.print(F("NEC")); break ;
case SONY: Serial.print(F("SONY")); break ;
case RC5: Serial.print(F("RC5")); break ;
case RC6: Serial.print(F("RC6")); break ;
case DISH: Serial.print(F("DISH")); break ;
case SHARP: Serial.print(F("SHARP")); break ;
case JVC: Serial.print(F("JVC")); break ;
case SANYO: Serial.print(F("SANYO")); break ;
case MITSUBISHI: Serial.print(F("MITSUBISHI")); break ;
case SAMSUNG: Serial.print(F("SAMSUNG")); break ;
case LG: Serial.print(F("LG")); break ;
case WHYNTER: Serial.print(F("WHYNTER")); break ;
case AIWA_RC_T501: Serial.print(F("AIWA_RC_T501")); break ;
case PANASONIC: Serial.print(F("PANASONIC")); break ;
case DENON: Serial.print(F("Denon")); break ;
}
}
void ircode (decode_results *results)
{
if (results->decode_type == PANASONIC) {
Serial.print(results->address, HEX);
Serial.print(F(":"));
}
Serial.print(results->value, HEX);
}
void dumpInfo(decode_results *results)
{
if (results->overflow) {
Serial.println(F("IR code too long. Edit IRremoteInt.h and increase RAWBUF"));
return;
}
Serial.print(F("Encoding : "));
encoding(results);
Serial.println(F(""));
Serial.print(F("Code : "));
ircode(results);
Serial.print(F(" ("));
Serial.print(results->bits, DEC);
Serial.println(F(" bits)"));
}
void dumpRaw (decode_results *results)
{
Serial.print("Timing[");
Serial.print(results->rawlen-1, DEC);
Serial.println("]: ");
for (int i = 1; i < results->rawlen; i++) {
unsigned long x = results->rawbuf[i] * USECPERTICK;
if (!(i & 1)) {
Serial.print("-");
if (x < 1000) Serial.print(" ") ;
if (x < 100) Serial.print(" ") ;
Serial.print(x, DEC);
} else {
Serial.print(" ");
Serial.print("+");
if (x < 1000) Serial.print(" ") ;
if (x < 100) Serial.print(" ") ;
Serial.print(x, DEC);
if (i < results->rawlen-1) Serial.print(", ");
}
if (!(i % 8)) Serial.println("");
}
Serial.println("");
}
使用於本製作內容的小米萬能遙控器是一代,後續有二代增強版、搭配小愛同學的版本等,介面會有所不同,若無創維機上盒的選項,可用長虹電視代替,可將 45-55 行替換如下,再上傳至晶片
A. 請將上方程式 24-25 行左方的雙斜線拿掉,將程式上傳至晶片進入除錯模式
B. 選取米家APP內萬能遙控器中任一牌電視測試(按任一鍵均可),若此電視遙控器是NEC編碼的,在Arduino IDE監控視窗內會出現編碼代號,若無請更換其它牌電視繼續測試
C. 找到的話請依序記錄 "0~9 確定" 共11個鍵的NEC編碼代號替換 45-55 行編碼代號 (0x 之後的16進位數字)
D. 加回 24-25 行的雙斜線,將程式上傳至晶片即完成