
The Jackson PT9723 is yet another 433MHz remote power control system. I picked mine up on sale from Officeworks last month, who don’t seem to sell them any more. But they’re still readily available online for a fairly modest price.
I bought it with the intention of controlling it with an Arduino. However, interfacing with it proved to be a little more difficult than most other systems around, and nobody else seems to have done it yet. So here’s how I managed it.
About the remote
The remote handles four separate channels. On the outside, rather than buttons that toggle each channel on or off, the remote has separate on and off buttons for each channel, as well as a 9th button to turn all channels off. On the inside there’s two main parts that we care about.
- A Holtek 7130A-1 power regulator. This takes the 12V from the battery and outputs 3V (at up to 30mA) to power the rest of the circuit. After accidentally hooking this up to my bench supply with the polarity reversed, I can confirm that these operate using really foul-smelling smoke. Luckily we won’t be requiring it any more.
- A Holtek HT46R01T3. This chip combines a small MCU with a 433MHz transmitter. The data sheet specifies an operating voltage of 2V-3.6V, so it’s trivial to power from the 3.3V rail on an Arduino.
Six of the GPIOs from the HT46R01T3 are used. Each button shorts a pair of these GPIOs together to tell the MCU to transmit a command. So to talk to an arduino we break out six GPIO pins, plus two more wires to power the remote.
Parts
As well as an Arduino, we use:
- A shift register. I used a Freetronics EXPAND shift register module.
- 8x NPN transistors. BC549s worked for me. A BC547 or any other equivalent should be fine.
- 8x 150kΩ resistors.
- Some 8-strand ribbon cable, in addition to a handful of other hookup wire.
Hardware hacking
Each command is triggered by shorting two GPIO pins together. The pins used, and the resulting command, look like:
| Pins | 16 | 2 | 13 |
|---|---|---|---|
| 14 | Outlet 1 On | Outlet 2 Off | All Outlets Off |
| 15 | Outlet 1 Off | Outlet 3 On | Outlet 4 On |
| 3 | Outlet 2 On | Outlet 4 Off | Outlet 4 Off |
To start with, we take a length of 8-strand ribbon cable, and solder it on to the remote PCB. For power, use the negative battery terminal, and the far right (from the back) pin of the power regulator. For the GPIO pins, I used a continuity meter to trace them to a convenient solder pad on one of the push buttons.
For my remote, these are how the different wires wound up being connected:
| Red | +3.3V |
| Brown | GND |
| Grey | Pin 2 |
| Purple | Pin 3 |
| Blue | Pin 13 |
| Green | Pin 14 |
| Yellow | Pin 15 |
| Orange | Pin 16 |
We use a separate transistor to activate each command, omitting the “all outputs off” command. Each output from the shift register is connected to a 150kΩ resistor, which is then connected to the base of an NPN transistor. Two GPIO pins are then connected to the collector and emitter pins of the transistor. To issue the “Outlet 1 On” command, connect GPIO pins 14 and 16. It doesn’t seem to matter which way around these are connected to the transistor — I tested both orientations and they seemed to work.
We need eight of these switches. I tested each command on a breadboard, and then individually after assembling them on a prototype board. Once they’re assembled they’re connected to the outputs from the shift register. My code uses “Outlet 1 On” hooked to output H, “Outlet 1 Off” to output G, “Outlet 2 On” to output F and so on. Because I assembled it upside down. :-(
Connect the +ve wire from the remote to the 3.3V power pin on the Arduino, and the ground wire from the remote to one of the ground pins on the Arduino.
Finally, the shift register is connected to the Arduino. For the EXPAND module:
- Connect Vcc and Reset pins to the 5V supply on the Arduino.
- Connect GND and Output Enable pins to the GND pin on the Arduino.
- Connect Clock to digital pin 5 on the Arduino.
- Connect Latch to digital pin 6 on the Arduino.
- Connect Serial In to digital pin 7 on the Arduino.
It gets a little bit cramped, but I was able to fit the EXPAND module and all other components on to a Freetronics ProtoShield Short, with enough room left over on the right hand side for a couple more relay drivers that I am avoiding discussing in this post.
Software hacking
To transmit a command we have to simulate a button press:
- Send a value to the shift register turning on the appropriate register output.
- Delay briefly. 500ms works well to just issue a command. If you want to use the arduino to program outlets then closer to 2000ms would be needed.
- Send a 0 to the shift register to turn off all register outputs.
The below sample sketch listens for keystrokes entered on the serial console, and sends the associated command. Train a couple of outlets to the remote, load the sketch, open a serial console (make sure the “no line ending” option is set), and then if you’re anything like me spend half an hour typing on the keyboard and giggling at the little LEDs turning on and off.
/* RemoteDemo
Demo sketch for Jackson remote power control.
Hardware:
A shift register connected to pins 5, 6, and 7.
Outputs are wired as:
A: 4off
B: 4on
C: 3off
D: 3on
E: 2off
F: 2on
G: 1off
H: 1on
Run the sketch, and open the Serial Monitor in the Arduino IDE.
Typing a letter between a-h will send the associated command.
*/
// IO pins
const int dataPin = 7;
const int latchPin = 6;
const int clockPin = 5;
boolean cmdEnabled = false; // true if we're sending a command
long cmdTimer = 0; // track how long we're sending command
int inByte = 0; // incoming serial byte
void sendCmdOn(int cmd) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, cmd);
digitalWrite(latchPin, HIGH);
cmdEnabled = true;
cmdTimer = millis() + 500;
}
void sendCmdOff() {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
digitalWrite(latchPin, HIGH);
cmdEnabled = false;
}
void setup() {
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
// Flush the expand module
sendCmdOff();
Serial.begin(9600);
}
void loop() {
// If there's a serial character waiting, parse it
// and send the appropriate command.
if (Serial.available() > 0) {
inByte = char(Serial.read());
switch (inByte) {
case 'h':
Serial.println("Turning on Outlet 1");
sendCmdOn(128);
break;
case 'g':
Serial.println("Turning off Outlet 1");
sendCmdOn(64);
break;
case 'f':
Serial.println("Turning on Outlet 2");
sendCmdOn(32);
break;
case 'e':
Serial.println("Turning off Outlet 2");
sendCmdOn(16);
break;
case 'd':
Serial.println("Turning on Outlet 3");
sendCmdOn(8);
break;
case 'c':
Serial.println("Turning off Outlet 3");
sendCmdOn(4);
break;
case 'b':
Serial.println("Turning on Outlet 4");
sendCmdOn(2);
break;
case 'a':
Serial.println("Turning off Outlet 4");
sendCmdOn(1);
break;
default:
Serial.println("Invalid command received");
}
}
// If we've exceeded the timer, stop sending a command.
if (cmdEnabled && cmdTimer < millis()) {
Serial.println("Releasing button");
sendCmdOff();
}
}


[…] this board for a while, but wanted to control the outside lights from the same system as the power controller I built recently, so build new drivers for my relays on the side of that shield. The end result was a very, very […]