Shift Register and SPI.Transfer/shiftOut

Hello all,

I’ve been butting my head up against this for a bit and am feeling pretty clueless.

I’m trying to get an old VFD working, and that VFD uses an NEC uPD6323BC 21-bit shift register to control the elements. So, thinking I was smart, I figured I would use the Arduino to control input to the Clock, Serial Input, and Latch pins of that board.

I’ve tried both setting up and running “SPI” as well as using serial with “shiftOut”, but I get pretty much the same problem on each one. No matter what data I send it, it seems to illuminate multiple elements with no particular correlation to each other. They’re not random as they’re repeatable (if I send “1” over and over the same elements illuminate.), but they’re really all over the place. The good news is it seems I’m actually successfully sending data as I get life out of the board and elements illuminating. Also, if I send “0” all elements turn off as expected.

There are 19 elements, and the 21-bit register implies to me that each bit controls an individual element, but even when sending just “1”, it seems to illuminate multiple elements. I’ve tried typing in a 21-digit binary number to send, I’ve tried Hex and even just counting up an int, like in my code example below.

I don’t know enough about serial communication to know if I’m doing something obviously and painfully wrong. I feel like I’m not sending enough bits to fill the full register and multiple bits are getting stacked on top of each other or something.

Here’s the datasheet for the shift register: Datasheet

Here’s a few pictures from the datasheet that better illustrate what I’m trying to achieve.

Pic 1: This one I can follow pretty easy, the concept is simple enough.

Pic 2: This is the program example. Only problem is, I have no idea what half the abbreviations mean…

If anyone could just give me a nudge in the right direction, that’d be amazing!

Thanks all,
David

Here’s my code. It’s pretty much a simple trial and error test program.

#include <SPI.h>

const int latchHold = 10;
const int dataOut = 11;
const int sClock = 13;

void setup() {
  Serial.begin(9600);
  SPI.begin ();
  pinMode (dataOut, OUTPUT);
  pinMode (sClock, OUTPUT);
  pinMode (latchHold, OUTPUT);
}

void loop() {
  
  for (int i = 1; i < 256; i++) {
    //shiftOut(dataOut, sClock, LSBFIRST, i);
    
    digitalWrite(latchHold, LOW);
    SPI.beginTransaction(SPISettings(2000000, LSBFIRST, SPI_MODE1));
    SPI.transfer(0);
    SPI.transfer(i);
    SPI.endTransaction();
    digitalWrite(latchHold, HIGH);
    digitalWrite(latchHold, LOW);
    
    delay(1000);
  }
}

Right now, you're sending 2 bytes (16 bits) of data. What happens if you send a third byte of all zeros?

If you don't send all 21 bits, some of the last bits will be repeated.

Pieter

Thank you so much!

That was the nudge in the right direction I needed!

You were right, I wasn’t sending enough data and that was resulting in data remaining when the next set of data was sent. I ended up going with shiftOut, but because shiftOut only does 8 bits at a time, I had to call the function three times and perform a bit shift to get it done. Now, it all works beautifully though!

Here’s my new code:

const int latchHold = 10;
const int dataOut = 11;
const int sClock = 13;

long digit1[] = {192,7552,5568,1728,5952,8000,448,8128,6080};
long digit2[] = {24576,966656,712704,221184, 761856, 1024000,57344,1040384,778240};

void setup() {
  Serial.begin(9600);
  pinMode (dataOut, OUTPUT);
  pinMode (sClock, OUTPUT);
  pinMode (latchHold, OUTPUT);
}

void loop() {
  
  for (long i = 0; i < 9; i++) {
    digitalWrite(latchHold, LOW);

    //MPH = +1, km/h = +2, 100 = + 24, 200 = + 40
    long data = digit1[i] + digit2[i] + 2 + 40;
    
    shiftOut(dataOut, sClock, MSBFIRST, data >> 16);
    shiftOut(dataOut, sClock, MSBFIRST, data >> 8);
    shiftOut(dataOut, sClock, MSBFIRST, data);
    
    digitalWrite(latchHold, HIGH);
    digitalWrite(latchHold, LOW);
    
    delay(200);
  }
}

And here’s me running a slightly different version of that code as a test:

Thanks again!
David

Hello David,

Congratulations on getting it working via the Arduino processer - great work!

I have what I think is the same VFD display (from a 1990 Nissan 180SX) and I am hoping (desperately) that you might be able to help me solve a related problem...

In my case I have the data bits going into the uPD6323BC - because the factory chip is OK - but there is a failure somewhere in the filament power circuit, which is somewhat complex and I have not been able to locate the exact fault.

Clearly the power to your VFD display is fine - would you be able to confirm a) the filament voltage, and b) the negative offset required to get the display to work?

I believe the filament voltage is AC, and the offset (to ground) should be between -6 and -23 based on the chip datasheet. I am not sure if adjusting the dash brightness changes the filament voltage, the offset, or both.

Did you build a filament power circuit - or are you using the factory one from the instrument cluster?

Any help would be really appreciated,

Regards,

Adrian