Shift Registers and data out

Greetings, I need some help wrapping my mind around on how an Arduino sends out the binary code for a shift register. I am designing an IN-1 nixie clock, that will be using the Microchip HV5622 IC. HV5622

I've perused the numerous nixie clocks out there and their code. I understand having the Arduino control when to pulse the clock, and latch, it's just sending the actual 0's and 1's. Is it done with an array, where I know the exact binary code to output for certain pins? If so that seems very tedious typing each binary code to turn on the correct pin of the shift register. I am very new to C programming, so please bear with me as I might ask simple questions.

The other thing about this HV5622 register is understanding the logic of what binary number I need to send to it to trigger each pin. For instance if I wanted to trigger HV output ten, would I send 0b1010 into the register?

Goldbrick_Gangboss: For instance if I wanted to trigger HV output ten, would I send 0b1010 into the register?

No, you would send 0x20 --> 00000000 00000000 00000010 00000000

For reference:

Goldbrick_Gangboss: The other thing about this HV5622 register is understanding the logic of what binary number I need to send to it to trigger each pin. For instance if I wanted to trigger HV output ten, would I send 0b1010 into the register?

From the datasheet:

The device consists of a 32-bit Shift register, 32 latches and control logic to perform the polarity select and blanking of the outputs.

This is telling you the HV5622 does no decoding - logically it's just a plain old shift register, like a 74HC164, just four times longer. So to output the correct pattern represented by 0x1010 in the Arduino it will have to be converted to 0b1000000000, a string of ten bits. Sending 0b0100000000 would turn on HV output nine, and so on. Sending your 0x1010 would turn on outputs two and four.

It's a bit of a wrinkle to deal with 10-bit values when everything computer is based on 8-bit values. There are multiple ways to do these things.

Do a site search on 'nixie'.

Goldbrick_Gangboss: I am very new to C programming, so please bear with me as I might ask simple questions.

Start with the demo sketches in IDE -> file/examples/digital. The first five will give you a good grounding for what's to come. Do some simple things to get your programming feet under you.

Bookmark the Arduino reference page.

Power_Broker: No, you would send 0x20 --> 00000000 00000000 00000010 00000000

I believe this makes sense written out in full format, since this is a 32 bit register I’ll need to send 32 bits of data. In the example above you send a high signal on the tenth bit correct? This is what opens/turns on pin 10?

dougp: It's a bit of a wrinkle to deal with 10-bit values when everything computer is based on 8-bit values. There are multiple ways to do these things.

I’m not understanding how it’s a 10 bit value data out I need to send to the register. Nor how you gleaned that information from the data sheet. Perhaps you will kindly educate my ignorance on this.

Thanks for the responses.

Goldbrick_Gangboss: I’m not understanding how it’s a 10 bit value data out I need to send to the register. Nor how you gleaned that information from the data sheet.

Each Nixie tube has ten pins to select which element illuminates, correct?

Goldbrick_Gangboss: I believe this makes sense written out in full format, since this is a 32 bit register I’ll need to send 32 bits of data. In the example above you send a high signal on the tenth bit correct? This is what opens/turns on pin 10?

Yes, basically a bit of 1 means the corresponding shift register position is "turned on".

dougp: Each Nixie tube has ten pins to select which element illuminates, correct?

That is correct. I will not be driving all ten at the same time. The most at any time will be 4.

Goldbrick_Gangboss: That is correct. I will not be driving all ten at the same time. The most at any time will be 4.

One or both of us is confused.

Let's assume a four digit clock - HHMM only. Each nixie tube has ten inputs. That means you'll need *forty data outputs *to drive the display assuming direct drive of each tube - although they can be multiplexed, ie. fewer cathode drives required, at the expense of adding anode drivers.

You cannot directly drive a single Nixie with only four bits and get all ten digits displayed, you would have to choose which four digits you want to display. The other six would never illuminate. You can however substitute a 1-of-10 decoder (representative of function only) IC to convert a BCD value to the correct signal to turn on a particular Nixie element. This would require four decoder chips and their supporting circuitry. You then have sixteen bits filled with four BCD values presented to the decoders.

