New Haven Display VFD with Arduino

Hello,

I'm trying to get New Haven Display's M0116MY-161LSBR2-S2 VFD to function with an arduino. As a test sketch, I tried to print nothing the letter 'A' all the way across the screen following the timing specs in the datasheet. My code is below:

int clockPin = 6;
int dataPin = 7;

int data[8] = {
  0,0,0,0,0,0,0,0};
int data2[8] = {
  0,0,0,0,0,0,0,1};
  
void setup() {
  Serial.begin(9600);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(clockPin, 0);

  writeByte(0xAF);
  writeByte(0xC0);
  writeByte(0xF0);
}

void loop() {
  writeByte(0x00);
  writeByte(0x01);
  writeByte(0x02);
  writeByte(0x03);
  writeByte(0x04);
  writeByte(0x05);
  writeByte(0x06);
  writeByte(0x07);
  writeByte(0x08);
  writeByte(0x09);
  writeByte(0x0A);
  writeByte(0x0B);
  writeByte(0x0C);
  writeByte(0x0D);
  writeByte(0x0E);
  writeByte(0x0F);
  
  delay(1000);
  
  clearBuffer();
  
  delay(1000);
}

void writeByte(int value) {
  for (int i = 0; i < 8; i++) {
    //set clock to HIGH, wait 5 us
    digitalWrite(clockPin, 1);
    //delayMicroseconds(5);
    //write data, bit by bit, and wait 5 more microseconds
    digitalWrite(dataPin, (value >> i) & 0x01);
    delayMicroseconds(5);
    //set clock to low, wait 5 us
    digitalWrite(clockPin, 0);
    delayMicroseconds(5);
  }
  //between words, wait longer
  delayMicroseconds(60);
}

void clearBuffer() {
  for(int i = 0; i < 16; i++) {
    writeByte(0x20);
  }
}

However, this just provides a garbled mess of letters. I've tried other letters, and only "@" seems to work, but that's probably because the character code is 0x00, so the timing doesn't matter for that. Am I approaching inputting the data/clock the wrong way, or is this a reasonable approach? Is it just an issue with the timing somewhere?

I've attached the data sheet for easy reference.

thanks!

M0116MY-161LSBR2-S2.pdf (1.29 MB)

First, mark up the code you have posted by selecting "modify" on your first post, highlight the code and use the code [ # ] icon above the submit window.

As it is, I suspected you had a problem with not using the index in your digitalWrite(dataPin, data [i]); line.

I think you should try initialising it by sending the three codes AFh, C0h and F0h first, and then sending 16 character codes only.

I'm afraid I'm not entirely sure what you mean by not using the index.

Where did you get the codes 0xAF, 0xC0 and oxF0 from? I don't see these anywhere in the manual.

thanks!

Where did you get the codes 0xAF, 0xC0 and oxF0 from? I don't see these anywhere in the manual.

Maybe you just didn't recognize them since they are specified in binary. One place that I found them is in section 5.1 'Control Data'.

Don

Ah, that makes sense -- that said, I'm still not sure what the first one does. The second ones seems to set the character buffer to 16 characters, and the last one sets the brightness, but i'm not sure what the buffer pointer control does (or why I'm setting it to this value).

asymptoticdesign:
I'm not sure what the buffer pointer control does (or why I'm setting it to this value).

Darned if I am sure either, but these settings - more or less (I specified half brightness) - are what the "reset" pin is supposed to do but as you are not using the reset, it seems reasonable to initialise it in this fashion just in case it puts things right.

Paul__B, thanks for your suggestion.

I've updated the code in the original post to reflect what I'm working with right now. Unfortunately, I'm still getting a pretty garbled mess. The output of code that should put out "@ABCDEFGHIJKLMNO" instead outputs "0@HDLBJFNAIEMCKG", so it's pretty evident that there's some strangeness going on with the timing spec somewhere. Any suggestions?

I would have to ask - is that significantly different from its behaviour before?

Looking at the code -you need in setup(), to initialise the sate of the clock and data pins to the initial state cited in the datasheet, otherwise the whole sending sequence can be out of synchronisation. Apart from the control values which I note you have added into your original code, there may be an initialisation pattern required to ensure synchronisation. This is like a form if I2C, but not quite.

Will keep thinking on it ...

I just figured out the issue, and it was embarassingly simple -- I was clocking in data LSB first, and it needed to be MSB first.

int clockPin = 6;
int dataPin = 7;

int data[8] = {
  0,0,0,0,0,0,0,0};
int data2[8] = {
  0,0,0,0,0,0,0,1};
  
void setup() {
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(clockPin, 0);
digitalWrite(dataPin, 0);

  writeByte(0xAF);
  writeByte(0xC0);
  writeByte(0xF0);


}

void loop() {
  writeByte(0x00);
  writeByte(0x01);
  writeByte(0x02);
  writeByte(0x03);
  writeByte(0x04);
  writeByte(0x05);
  writeByte(0x06);
  writeByte(0x07);
  writeByte(0x08);
  writeByte(0x09);
  writeByte(0x0A);
  writeByte(0x0B);
  writeByte(0x0C);
  writeByte(0x0D);
  writeByte(0x0E);
  writeByte(0x0F);
  
  delay(1000);
  
  clearBuffer();
  
  delay(1000);
}

void writeByte(int value) {
  for (int i = 8; i <0; i++) {
    //set clock to HIGH, wait 5 us
    digitalWrite(clockPin, 1);
    //write data, bit by bit, and wait 5 more microseconds
    digitalWrite(dataPin, (value << (i-1)) & 0x01);
    delayMicroseconds(5);
    //set clock to low, wait 5 us
    digitalWrite(clockPin, 0);
    delayMicroseconds(5);
  }
  //between words, wait longer
  delayMicroseconds(60);
}

void clearBuffer() {
  for(int i = 0; i < 16; i++) {
    writeByte(0x20);
  }
}

I just figured out the issue, and it was embarassingly simple -- I was clocking in data LSB first, and it needed to be MSB first.

The working code is below:

int clockPin = 6;
int dataPin = 7;

void setup() {
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  digitalWrite(clockPin, 0);
  digitalWrite(dataPin, 0);

  writeByte(0xAF);
  writeByte(0xC0);
  writeByte(0xF0);
}

void loop() {
  writeByte(0x00);
  writeByte(0x01);
  writeByte(0x02);
  writeByte(0x03);
  writeByte(0x04);
  writeByte(0x05);
  writeByte(0x06);
  writeByte(0x07);
  writeByte(0x08);
  writeByte(0x09);
  writeByte(0x0A);
  writeByte(0x0B);
  writeByte(0x0C);
  writeByte(0x0D);
  writeByte(0x0E);
  writeByte(0x0F);
  
  delay(1000);
  
  clearBuffer();
  
  delay(1000);
}

void writeByte(int value) {
  for (int i = 8; i > 0; i++) {
    //set clock to HIGH, wait 5 us
    digitalWrite(clockPin, 1);
    //write data, bit by bit, and wait 5 more microseconds
    digitalWrite(dataPin, (value << (i-1)) & 0x01);
    delayMicroseconds(5);
    //set clock to low, wait 5 us
    digitalWrite(clockPin, 0);
    delayMicroseconds(5);
  }
  //between words, wait longer
  delayMicroseconds(60);
}

void clearBuffer() {
  for(int i = 0; i < 16; i++) {
    writeByte(0x20);
  }
}