I've recently started working on a custom spa pool controller, to allow WiFi control of temperatures, blowers, and automatic heating/filtration cycles using an Arduino.
The bulk of the project is done at this stage, but I've run into an issue whilst reverse engineering the existing control panel of the spa to integrate with my custom controller.
The control panel has three LEDs, one bi-colour LED, and a triple 7-segment display, all of which are controlled by two HEF4094B shift registers. One shift register (U2) takes input from my Arduino on the data line, and another (U1) has its data line connected to the serial output of U1.
I took the time to go through each of the parallel outputs on the shift registers, to figure out which outputs controlled which regions of the control panel:
U1 - Data wire connected to U2 serial output
--
QP0 - Display segment G
QP1 - Display segment C
QP2 - Display DP
QP3 - Display segment D
QP4 - Display segment B
QP5 - Display segment F
QP6 - Display segment E
QP7 - Display segment A
U2 - Data wire connected to Arduino
--
QP0 - Bi-colour LED (Green)
QP1 - Red LED
QP2 - Yellow LED
QP3 - Bi-colour LED (Red)
QP4 - Green LED
QP5 - Display digit 1 select
QP6 - Display digit 3 select
QP7 - Display digit 2 select
Based on this, I tried a quick test (based on an example found here) to iterate through the outputs on U2, setting an individual bit high every 500 ms:
const byte COL_COUNT = 9;
//array to hold the data
unsigned char sequence[COL_COUNT] = {B00000000, B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000};
//unsigned char sequence[COL_COUNT] = {1, 2, 4, 8, 16, 32, 64, 128};
//unsigned char sequence[COL_COUNT] = {0x01, 0x02, 0x04, 0x8, 0x10, 0x20, 0x40, 0x80};
//Define which pins will be used for the shift register control
//can be any digital pin on the Arduino
int latchPin = 8; //Pin connected to STR(pin 1) of HEF4094
int clockPin = 12; //Pin connected to CP(pin 3) of HEF4094
int dataPin = 11; //Pin connected to D(pin 2) of HEF4094
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
for (int col = 0; col < COL_COUNT; col++) {
digitalWrite(latchPin, HIGH); // Pull latch HIGH to send data
shiftOut(dataPin, clockPin, MSBFIRST, sequence[col]); // Send the data
digitalWrite(latchPin, LOW); // Pull latch LOW to stop sending data
delay(500);
}
}
The output after running this example was not as I expected. I did expect the 7-segment displays to output garbage, but I would have expected the LEDs to turn on in the order listed above (i.e QP0, QP1, QP2, QP3 etc). This was instead the output I got, with the input binary listed below each state:
This is my first time using shift registers in a project, and I wonder if I am misunderstanding how they work here. If anyone can figure out why the register is outputting multiple bits high at once, and not setting outputs high in any sort of coherent order, your input would be much appreciated!