/* Retransmit B.M.C. CS2 Amp IR multicontroller code as Pioneer D6 * or DV-656A or SqueezeBox Touch or Sony MiniDisc or Samsung TV * and TOSLINK input selector * IR code depending on value of variable 'transport' * Pioneer D6 remote can also control the CS2 amp * * beta 0.21-2019 Hans R Lønningdal http://snw.lonningdal.no * Known issue - IR transmitter diode used are very directional * * Using Ken Shirriff's IRremote Library * http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html * */ #include //https://github.com/z3t0/Arduino-IRremote #define DBUG; // comment out this line for production code. DEBUG already taken by Ken :) #ifdef DBUG #define SP(x) Serial.print (x) #define SPLN(x) Serial.println (x) #define SPHEX(x) Serial.print ("0x"); Serial.println (x, HEX) #else #define SP(x) #define SPLN(x) #define SPHEX(x) #endif unsigned int RECV_PIN = 11; unsigned int STATUS_PIN = 13; IRrecv irrecv(RECV_PIN); IRsend irsend; decode_results results; // results from received IR code unsigned long newvalue; // IR code to transmit unsigned long buttonbefore; // remember last reseived button IR code value unsigned int device = 0; // used to define special feature for the remote send options unsigned int onetofour = 1; // using up/down for direct 1-4 selection on optical input selector unsigned int transport = 1; // BMC CD PROG button alter this value const unsigned int CD = 1; // Pioneer PD D6-MK2 SACD transport const unsigned int SB = 2; // SqueezeBox Touch const unsigned int MD = 3; // Sony MDE-JE770 MiniDisc const unsigned int DAC = 4; // DAC controls used to control TOSLINK selector const unsigned int TV = 5; // Samsung TV (2016) UE60KS7005 const unsigned int DV = 6; // Pioneer DV-656A DVD Audio / CD transport const unsigned int AMP = 7; // B.M.C. CS2 amp void transportStatus(unsigned int activeLED) { // adjust for digital pins used to visualize transport status for (int i = 4; i <= 6; i++) { digitalWrite(i, LOW); } digitalWrite(activeLED + 3, HIGH); } void sendCode(unsigned long button) { digitalWrite(13, HIGH); // Arduino LED // handle repeats from B.M.C. & many others. Needed as DV-656A don't // use repeat code but prefix command code with a fixed 32-bit value if (button == 0xFFFFFFFF) { // we don't want to increment Up/Down input selector for // DAC device so we keep repeat code as is // luckely the optical selector use this repeat code if (device != DAC) {button = buttonbefore;} } else { buttonbefore = button; } device = 0; // 'transport' is default CD=1, new users should test with this branch, or change 'transport' value if (transport == CD) { // verified with Pioneer D6-MK2 SACD player switch (button) { case 0x618650AF: newvalue = 0x45BA38C7; device = CD; SPLN("Power"); break; // Pioneer D6 Power (CD DISP) case 0x6186708F: newvalue = 0x45BA8A75; device = CD; SPLN("Tray"); break; // Pioneer D6 Tray (CD REP) case 0x618610EF: newvalue = 0x45BAE817; device = CD; SPLN("Play"); break; // Pioneer D6 Play case 0x6186906F: newvalue = 0x45BA6897; device = CD; SPLN("Stop"); break; // Pioneer D6 Stop case 0x618630CF: newvalue = 0x45BA708F; device = CD; SPLN("FFW"); break; // Pioneer D6 Fast Forward case 0x6186B04F: newvalue = 0x45BAF00F; device = CD; SPLN("FRW"); break; // Pioneer D6 Fast Rewind case 0x618620DF: newvalue = 0x45BA8877; device = CD; SPLN("Prew"); break; // Pioneer D6 Prew case 0x618600FF: newvalue = 0x45BA08F7; device = CD; SPLN("Next"); break; // Pioneer D6 Next case 0x618648B7: newvalue = 0x45BA807F; device = CD; SPLN("1"); break; // Pioneer D6 1 case 0x6186C837: newvalue = 0x45BA40BF; device = CD; SPLN("2"); break; // Pioneer D6 2 case 0x61868877: newvalue = 0x45BAC03F; device = CD; SPLN("3"); break; // Pioneer D6 3 case 0x618608F7: newvalue = 0x45BA20DF; device = CD; SPLN("4"); break; // Pioneer D6 4 case 0x6186F00F: newvalue = 0x45BAA05F; device = CD; SPLN("5"); break; // Pioneer D6 5 case 0x618618E7: newvalue = 0x45BA609F; device = CD; SPLN("6"); break; // Pioneer D6 6 case 0x6186E817: newvalue = 0x45BAE01F; device = CD; SPLN("7"); break; // Pioneer D6 7 case 0x618628D7: newvalue = 0x45BA10EF; device = CD; SPLN("8"); break; // Pioneer D6 8 case 0x6186A857: newvalue = 0x45BA906F; device = CD; SPLN("9"); break; // Pioneer D6 9 case 0x61866897: newvalue = 0x45BA00FF; device = CD; SPLN("0"); break; // Pioneer D6 0 case 0x618658A7: newvalue = 0x45BA18E7; device = CD; SPLN("Pause"); break; // Pioneer D6 Pause (CD CHECK) case 0x61869867: newvalue = 0x45BAA25D; device = CD; SPLN("Clear"); break; // Pioneer D6 Clear } } if (transport == SB) { // verified with SqueezeBox Touch - NEC 32-bit, first 4 digits 0x7689#### are // device/manufactor idetifier, or 16-bit pre-data as it called in lirc's database switch (button) { // https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/remotes/slim_devices/Squeezebox3.lircd.conf case 0x618650AF: newvalue = 0x76897887; device = SB; SPLN("Display"); break; // SqueezeBox Display Now Playing case 0x6186708F: newvalue = 0x768938C7; device = SB; SPLN("Repeat"); break; // SqueezeBox Repeat case 0x618610EF: newvalue = 0x768910EF; device = SB; SPLN("Play"); break; // SqueezeBox Play (will power on the Touch) case 0x6186906F: newvalue = 0x768920DF; device = SB; SPLN("Stop"); break; // SqueezeBox Stop (actually Pause) case 0x618630CF: newvalue = 0x7689A05F; device = SB; SPLN("FFW"); break; // SqueezeBox Fast Forward case 0x6186B04F: newvalue = 0x7689C03F; device = SB; SPLN("FRW"); break; // SqueezeBox Fast Rewind case 0x618620DF: newvalue = 0x7689C03F; device = SB; SPLN("Prew"); break; // SqueezeBox Prew case 0x618600FF: newvalue = 0x7689A05F; device = SB; SPLN("Next"); break; // SqueezeBox Next case 0x618648B7: newvalue = 0x7689F00F; device = SB; SPLN("1"); break; // SqueezeBox 1 case 0x6186C837: newvalue = 0x768908F7; device = SB; SPLN("2"); break; // SqueezeBox 2 case 0x61868877: newvalue = 0x76898877; device = SB; SPLN("3"); break; // SqueezeBox 3 case 0x618608F7: newvalue = 0x768948B7; device = SB; SPLN("4"); break; // SqueezeBox 4 case 0x6186F00F: newvalue = 0x7689C837; device = SB; SPLN("5"); break; // SqueezeBox 5 case 0x618618E7: newvalue = 0x768928D7; device = SB; SPLN("6"); break; // SqueezeBox 6 case 0x6186E817: newvalue = 0x7689A857; device = SB; SPLN("7"); break; // SqueezeBox 7 case 0x618628D7: newvalue = 0x76896897; device = SB; SPLN("8"); break; // SqueezeBox 8 case 0x6186A857: newvalue = 0x7689E817; device = SB; SPLN("9"); break; // SqueezeBox 9 case 0x61866897: newvalue = 0x76899867; device = SB; SPLN("0"); break; // SqueezeBox 0 case 0x618658A7: newvalue = 0x768940BF; device = SB; SPLN("Power"); break; // SqueezeBox Power (CD CHECK) case 0x61869867: newvalue = 0x768922DD; device = SB; SPLN("Home"); break; // SqueezeBox Home (CD CLEAR) } } if (transport == MD) { // not verified - IR codes from Sony MDE-JE770 remote switch (button) { case 0x618650AF: newvalue = 0xA9E; device = MD; SPLN("Power"); break; // Sony Power case 0x6186708F: newvalue = 0x69E; device = MD; SPLN("Tray"); break; // Sony Tray case 0x618610EF: newvalue = 0x55E; device = MD; SPLN("Play"); break; // Sony Play case 0x6186906F: newvalue = 0x15E; device = MD; SPLN("Stop"); break; // Sony Stop case 0x618630CF: newvalue = 0x35E; device = MD; SPLN("FFW"); break; // Sony Fast Forward case 0x6186B04F: newvalue = 0xD5E; device = MD; SPLN("FRW"); break; // Sony Fast Rewind case 0x618620DF: newvalue = 0x5E; device = MD; SPLN("Prew"); break; // Sony Prew case 0x618600FF: newvalue = 0x85E; device = MD; SPLN("Next"); break; // Sony Next case 0x618648B7: newvalue = 0x1E; device = MD; SPLN("1"); break; // Sony 1 case 0x6186C837: newvalue = 0x81E; device = MD; SPLN("2"); break; // Sony 2 case 0x61868877: newvalue = 0x41E; device = MD; SPLN("3"); break; // Sony 3 case 0x618608F7: newvalue = 0xC1E; device = MD; SPLN("4"); break; // Sony 4 case 0x6186F00F: newvalue = 0x21E; device = MD; SPLN("5"); break; // Sony 5 case 0x618618E7: newvalue = 0xA1E; device = MD; SPLN("6"); break; // Sony 6 case 0x6186E817: newvalue = 0x61E; device = MD; SPLN("7"); break; // Sony 7 case 0x618628D7: newvalue = 0xE1E; device = MD; SPLN("8"); break; // Sony 8 case 0x6186A857: newvalue = 0x11E; device = MD; SPLN("9"); break; // Sony 9 case 0x61866897: newvalue = 0x91E; device = MD; SPLN("0"); break; // Sony 0 case 0x618658A7: newvalue = 0x95E; device = MD; SPLN("Pause"); break; // Sony Pause (CD CHECK) case 0x61869867: newvalue = 0xF1E; device = MD; SPLN("Clear"); break; // Sony Clear (CD CLEAR) } } if (transport == DV) { // verified with Pioneer DV-656A DVD Audio / CD transport switch (button) { case 0x618650AF: newvalue = 0xF50A3DC2; device = DV; SPLN("Power"); break; // DV-656A Power (CD DISP) case 0x6186708F: newvalue = 0xF50A6D92; device = DV; SPLN("Tray"); break; // DV-656A Tray (CD REP) case 0x618610EF: newvalue = 0xC53A7986; device = DV; SPLN("Play"); break; // DV-656A Play case 0x6186906F: newvalue = 0xC53A19E6; device = DV; SPLN("Stop"); break; // DV-656A Stop case 0x618630CF: newvalue = 0xF50A9768; device = DV; SPLN("FFW"); break; // DV-656A Fast Forward case 0x6186B04F: newvalue = 0xF50A57A8; device = DV; SPLN("FRW"); break; // DV-656A Fast Rewind case 0x618620DF: newvalue = 0xC53AB946; device = DV; SPLN("Prew"); break; // DV-656A Prew case 0x618600FF: newvalue = 0xC53A39C6; device = DV; SPLN("Next"); break; // DV-656A Next case 0x618648B7: newvalue = 0xF50A857A; device = DV; SPLN("1"); break; // DV-656A 1 case 0x6186C837: newvalue = 0xF50A45BA; device = DV; SPLN("2"); break; // DV-656A 2 case 0x61868877: newvalue = 0xF50AC53A; device = DV; SPLN("3"); break; // DV-656A 3 case 0x618608F7: newvalue = 0xF50A25DA; device = DV; SPLN("4"); break; // DV-656A 4 case 0x6186F00F: newvalue = 0xF50AA55A; device = DV; SPLN("5"); break; // DV-656A 5 case 0x618618E7: newvalue = 0xF50A659A; device = DV; SPLN("6"); break; // DV-656A 6 case 0x6186E817: newvalue = 0xF50AE51A; device = DV; SPLN("7"); break; // DV-656A 7 case 0x618628D7: newvalue = 0xF50A15EA; device = DV; SPLN("8"); break; // DV-656A 8 case 0x6186A857: newvalue = 0xF50A956A; device = DV; SPLN("9"); break; // DV-656A 9 case 0x61866897: newvalue = 0xF50A05FA; device = DV; SPLN("0"); break; // DV-656A 0 case 0x618658A7: newvalue = 0xC53AF906; device = DV; SPLN("Pause"); break;// DV-656A Pause (CD CHECK) case 0x61869867: newvalue = 0x0; device = 0; SPLN(" "); break; // CD CLEAR - device=0 ensure nothing is transmitet } } if (transport == TV) { // Samsung TV using generic codes, this 2016 model comes with Bluetooth remote switch (button) { // https://sourceforge.net/p/lirc-remotes/code/ci/master/tree/remotes/samsung/BN59-00856A.lircd.conf case 0x618650AF: newvalue = 0xE0E040BF; device = TV; SPLN("Power"); break; // SqueezeBox Power } } /*-- DAC secton of B.M.C. remote --*/ switch (button) { case 0x8666609F: // DAC DF newvalue = 0x0; // device = 0x0; //device = DAC; SPLN("DAC DF"); break; case 0x8666619E: // DAC OVS newvalue = newvalue = 0xE0E0D02F; // Samsung TV - Volume Ned device = TV; SPLN("DAC OVS"); break; case 0x8666629D: // DAC UPS newvalue = newvalue = 0xE0E0E01F; // Samsung TV - Volume Opp device = TV; SPLN("DAC UPS"); break; case 0x86662AD5: // DAC IN UP if (newvalue != 0xFFFFFFFF ) {onetofour++;} if (onetofour >= 5) {onetofour = 1;} if (onetofour == 1) {newvalue = 0x1FE807F;} // Optical Selector 1 if (onetofour == 2) {newvalue = 0x1FE20DF;} // Optical Selector 2 if (onetofour == 3) {newvalue = 0x1FEE01F;} // Optical Selector 3 if (onetofour == 4) {newvalue = 0x1FE50AF;} // Optical Selector 4 device = DAC; #ifdef DBUG SPLN("DAC Input Down"); SP("onetofour = "); SPLN(onetofour); #endif break; case 0x8666AA55: // DAC IN DOWN if (newvalue != 0xFFFFFFFF) {onetofour--;} if (onetofour <= 0) {onetofour = 4;} if (onetofour == 1) {newvalue = 0x1FE807F;} // Optical Selector 1 if (onetofour == 2) {newvalue = 0x1FE20DF;} // Optical Selector 2 if (onetofour == 3) {newvalue = 0x1FEE01F;} // Optical Selector 3 if (onetofour == 4) {newvalue = 0x1FE50AF;} // Optical Selector 4 device = DAC; #ifdef DBUG SPLN("DAC Input Down"); SP("onetofour = "); SPLN(onetofour); #endif break; case 0x8666728D: // DAC MUTE newvalue = 0x1FE58A7; // Optical Selector On/Off device = DAC; SPLN("DAC MUTE"); break; case 0x866640BF: // DAC VOL UP newvalue = 0x0; // Optical Selector device = DAC; SPLN("DAC VOL UP"); break; case 0x866641BE: // DAC VOL DOWN newvalue = 0x0; // Optical Selector device = DAC; SPLN("DAC VOL DOWN"); break; /*-- B.M.C. CD PROGRAM button used to alter internal tranport value --*/ case 0x6186D02F: transport++; if (transport >= 6) {transport = 1;} // DV-656A left out for now transportStatus(transport); delay(200); // dirty way to supress repeats SPLN("CD Program"); SP("transport = "); SPLN(transport); break; /*-- Control B.M.C. from Pioneer D6 remote - verified --*/ case 0xA55A50AF: newvalue = 0x866602FD; // Volume Up device = AMP; break; case 0xA55AD02F: newvalue = 0x8666827D; // Volume Down device = AMP; break; case 0xA55A48B7: newvalue = 0x8666A659; // Mute device = AMP; break; /*-- Pioneer D6 remote Amp Power button used to alter Input Up selector on B.M.C. CS2 --*/ case 0xA55A38C7: delay(200); newvalue = 0x8666C639; // B.M.C. CS2 Input Up will start ower from Phono 1 after XRL 2 device = AMP; break; } // end switch // finaly we're ready to send new IR code if (device >= 1) { switch (device) { case CD: irsend.sendNEC(newvalue, 32); break; // Pioneer D6 use NEC 32-bit and quicly repeats the same code case AMP: irsend.sendNEC(newvalue, 32); irsend.sendNEC(0xFFFFFFFF, 32); break; // B.M.C. use NEC 32-bit and seem to prefer at a fixed 32-bit repeat command at the end case DV: irsend.sendNEC(0xC53A9966, 32); irsend.sendNEC(newvalue, 32); break; // DV-656A use NEC 32-bit with the 32-bit prefix 0xC53A9966 case DAC: irsend.sendNEC(newvalue, 32); break; // S/P DIF Optical Selector use NEC 32 bit case SB: irsend.sendNEC(newvalue, 32); delay(5); // SB Touch seem to like a couple irsend.sendNEC(newvalue, 32); delay(5); // of repeats to give solid response irsend.sendNEC(newvalue, 32); break; // case MD: irsend.sendSony(newvalue, 12); break; // Sony MD use Sony 12-bit - not verified case TV: irsend.sendNEC(newvalue, 32); // Samsung TV (2016) actually comes with Bluetooth Smart Control delay(3); break; // need several repeats of the same code but seems more reliable with a short delay } #ifdef DBUG SP("Code sent: "); SPHEX(newvalue); } else { SPLN("This code not registered with any device."); #endif } digitalWrite(13, LOW); irrecv.enableIRIn(); } void encoding (int type) { switch (type) { default: case UNKNOWN: SP("UNKNOWN"); break ; case NEC: SP("NEC"); break ; case SONY: SP("SONY"); break ; case RC5: SP("RC5"); break ; case RC6: SP("RC6"); break ; case DISH: SP("DISH"); break ; case SHARP: SP("SHARP"); break ; case JVC: SP("JVC"); break ; case SANYO: SP("SANYO"); break ; case MITSUBISHI: SP("MITSUBISHI"); break ; case SAMSUNG: SP("SAMSUNG"); break ; case LG: SP("LG"); break ; case WHYNTER: SP("WHYNTER"); break ; case AIWA_RC_T501: SP("AIWA_RC_T501"); break ; case PANASONIC: SP("PANASONIC"); break ; case DENON: SP("Denon"); break ; } SP(" "); } void setup() { #ifdef DBUG Serial.begin(115200); while (!Serial); #endif irrecv.enableIRIn(); // Start the receiver } void loop() { newvalue = 0x0; if (irrecv.decode(&results)) { newvalue = results.value; #ifdef DBUG // Check if the buffer overflowed if (results.overflow) { SPLN("IR code too long. Edit IRremoteInt.h and increase RAWBUF"); return; } encoding(results.decode_type); SP(results.bits); SP("-bits"); SP(" "); if(results.address > 0x0){SPHEX(results.address); SP(" ");} SPHEX(newvalue); #endif irrecv.resume(); // Receive the next value } if (newvalue > 0x0) { //SPLN("Call sendCode"); sendCode(newvalue); } } /* Circuit * IR receiver output to pin 11, 5V and ground * IR LED transmiter anode to 100R resistor, other end of resistor to pin 3, IR LED cathode to ground */