Post by jd on May 1, 2020 3:00:12 GMT
Did a really convenient mod of my NSM Grand Performer 2000. Thought I'd share. I was able to fairly easily make a custom remote control system. Juke model doesn't really matter so long as what you want to control can be done by relays. I tried to upload photos, but they would not attach even though they are less than 1Mb.
NSM had a factory remote package, but I didn't like the limited features. I wanted Volume Up/Down, Reject, Service Mode On/Off, Display Page Left/Right, and Bluetooth Module Power On/Off. That used 7 of the 8 relays in my block. Bluetooth power and service mode required the relays to latch, the others were momentary on my remote button push.
I installed an outlet that was switched on with the main juke power. Plugged in an old I-phone charger for a low noise 5V power supply. Bought a $3 IR sensor that came with a generic membrane remote off amazon. Got an 8 relay block for $10 with 5V coils, and an Arduino Uno microcontroller which was probably around $15. All connections were made with generic pinheader cables so there was not much effort required in wiring the relay block or IR sensor to the microcontroller. Most of the work was in mounting and wiring the relay block to the jukebox.
Mounted the remote sensor within the display board of my NSM. It is invisible behind the red plexiglass. You can see it has a tiny LED that lights when actuated, but it doesn't block any of the digits. Used this page for instructions; www.circuitbasics.com/arduino-ir-remote-receiver-tutorial/
Two key steps, neither are too hard: 1) need to find, download, and add the IRremote library to the Arduino software that will include a ".h" and a ".cpp"file. 2) Need to decode your remote. I was able to directly copy/paste code from this site and open the serial monitor in the Arduino software such that I could read the hexidecimal codes each button produced from my remote off the computer screen. Then customized the program to perform what actions I wanted when the buttons of interest were pressed. Below was my final code. Note I left the numerals on my remote in my code, but they do not currently do anything. The magic for each button occurs between "case" and "break". Also note DigitalWrite...LOW = ON and DigitalWrite...HIGH = OFF. Momentary relays turn on with their button presses and off 100 millisecs after the button is released. My code uses a true/false bit to track the on/off state of the latching relays and a true/false one time action trip bit to track if the button action has already been performed during the current button press (prevents the relay from cycling on and off while the button is held). This trip resets 100 millisecs after the button is released. Latching code basically says "if you are on, turn off and if your are off, turn on but only if you have not yet performed an action this button press". "Millis()" is the system clock so setting my "timer" variable = millis() provides the timestamp of when the button press occured. The difference afterwards millis() - timer is the time that has elapsed in milliseconds since the button was released.
#include <IRremote.h>
const int RECV_PIN = 7; //pin where the IR sensor signal goes
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
unsigned long int timer = 0;
boolean bttrip = false;
boolean btpwr = false;
boolean servtrip = false;
boolean servpwr = false;
//my relay block pin assignments
int bt = 2; //bluetooth relay
int pagel = 3; //page left relay
int pager = 4; //page right relay
int serv = 5; //service mode relay
int volup = 6; //volume up relay
int voldwn = 8; //volume down relay
int rej = 9; //reject relay
void setup(){
irrecv.enableIRIn();
irrecv.blink13(true);
pinMode(bt, OUTPUT);
pinMode(pagel, OUTPUT);
pinMode(pager, OUTPUT);
pinMode(serv, OUTPUT);
pinMode(volup, OUTPUT);
pinMode(voldwn, OUTPUT);
pinMode(rej, OUTPUT);
digitalWrite(bt,HIGH);
digitalWrite(pagel,HIGH);
digitalWrite(pager,HIGH);
digitalWrite(serv,HIGH);
digitalWrite(volup,HIGH);
digitalWrite(voldwn,HIGH);
digitalWrite(rej,HIGH);
}
void loop(){
if (irrecv.decode(&results)){
if (results.value == 0XFFFFFFFF)
results.value = key_value;
switch(results.value){
case 0xFFA25D:
//Serial.println("1");
break;
case 0xFF629D:
//Serial.println("2");
break;
case 0xFFE21D:
//Serial.println("3");
break;
case 0xFF22DD:
//Serial.println("4");
break;
case 0xFF02FD:
//Serial.println("5");
break ;
case 0xFFC23D:
//Serial.println("6");
break ;
case 0xFFE01F:
//Serial.println("7");
break ;
case 0xFFA857:
//Serial.println("8");
break ;
case 0xFF906F:
//Serial.println("9");
break ;
case 0xFF6897: //bluetooth button action (latching)
//Serial.println("*");
if(bttrip == false)
{
if(btpwr == true)
{
digitalWrite(bt,HIGH);
btpwr = false;
}
else
{
digitalWrite(bt,LOW);
btpwr = true;
}
bttrip = true;
}
delay(10);
timer = millis();
break ;
case 0xFF9867:
//Serial.println("0");
break ;
case 0xFFB04F: //reject button action
//Serial.println("#");
digitalWrite(rej,LOW);
delay(10);
timer = millis();
break ;
case 0xFF18E7: //volume up action (momentary)
//Serial.println("UP");
digitalWrite(volup,LOW);
delay(10);
timer = millis();
break ;
case 0xFF10EF: // page left action (momentary)
//Serial.println("LEFT");
digitalWrite(pagel,LOW);
delay(10);
timer = millis();
break ;
case 0xFF38C7:
//Serial.println("OK");
if(servtrip == false)
{
if(servpwr == true)
{
digitalWrite(serv,HIGH);
servpwr = false;
}
else
{
digitalWrite(serv,LOW);
servpwr = true;
}
servtrip = true;
}
delay(10);
timer = millis();
break ;
case 0xFF5AA5: //page right action (momentary)
//Serial.println("RIGHT");
digitalWrite(pager,LOW);
delay(10);
timer = millis();
break ;
case 0xFF4AB5: //volume down action (momentary)
//Serial.println("DOWN");
digitalWrite(voldwn,LOW);
delay(10);
timer = millis();
break ;
}
key_value = results.value;
irrecv.resume();
}
if(millis()-timer > 100) digitalWrite(volup,HIGH); //relay off on 100 millisec timer for momentary button presses
if(millis()-timer > 100) digitalWrite(voldwn,HIGH);
if(millis()-timer > 100) digitalWrite(rej,HIGH);
if(millis()-timer > 100) digitalWrite(pagel,HIGH);
if(millis()-timer > 100) digitalWrite(pager,HIGH);
if(results.value == 0xFF6897)
{ //relay trip reset for latching bluetooth relay function
if(millis()-timer > 100)
{
bttrip = false;
}
} //end BT on/off
if(results.value == 0xFF38C7)
{ //relay trip reset for latching service mode relay function
if(millis()-timer > 100)
{
servtrip = false;
}
} //end SERV on/off
} // end void loop
const int RECV_PIN = 7; //pin where the IR sensor signal goes
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;
unsigned long int timer = 0;
boolean bttrip = false;
boolean btpwr = false;
boolean servtrip = false;
boolean servpwr = false;
//my relay block pin assignments
int bt = 2; //bluetooth relay
int pagel = 3; //page left relay
int pager = 4; //page right relay
int serv = 5; //service mode relay
int volup = 6; //volume up relay
int voldwn = 8; //volume down relay
int rej = 9; //reject relay
void setup(){
irrecv.enableIRIn();
irrecv.blink13(true);
pinMode(bt, OUTPUT);
pinMode(pagel, OUTPUT);
pinMode(pager, OUTPUT);
pinMode(serv, OUTPUT);
pinMode(volup, OUTPUT);
pinMode(voldwn, OUTPUT);
pinMode(rej, OUTPUT);
digitalWrite(bt,HIGH);
digitalWrite(pagel,HIGH);
digitalWrite(pager,HIGH);
digitalWrite(serv,HIGH);
digitalWrite(volup,HIGH);
digitalWrite(voldwn,HIGH);
digitalWrite(rej,HIGH);
}
void loop(){
if (irrecv.decode(&results)){
if (results.value == 0XFFFFFFFF)
results.value = key_value;
switch(results.value){
case 0xFFA25D:
//Serial.println("1");
break;
case 0xFF629D:
//Serial.println("2");
break;
case 0xFFE21D:
//Serial.println("3");
break;
case 0xFF22DD:
//Serial.println("4");
break;
case 0xFF02FD:
//Serial.println("5");
break ;
case 0xFFC23D:
//Serial.println("6");
break ;
case 0xFFE01F:
//Serial.println("7");
break ;
case 0xFFA857:
//Serial.println("8");
break ;
case 0xFF906F:
//Serial.println("9");
break ;
case 0xFF6897: //bluetooth button action (latching)
//Serial.println("*");
if(bttrip == false)
{
if(btpwr == true)
{
digitalWrite(bt,HIGH);
btpwr = false;
}
else
{
digitalWrite(bt,LOW);
btpwr = true;
}
bttrip = true;
}
delay(10);
timer = millis();
break ;
case 0xFF9867:
//Serial.println("0");
break ;
case 0xFFB04F: //reject button action
//Serial.println("#");
digitalWrite(rej,LOW);
delay(10);
timer = millis();
break ;
case 0xFF18E7: //volume up action (momentary)
//Serial.println("UP");
digitalWrite(volup,LOW);
delay(10);
timer = millis();
break ;
case 0xFF10EF: // page left action (momentary)
//Serial.println("LEFT");
digitalWrite(pagel,LOW);
delay(10);
timer = millis();
break ;
case 0xFF38C7:
//Serial.println("OK");
if(servtrip == false)
{
if(servpwr == true)
{
digitalWrite(serv,HIGH);
servpwr = false;
}
else
{
digitalWrite(serv,LOW);
servpwr = true;
}
servtrip = true;
}
delay(10);
timer = millis();
break ;
case 0xFF5AA5: //page right action (momentary)
//Serial.println("RIGHT");
digitalWrite(pager,LOW);
delay(10);
timer = millis();
break ;
case 0xFF4AB5: //volume down action (momentary)
//Serial.println("DOWN");
digitalWrite(voldwn,LOW);
delay(10);
timer = millis();
break ;
}
key_value = results.value;
irrecv.resume();
}
if(millis()-timer > 100) digitalWrite(volup,HIGH); //relay off on 100 millisec timer for momentary button presses
if(millis()-timer > 100) digitalWrite(voldwn,HIGH);
if(millis()-timer > 100) digitalWrite(rej,HIGH);
if(millis()-timer > 100) digitalWrite(pagel,HIGH);
if(millis()-timer > 100) digitalWrite(pager,HIGH);
if(results.value == 0xFF6897)
{ //relay trip reset for latching bluetooth relay function
if(millis()-timer > 100)
{
bttrip = false;
}
} //end BT on/off
if(results.value == 0xFF38C7)
{ //relay trip reset for latching service mode relay function
if(millis()-timer > 100)
{
servtrip = false;
}
} //end SERV on/off
} // end void loop