Hello.
This might be a long post. I already have some experience using 74HC595 SIPO shift register with stuff like 7 segment displays which is nice and easy since you only need to deal with 8 bits, which is the same # of outputs on the IC. I've also used them to drive Nixie tubes with the k155id1 nixie driver, which required 4 bits input and decodes a one of ten (0-9) decimal value on the Nixie.
So, I wanted to try driving nixies with only shift registers, instead using MPSA42 transistors to deal with the high voltage stuff. I would connect it like so:
0000000001 -> digit 0
0000000010 -> digit 1... etc (one of ten fashion)
Since the number of bits is greater than the # of outputs on the IC, I decided that I would divide it by 8's, sorta. Like this:
00000000 - 01000000 -- 0010XXXX (we don't care about the last 4 remainder bits for now)
so the first 10 bits are connected to the first tube, the next 10 are connected to the next, etc.
if we look every 10 bits (ignoring those 4 remainders) we get:
0000000001 --> 0000000010 which is the correct sequence of digits to display.
I realized that each register would kinda follow this pattern:
first register is just the first 8 bits of the first digit (from left to right), so I used a bit shift for this.
second register is the last 2 bits of the first digit followed by the first 6 digits of the second digit. (achieved this with a bit shift along with a bitwise OR)
the third is would be the last 4 bits of the second digit followed by the first 4 of the the next digit. (I didn't specify the third digit yet, so its just "0bXXXXXXXXXX" for now.)
I then continued this logic for the other registers, but I'm keeping it to 3 in this for brevity.
As for the code, it works completely as intended (unless there's some unique test case im missing but I doubt that) , but I'm just wondering if I overlooked a simpler way to do this:
const byte data = 5;
const byte latch = 4;
const byte clk = 3;
byte reg1;
byte reg2;
byte reg3;
byte reg4;
byte reg5;
byte reg6;
byte reg7;
byte reg8;
byte newbyte;
//int arr[] = {0b0000000001, 0b0000000010, 0b0000000100, 0b0000001000, 0b0000010000, 0b0000100000, 0b0001000000, 0b0010000000, 0b0100000000, 0b1000000000};
int arr[] = {1,2,4,8,16,32,64,128,256,512}; //displays: "0" , "1" , "2", "3" ... etc.
int h0 = arr[1]; // display #1, displaying a "1"
int h1 = arr[9]; // display #2, displaying a "9"
int m0 = arr[3]; // display #3, you get the point.
int m1 = arr[4];
int s0 = arr[5];
int s1 = arr[6];
byte n;
byte f;
void setup() {
// put your setup code here, to run once:
pinMode(data, OUTPUT);
pinMode(latch, OUTPUT);
pinMode(clk, OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
reg1 = (h0 >> 2); //first 8 bits of digit 1
reg2 = ((h0 << 6) | (h1 >> 4)); // last 2 bits of digit 1 followed by first 6 bits of digit 2
reg3 = ((h1 << 4) | (m0 >> 6)); // last 4 bits of digit 2 followed by first 4 of digit 3
reg4 = ((m0 << 2) | (m1 >> 8)); // and so on
reg5 = (m1);
reg6 = (s0 >> 2);
reg7 = ((s0 << 6) | (s1 >> 4));
reg8 = (s1 << 4);
Serial.println("------- ");
bitset(reg1);
bitset(reg2);
bitset(reg3);
bitset(reg4);
bitset(reg5);
bitset(reg6);
bitset(reg7);
bitset(reg8);
Serial.println("------- ");
delay(1000);
}
byte bitset(byte f) {
//example: 0b1000000000 ---> 512, however, we want the first 8 bits ---> 0b00000000 ---> 0. i'll just read up til the 8th one.
for (byte i = 0; i < 8; i++) {
n = (bitRead(f, i));
bitWrite(newbyte, i, n);
}
Serial.println(newbyte); //replace with shiftOut(data,clk,LSBFIRST,newbyte); (im too lazy to set up the breadboard atm)
}
And here's a simplified version of the schematic:
So yeah, my method works and all, but I'm just wondering if I made it more complicated than it has to be?
Thanks.