Without the decoder a. you'll need two HV5622s to accommodate the 40 bits and, b. you'll have to convert a number like '1027' to four separate 1-of-10 values, one for each digit, and send them out to your cascaded (output of one becomes the input for the next) HV5622s.

dougp:
One or both of us is confused.

Without the decoder a. you’ll need two HV5622s to accommodate the 40 bits and, b. you’ll have to convert a number like ‘1027’ to four separate 1-of-10 values, one for each digit, and send them out to your cascaded (output of one becomes the input for the next) HV5622s.

It’s likely that I am confused Doug. Understanding shift registers and how to turn on 4 HV output drains on at once is starting to make sense to me.

You are correct. I will be using two HV5622 chips in my project. The only reason I am using two chips is because I want to implement “Vegas Protocol” on the clock. Meaning I want to cycle all the numbers on all tubes at certain time increments one digit at a time. A slot machine effect per say.

At any given hour and minute of the day, let’s say 21:48. As I understand it I would only need to drive the outputs for the 2X:XX, X1:XX, XX:4X, and XX:X8 of the two HV 5622 registers. Perhaps this wiring diagram might give you some insight at what I am trying to accomplish. This by no means is the way I am designing the clock, but this is where I got the idea to use the HV5622.
http://reboots.g-cipher.net/time/time-schematic.pdf

I’ve attached my schematic. It is still a work in progress. I am still doing breadboard testing currently.

Schematic_IN-1 HV5622_Sheet_1_20190919144947.pdf (91.7 KB)

Goldbrick_Gangboss:
You are correct. I will be using two HV5622 chips in my project. The only reason I am using two chips is because I want to implement “Vegas Protocol” on the clock. Meaning I want to cycle all the numbers on all tubes at certain time increments one digit at a time. A slot machine effect per say.

Thanks for the schematic. I now see that you don't actually need two 5622s. I was not considering that the hours/mins digits will not utilize all ten pins for their respective Nixie displays.

Are you saying the Vegas thing would look like:

2 1 : 48
2 2 : 48
2 3 : 48
2 4 : 48

Goldbrick_Gangboss:
At any given hour and minute of the day, let’s say 21:48. As I understand it I would only need to drive the outputs for the 2X:XX, X1:XX, XX:4X, and XX:X8 of the two HV 5622 registers. Perhaps this wiring diagram might give you some insight at what I am trying to accomplish. This by no means is the way I am designing the clock, but this is where I got the idea to use the HV5622.
http://reboots.g-cipher.net/time/time-schematic.pdf

I think you're missing what the shift register does. Let's use the schematic you gave. Minutes Ones requires ten pins from the 5622, since the digits 0-9 will be shown. Minutes Tens requires six pins from the 5622 because only digits 0-5 are needed. So we've used sixteen of the thirty-two pins available.

I made up a short sketch to illustrate one way that it can be done in the Arduino to generate the shift register data.

#include "binLdngZero.h" // so we can see all thirty-two bits.

int secs = 60;
unsigned long srData; // to hold S.R. data

void setup() {
  Serial.begin(115200);
}

void loop() {
  for (uint8_t i = 0; i < secs; i++) {
    int secOnes, secTens, temp;
    temp = i;
    secOnes = temp % 10;
    temp = temp / 10;
    secTens = temp % 10;
    srData = 0;
    bitSet(srData, secOnes); // turn on a bit to drive the ones Nixie
    bitSet(srData, secTens + 10); // turn on a bit to drive the tens Nixie
    printBinWithLeading(Serial, srData, true);
    Serial.print("\t\t");
    Serial.print(secTens);
    Serial.print("\t");
    Serial.println(secOnes);
    delay(1000);
  }
}

You'll need to include this header file.

// Print a number in binary with leading zeroes
//
// by septillion: https://forum.arduino.cc/index.php?topic=464778.0
//
// Prints a whole number in its binary form with leading
// zeroes - to keep column alignment.
// 1/26/19 - Added option (bool type 'nybbleSep') to print one
// space between nybbles.  nybbleSep true = add separator,
// else no separator.
// 1/26/19 - Added types long and int
//
// Calling convention: printBinWithLeading(Serial, argument, true/false);

#ifndef BIN_LDNG_ZERO_H
#define BIN_LDNG_ZERO_H

void printBinWithLeading(Print &out, unsigned long n, bool nybbleSep, byte size) {
  for (byte i = size ; i--;) {
    out.print(bitRead(n, i));
    if (nybbleSep) { // add a space between nybbles? hdp 1/26/19
      if (!(i & 3) & i != 0) out.print(" ");
//      if (i % 4 == 0 & i != 0) out.print(" ");
      if (i == 0) {
        break;
      }
    }
  }
}

inline void printBinWithLeading(Print &out, unsigned long n, bool nybbleSep) {
  printBinWithLeading(out, n, nybbleSep, sizeof(n) * 8);
}
inline void printBinWithLeading(Print &out, long n, bool nybbleSep) {
  printBinWithLeading(out, n, nybbleSep, sizeof(n) * 8);
}
inline void printBinWithLeading(Print &out, int n, bool nybbleSep) {
  printBinWithLeading(out, n, nybbleSep, sizeof(n) * 8);
}
inline void printBinWithLeading(Print &out, uint16_t n, bool nybbleSep) {
  printBinWithLeading(out, n, nybbleSep, sizeof(n) * 8);
}
inline void printBinWithLeading(Print &out, byte n, bool nybbleSep) {
  printBinWithLeading(out, n, nybbleSep, sizeof(n) * 8);
}
#endif

Add this file by opening a new tab in your sketch and giving it the indicated name. Copy/paste the code into the new tab.

Arduino IDE tab button.PNG

The eight columns of four represent the contents of the 5622 to be presented to the Nixies, LSB on the right based on the last two columns (seconds tens and seconds ones in decimal form).

hours minutes.PNG

This would represent a value of 04 minutes.

Arduino IDE tab button.PNG

hours minutes.PNG

You misunderstand Doug, I want to use all 40 nixie tube numbers. The link for the schematic (by Reboot) is not my design, work or how I am building my clock. Please look back at that post with the link and select the file attachment I put at the bottom of that post or see the link to it on Google Drive below. My design will use all numbers. Here is my actual schematic. My Schematic

This following video link is what I call "Vegas Protocol". It's the cycling of all the number digits. In this video you will see 75 scroll horizontally a few times. My clock will not do that. I want my clock to just do the cycling of all numbers in the tubes, like in the video after the 75 moving horizontally. The effect I want starts at 0:14 in the video. Vegas Protocol Video

This is the only reason I want to use all 40 nixie tube outputs.

Thank you for sharing that code, when I have more time to sit down and read it I will respond again.

Goldbrick_Gangboss: Please look back at that post with the link and select the file attachment I put at the bottom of that post or see the link to it on Google Drive below. My design will use all numbers.

I think I get it now.

A question; what is the purpose of using outputs 12 thru 32 (less output 22) and leaving 1 thru 11 unconnected on the NX1/2 driver? This will mean sending eleven trailing dummy bits to push the first twenty bits into position.

Another; what is the purpose of using separate CLK and DATAIN signals for each display driver? I would have expected DATA&OUT of one to be connected to DATAIN of the other.

The schematic is not a final draft. I did that to make it simple to read. I am by no means an electrical engineer with design experience either. This is also my first time using a CAD like program to design a circuit. Logically to me yes, I like structure and will design the wiring print to use 1 through 20 for hours on first HV5622, and 1 through 20 for minutes on second HV5622. That will still leave 24 unassigned outputs on the shift registers. Wasted outputs I suppose, but also my first design project. If you’d like a run down of my full project I can explain it all. I intend on doing that in the future once I get the hang of programming, and circuit board design. I am still in my infancy of R&D for this clock.

The reason I did two DATAIN is because I do not fully understand how the DATAOUT from register one works. I have a very rudimentary grasp of electronic components and how to read their data sheets. And two signals for CLK, is I assumed that each register would need a different pulse, because minutes will change far more frequently than hours will.