Noritake-Itron GU-7xxx VFD

Hi there. I’m not much of a coder.

Regardless, i got some crazy idea into my head that i could use an arduino and various sensors to get some diagnostic information from the engine and transmission in a pre-OBD2 vehicle.

I know there are projects out there, but all of them seem to be turning into or growing out of stand-alone ECU projects, and i’m just not interested. i want this to be simple and my own.

I like vacuum fluorescent displays, so i bought one. Noritake-Itron GU140X32F-7000. These cost a hundred bucks onsey-twosey from the likes of digikey but there are some on ebay for $30ish. Said to be new, and it was in the characteristic green baggie of an NI display, but no protective film on the glass.

I intend to use this thread blog-style to describe my development of a library to support the GU-7k series displays. And I’ll post my code.

I actually have a CU series display as well, so i started with this site: http://tronixstuff.com/2013/08/23/using-older-noritake-itron-vfd-modules/

So my initial code will look suspiciously like his. But it turns out that the CU and GU series use similar but different commands.

These turn out to be rs232 displays. Not ttl level uart serial - it wants . that took a bit to figure out because the datasheets don’t come right out and say that.

Aside from needing a max232 or similar, they are pretty easy to hook up. Just +5v, ground, and the serial input.

There is also a “busy” line that near as i can tell is like an inverted CTS signal. When the display controller is busy and unable to accept input, it raises the busy line. I think. Application note says that there is a 12 byte input buffer but it doesn’t recommend relying on it.

I may have already run into that.

Trying out the brightness setting (levels available are 1 through 8) i discovered that text pushed to the display directly after setting brightness would get truncated at around 12 characters. Apparently brightness setting is an expensive procedure for the controller. Added a delay after the setting, cleared it right up.

Anyway, here’s what i have so far:

// Noritake Itron GU-7k Test 

#include <SoftwareSerial.h>
SoftwareSerial VFD(10,11); // RX, TX

void setup()
{
  VFD.begin(38400); // set speed
  resetVFD();
  VFDclearscreen();
  VFD.write(0x1F);
  VFD.write(0x02); // vertical scroll mode (on) 
}

void resetVFD()
// performs a software reset on the VFD controller
{
  VFD.write(0x1B); // ESC
  VFD.write(0x40); // software reset
}

void VFDnewline()
{
  VFD.write(0x0D); // carriage return
  VFD.write(0x0A); // line feed
}

void VFDclearscreen()
{
  VFD.write(0x0C); // clear display
  VFD.write(0x0B); // form feed
}

void VFDcursor(int mode)
{
  VFD.write(0x1F);
  VFD.write(0x43);
  VFD.write(mode);
}

void VFDbright(int level) // levels 1 to 8
{
  VFD.write(0x1F);
  VFD.write(0x58);
  VFD.write(level);
  delay(5); // brightness setting appears to be expensive?
}

void VFDchars()
// run through characters for selected font
{
  for (int i = 21 ; i <256; i++)
  {
   VFD.write(i);
   delay(10);
  }
}

void moveCursor(byte position)
// moves the cursor - lines are sequential
{
  VFD.write(0x1F);
  VFD.write(0x24); // move cursor
  VFD.write(position); // location
}

void loop()
{
  delay(1000);
  VFD.print("Hello, Nurse! - 1");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 2");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 3");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 4");
  delay(1000);
  VFDclearscreen();
  VFDbright(1);
  VFD.print("** Bright 1 of 8 **");   
  delay(1000);
  VFDclearscreen();  
  VFDbright(2);
  VFD.print("** Bright 2 of 8 **");     
  delay(1000);
  VFDclearscreen();   
  VFDbright(3);
  VFD.print("** Bright 3 of 8 **");       
  delay(1000);
  VFDclearscreen();   
  VFDbright(4);
  VFD.print("** Bright 4 of 8 **");         
  delay(1000);
  VFDclearscreen();
  VFDbright(5);
  VFD.print("** Bright 5 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(6);
  VFD.print("** Bright 6 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(7);
  VFD.print("** Bright 7 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(8);
  VFD.print("** Bright 8 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDchars();
  VFDclearscreen();
  
}

added kerning, magnification, and font selection.

oughta tackle graphics next. If i can wrap my head around the example code.

// Noritake Itron GU-7k Test 

#include <SoftwareSerial.h>
SoftwareSerial VFD(10,11); // RX, TX

void setup()
{
  VFD.begin(38400); // set speed
  resetVFD();
  VFDclearscreen();
  VFD.write(0x1F);
  VFD.write(0x02); // vertical scroll mode (on) 
}

void resetVFD()
// performs a software reset on the VFD controller
{
  VFD.write(0x1B); // ESC
  VFD.write(0x40); // software reset
}

void VFDnewline()
{
  VFD.write(0x0D); // carriage return
  VFD.write(0x0A); // line feed
}

void VFDclearscreen()
{
  VFD.write(0x0C); // clear display
  VFD.write(0x0B); // form feed
}

void VFDcursor(int mode)
{
  VFD.write(0x1F);
  VFD.write(0x43);
  VFD.write(mode);
}

void VFDbright(int level) // levels 1 to 8
{
  VFD.write(0x1F);
  VFD.write(0x58);
  VFD.write(level);
  delay(5); // brightness setting appears to be expensive?
}

void VFDchars()
// run through characters for selected font
{
  for (int i = 21 ; i <256; i++)
  {
   VFD.write(i);
   delay(10);
  }
  delay(1000);
}

void moveCursor(byte position)
// moves the cursor - lines are sequential
{
  VFD.write(0x1F);
  VFD.write(0x24); // move cursor
  VFD.write(position); // location
}

/* Set kerning
** k=0: Fixed Font Size with 1 dot space
** k=1: Fixed Font Size with 2 dot space
** k=2: Proportional Font Size with 1 dot space
** k=3: Proportional Font Size with 2 dot space
*/

void VFDkerning(int k)
{
  VFD.write(0x1F);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x03);
  VFD.write(k % 0x100);
}

/* font magnification
   X = 1,2,3,4
   Y = 1,2
   Default X=1, Y=1
*/

void VFDmagnify(int X, int Y)
{
  VFD.write(0x1f);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x40);
  VFD.write(X);
  VFD.write(Y);
}  

/* 

font selection - font set and code type

Select int'l font set. Simple symbol only. See Font table. default n=0 
n=0 : US, n=1 : France, n=2 : Germany, n=3 : England, n=4 : Denmark1, 
n=5 : Sweden, n=6 : Italy, n=7 : Spain1, n=8 : Japan, n=9 : Norway,
n=10 : Denmark2, n=11 : Spain2, n=12 : Latin America, n=13 : Korea

Select font code. See Font table. Default n=0
n=0 : US-Euro std, n=1 : Katakana, n=2 : Multilingual, n=3 : Portuguese, 
n=4 : Canadian-French, n=5 : Nordic, n=16 : WPC1252, 
n=17 : Cyrillic #2, n=18 : Latin 2, n=19 : PC858

Obviously not all combinations are valid.

*/

void VFDfontsel(int set, int type)
{
  VFD.write(0x1b);
  VFD.write(0x52);
  VFD.write(set);
  
  VFD.write(0x1b);
  VFD.write(0x74);
  VFD.write(type);
}

void loop()
{
  delay(1000);
  VFD.print("Hello, Nurse! - 1");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 2");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 3");
  delay(1000);
  VFDnewline();
  VFD.print("Hello, Nurse! - 4");
  delay(1000);
  VFDclearscreen();
  VFDbright(1);
  VFD.print("** Bright 1 of 8 **");   
  delay(1000);
  VFDclearscreen();  
  VFDbright(2);
  VFD.print("** Bright 2 of 8 **");     
  delay(1000);
  VFDclearscreen();   
  VFDbright(3);
  VFD.print("** Bright 3 of 8 **");       
  delay(1000);
  VFDclearscreen();   
  VFDbright(4);
  VFD.print("** Bright 4 of 8 **");         
  delay(1000);
  VFDclearscreen();
  VFDbright(5);
  VFD.print("** Bright 5 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(6);
  VFD.print("** Bright 6 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(7);
  VFD.print("** Bright 7 of 8 **");
  delay(1000);
  VFDclearscreen();
  VFDbright(8);
  VFD.print("** Bright 8 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(1);
  VFDchars();
  VFDclearscreen();

  VFDkerning(2);
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(3);
  VFDchars();
  VFDclearscreen();
  VFDkerning(0);

  VFDmagnify(2,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(1,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(2,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,2);
  VFDchars();
  VFDclearscreen();
  VFDmagnify(1,1);
  
  /*
  
  VFDfontsel(1,0); // France
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(2,0); // Germany
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(3,0); // England
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(4,0); // Denmark 1
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(5,0); // Sweden
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(6,0); // Italy
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(7,0); // Spain 1
  VFDchars();
  VFDclearscreen();
  
  */
  
  VFDfontsel(8,1); // Japan
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(9,5); // Norway
  VFDchars();
  VFDclearscreen();
  
  /*
  
  VFDfontsel(10,0); // Denmark 2
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(11,0); // Spain 2 
  VFDchars();
  VFDclearscreen(); 
  
  VFDfontsel(12,0); // Latin America
  VFDchars();
  VFDclearscreen(); 
  
  */
  
  VFDfontsel(13,1); // Korea
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,17); // Cyrillic
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,0);
    
}

Tried selecting 115200bps via the jumper positions on the board. This proved less stable than 38400. Went down to 19200 and was able to remove the delay after setting the brightness. Then put it back anyway.

Added function to turn on or off inverted text. has no effect on text written before the escape sequence is sent.

beat my head against graphics for hours. The example code from noritake-itron is bad java converted to bad c++ and i can’t really make sense of it.

I am clearly out of my depth.

Here it is. For what it’s worth. Also attached are complete datasheet and app note.

// Noritake Itron GU-7k Test 

#include <SoftwareSerial.h>
SoftwareSerial VFD(10,11); // RX, TX

void setup()
{
  VFD.begin(19200); // set speed
  resetVFD();
  VFDclearscreen();
  VFD.write(0x1F);
//  VFD.write(0x01); // Overwrite mode, default
  VFD.write(0x02); // vertical scroll mode
//  VFD.write(0x03); // Horizontal scroll mode  
}

void resetVFD()
// performs a software reset on the VFD controller
{
  VFD.write(0x1B); // ESC
  VFD.write(0x40); // software reset
}

void VFDnewline()
{
  VFD.write(0x0D); // carriage return
  VFD.write(0x0A); // line feed
}

void VFDclearscreen()
{
  VFD.write(0x0C); // clear display
//  VFD.write(0x0B); // form feed
}

void VFDcursor(int mode)
{
  VFD.write(0x1F);
  VFD.write(0x43);
  VFD.write(mode);
}

void VFDbright(int level) // levels 1 to 8
{
  VFD.write(0x1F);
  VFD.write(0x58);
  VFD.write(level);
//  delay(5); // brightness setting appears to be expensive? -- needed at 38400bps
}

void VFDchars()
// run through characters for selected font
{
  for (int i = 21 ; i <256; i++)
  {
   VFD.write(i);
   delay(5);
  }
  delay(1000);
}

void moveCursor(byte position)
// moves the cursor - lines are sequential
{
  VFD.write(0x1F);
  VFD.write(0x24); // move cursor
  VFD.write(position); // location
}

/* Set kerning
** k=0: Fixed Font Size with 1 dot space
** k=1: Fixed Font Size with 2 dot space
** k=2: Proportional Font Size with 1 dot space
** k=3: Proportional Font Size with 2 dot space
*/

void VFDkerning(int k)
{
  VFD.write(0x1F);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x03);
  VFD.write(k % 0x100);
}

/* font magnification
   X = 1,2,3,4
   Y = 1,2
   Default X=1, Y=1
*/

void VFDmagnify(int X, int Y)
{
  VFD.write(0x1f);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x40);
  VFD.write(X);
  VFD.write(Y);
}  

/* 

font selection - font set and code type

Select int'l font set. Simple symbol only. See Font table. default n=0 
n=0 : US, n=1 : France, n=2 : Germany, n=3 : England, n=4 : Denmark1, 
n=5 : Sweden, n=6 : Italy, n=7 : Spain1, n=8 : Japan, n=9 : Norway,
n=10 : Denmark2, n=11 : Spain2, n=12 : Latin America, n=13 : Korea

Select font code. See Font table. Default n=0
n=0 : US-Euro std, n=1 : Katakana, n=2 : Multilingual, n=3 : Portuguese, 
n=4 : Canadian-French, n=5 : Nordic, n=16 : WPC1252, 
n=17 : Cyrillic #2, n=18 : Latin 2, n=19 : PC858

Obviously not all combinations are valid.

*/

void VFDfontsel(int set, int type)
{
  VFD.write(0x1b);
  VFD.write(0x52);
  VFD.write(set);
  
  VFD.write(0x1b);
  VFD.write(0x74);
  VFD.write(type);
}

/* 
graphics. I have no idea.
*/

/* 67x32 image "ArduinoLogo" */
uint8_t image_ArduinoLogo[] = {
    0xff,0xf0,0x0f,0xff,0xff,0x80,0x01,0xff,0xfe,0x00,0x00,0x7f,0xfc,0x00,0x00,0x3f,
    0xf8,0x00,0x00,0x1f,0xf0,0x00,0x00,0x0f,0xe0,0x0f,0xf0,0x07,0xc0,0x3f,0xfc,0x07,
    0xc0,0x7f,0xfe,0x03,0x80,0xff,0xff,0x01,0x81,0xff,0xff,0x01,0x81,0xff,0xff,0x81,
    0x01,0xfc,0x3f,0x81,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,
    0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,
    0x03,0xfc,0x3f,0x80,0x81,0xfc,0x3f,0x81,0x81,0xff,0xff,0x81,0x80,0xff,0xff,0x01,
    0xc0,0x7f,0xfe,0x03,0xc0,0x7f,0xfe,0x03,0xe0,0x3f,0xf8,0x07,0xf0,0x0f,0xf0,0x0f,
    0xf0,0x07,0xe0,0x1f,0xf8,0x03,0xc0,0x1f,0xfc,0x00,0x00,0x3f,0xfe,0x00,0x00,0x7f,
    0xff,0x80,0x01,0xff,0xff,0xc0,0x03,0xff,0xff,0x80,0x01,0xff,0xfe,0x00,0x00,0x7f,
    0xfe,0x00,0x00,0x7f,0xf8,0x03,0x80,0x1f,0xf0,0x07,0xe0,0x1f,0xf0,0x0f,0xf0,0x0f,
    0xe0,0x3f,0xf8,0x07,0xc0,0x7f,0xfc,0x03,0xc0,0x7f,0xfe,0x03,0x80,0xff,0xff,0x01,
    0x81,0xff,0xff,0x81,0x81,0xfc,0x3f,0x81,0x03,0xfc,0x3f,0x80,0x03,0xfc,0x3f,0xc0,
    0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,
    0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x01,0xfc,0x3f,0x81,0x81,0xff,0xff,0x81,
    0x81,0xff,0xff,0x81,0x80,0xff,0xff,0x01,0xc0,0x7f,0xfe,0x03,0xc0,0x1f,0xf8,0x07,
    0xe0,0x0f,0xf0,0x07,0xf0,0x00,0x00,0x0f,0xf8,0x00,0x00,0x1f,0xfc,0x00,0x00,0x3f,
    0xfe,0x00,0x00,0x7f,0xff,0x80,0x01,0xff,0xff,0xf8,0x1f,0xff
};

/* 16x16 image "globe" */
uint8_t image_globe[] = {
    0xf8,0x1f,0xe7,0xa7,0xcb,0xd3,0x9d,0xe9,0xa0,0x0d,0x5d,0xe2,0x3d,0xec,0x3d,0xec,
    0x40,0x00,0x3d,0xec,0x5d,0xea,0xa5,0xe5,0x98,0x09,0xcb,0xd3,0xe7,0xa7,0xf8,0x1f
};


void VFDpaint(uint8_t bmp[], int X, int Y)
{
  VFD.write(0x1f);
  VFD.write(0x28);
  VFD.write(0x66);
  VFD.write(0x11);
  VFD.write(X % 140);
  VFD.write(X / 140);
  VFD.write(Y % 32);
  VFD.write(Y / 32);
  VFD.write(0x01);
  VFD.write(bmp[0, X * Y]);
}

void VFDreverse(int val) // 0 = no 1 = yes
{
  VFD.write(0x1f);
  VFD.write(0x72);
  VFD.write(val);
}


void loop()
{
  VFDcursor(1);
  delay(1000);
  VFDpaint(image_ArduinoLogo,67,32);
  delay(20000);
  VFDclearscreen();
  
  VFD.print("Hello, Nurse! - 1");
  delay(1000);
  VFDnewline();

  VFDreverse(1);
  VFD.print("Hello, Nurse! - 2");
  delay(1000);
  VFDnewline();

  VFDreverse(0);
  VFD.print("Hello, Nurse! - 3");
  delay(1000);
  VFDnewline();

  VFDreverse(1);
  VFD.print("Hello, Nurse! - 4");
  delay(1000);
  VFDclearscreen();

  VFDreverse(0);
  
  VFDbright(1);
  VFD.print("** Bright 1 of 8 **");   
  delay(1000);
  VFDclearscreen();  
  
  VFDbright(2);
  VFD.print("** Bright 2 of 8 **");     
  delay(1000);
  VFDclearscreen();   
  
  VFDbright(3);
  VFD.print("** Bright 3 of 8 **");       
  delay(1000);
  VFDclearscreen();   
  
  VFDbright(4);
  VFD.print("** Bright 4 of 8 **");         
  delay(1000);
  VFDclearscreen();
  
  VFDbright(5);
  VFD.print("** Bright 5 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(6);
  VFD.print("** Bright 6 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(7);
  VFD.print("** Bright 7 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(8);
  VFD.print("** Bright 8 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(1);
  VFDchars();
  VFDclearscreen();

  VFDkerning(2);
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(3);
  VFDchars();
  VFDclearscreen();

  VFDkerning(0);

  VFDmagnify(2,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(1,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(2,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,2);
  VFDchars();
  VFDclearscreen();
  VFDmagnify(1,1);
  
  /*
  
  VFDfontsel(1,0); // France
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(2,0); // Germany
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(3,0); // England
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(4,0); // Denmark 1
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(5,0); // Sweden
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(6,0); // Italy
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(7,0); // Spain 1
  VFDchars();
  VFDclearscreen();
  
  */
  
  VFDfontsel(8,1); // Japan
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(9,5); // Norway
  VFDchars();
  VFDclearscreen();
  
  /*
  
  VFDfontsel(10,0); // Denmark 2
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(11,0); // Spain 2 
  VFDchars();
  VFDclearscreen(); 
  
  VFDfontsel(12,0); // Latin America
  VFDchars();
  VFDclearscreen(); 
  
  */
  
  VFDfontsel(13,1); // Korea
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,17); // Cyrillic
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,0);

    
}

apf200_r201et.pdf (1.91 MB)

gu140x32f-7000_e04.pdf (437 KB)

OK after a more careful reading of the application note and a realization that the code example for displaying graphics in it probably doesn’t work for them either, and some help from a friend to recall the 1st week of my 1st C class in 1991, I have graphics working.

The vertical resolution of bitmap graphics must be a multiple of 8 pixels on the gu7k displays, and although the X dimension is passed in bits, the Y dimension is passed in bytes.

So, everything in the following code works, and displays sort of a poor approximation of the arduino logo:

// Noritake Itron GU-7k Test 

#include <SoftwareSerial.h>
SoftwareSerial VFD(5,6); // RX, TX

void setup()
{
  VFD.begin(19200); // set speed
  resetVFD();
  VFDclearscreen();
  VFD.write(0x1F);
//  VFD.write(0x01); // Overwrite mode, default
  VFD.write(0x02); // vertical scroll mode
//  VFD.write(0x03); // Horizontal scroll mode  
}

void resetVFD()
// performs a software reset on the VFD controller
{
  VFD.write(0x1B); // ESC
  VFD.write(0x40); // software reset
}

void VFDnewline()
{
  VFD.write(0x0D); // carriage return
  VFD.write(0x0A); // line feed
}

void VFDclearscreen()
{
  VFD.write(0x0C); // clear display
//  VFD.write(0x0B); // form feed
}

void VFDcursor(int mode)
{
  VFD.write(0x1F);
  VFD.write(0x43);
  VFD.write(mode);
}

void VFDbright(int level) // levels 1 to 8
{
  VFD.write(0x1F);
  VFD.write(0x58);
  VFD.write(level);
//  delay(5); // brightness setting appears to be expensive? -- needed at 38400bps
}

void VFDchars()
// run through characters for selected font
{
  for (int i = 21 ; i <256; i++)
  {
   VFD.write(i);
   delay(5);
  }
  delay(1000);
}

void moveCursor(byte position)
// moves the cursor - lines are sequential
{
  VFD.write(0x1F);
  VFD.write(0x24); // move cursor
  VFD.write(position); // location
}

/* Set kerning
** k=0: Fixed Font Size with 1 dot space
** k=1: Fixed Font Size with 2 dot space
** k=2: Proportional Font Size with 1 dot space
** k=3: Proportional Font Size with 2 dot space
*/

void VFDkerning(int k)
{
  VFD.write(0x1F);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x03);
  VFD.write(k % 0x100);
}

/* font magnification
   X = 1,2,3,4
   Y = 1,2
   Default X=1, Y=1
*/

void VFDmagnify(int X, int Y)
{
  VFD.write(0x1f);
  VFD.write(0x28);
  VFD.write(0x67);
  VFD.write(0x40);
  VFD.write(X);
  VFD.write(Y);
}  

/* 

font selection - font set and code type

Select int'l font set. Simple symbol only. See Font table. default n=0 
n=0 : US, n=1 : France, n=2 : Germany, n=3 : England, n=4 : Denmark1, 
n=5 : Sweden, n=6 : Italy, n=7 : Spain1, n=8 : Japan, n=9 : Norway,
n=10 : Denmark2, n=11 : Spain2, n=12 : Latin America, n=13 : Korea

Select font code. See Font table. Default n=0
n=0 : US-Euro std, n=1 : Katakana, n=2 : Multilingual, n=3 : Portuguese, 
n=4 : Canadian-French, n=5 : Nordic, n=16 : WPC1252, 
n=17 : Cyrillic #2, n=18 : Latin 2, n=19 : PC858

Obviously not all combinations are valid.

*/

void VFDfontsel(int set, int type)
{
  VFD.write(0x1b);
  VFD.write(0x52);
  VFD.write(set);
  
  VFD.write(0x1b);
  VFD.write(0x74);
  VFD.write(type);
}

/* 
graphics. I have no idea.
*/

/* 67 bits by 4 bytes image "ArduinoLogo" */
byte image_ArduinoLogo[] = {
    0xff,0xf0,0x0f,0xff,0xff,0x80,0x01,0xff,0xfe,0x00,0x00,0x7f,0xfc,0x00,0x00,0x3f,
    0xf8,0x00,0x00,0x1f,0xf0,0x00,0x00,0x0f,0xe0,0x0f,0xf0,0x07,0xc0,0x3f,0xfc,0x07,
    0xc0,0x7f,0xfe,0x03,0x80,0xff,0xff,0x01,0x81,0xff,0xff,0x01,0x81,0xff,0xff,0x81,
    0x01,0xfc,0x3f,0x81,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,
    0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,
    0x03,0xfc,0x3f,0x80,0x81,0xfc,0x3f,0x81,0x81,0xff,0xff,0x81,0x80,0xff,0xff,0x01,
    0xc0,0x7f,0xfe,0x03,0xc0,0x7f,0xfe,0x03,0xe0,0x3f,0xf8,0x07,0xf0,0x0f,0xf0,0x0f,
    0xf0,0x07,0xe0,0x1f,0xf8,0x03,0xc0,0x1f,0xfc,0x00,0x00,0x3f,0xfe,0x00,0x00,0x7f,
    0xff,0x80,0x01,0xff,0xff,0xc0,0x03,0xff,0xff,0x80,0x01,0xff,0xfe,0x00,0x00,0x7f,
    0xfe,0x00,0x00,0x7f,0xf8,0x03,0x80,0x1f,0xf0,0x07,0xe0,0x1f,0xf0,0x0f,0xf0,0x0f,
    0xe0,0x3f,0xf8,0x07,0xc0,0x7f,0xfc,0x03,0xc0,0x7f,0xfe,0x03,0x80,0xff,0xff,0x01,
    0x81,0xff,0xff,0x81,0x81,0xfc,0x3f,0x81,0x03,0xfc,0x3f,0x80,0x03,0xfc,0x3f,0xc0,
    0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,0x03,0xe0,0x07,0xc0,
    0x03,0xfc,0x3f,0xc0,0x03,0xfc,0x3f,0xc0,0x01,0xfc,0x3f,0x81,0x81,0xff,0xff,0x81,
    0x81,0xff,0xff,0x81,0x80,0xff,0xff,0x01,0xc0,0x7f,0xfe,0x03,0xc0,0x1f,0xf8,0x07,
    0xe0,0x0f,0xf0,0x07,0xf0,0x00,0x00,0x0f,0xf8,0x00,0x00,0x1f,0xfc,0x00,0x00,0x3f,
    0xfe,0x00,0x00,0x7f,0xff,0x80,0x01,0xff,0xff,0xf8,0x1f,0xff
};

/* 16 bits by 2 bytes image "globe" */
byte image_globe[] = {
    0xf8,0x1f,0xe7,0xa7,0xcb,0xd3,0x9d,0xe9,0xa0,0x0d,0x5d,0xe2,0x3d,0xec,0x3d,0xec,
    0x40,0x00,0x3d,0xec,0x5d,0xea,0xa5,0xe5,0x98,0x09,0xcb,0xd3,0xe7,0xa7,0xf8,0x1f
};

/* immediately draw graphics at cursor. X is width in
bits, Y is height in bytes of 8 bits */

void VFDpaint(byte bmp[], int X, int Y)
{
  VFD.write(0x1F);
  VFD.write(0x28);
  VFD.write(0x66);
  VFD.write(0x11);
  VFD.write(X % 256);
  VFD.write(X / 256);
  VFD.write(Y % 256);
  VFD.write(Y / 256);
  VFD.write(0x01);
  
  for(int i = 0; i < X*Y; i++)
 {
  VFD.write(bmp[i]);
 } 
}

void VFDreverse(int val) // 0 = no 1 = yes
{
  VFD.write(0x1f);
  VFD.write(0x72);
  VFD.write(val);
}


void loop()
{
  VFDcursor(1);
  delay(100);
  VFDcursor(0);
  VFDclearscreen();
  VFDpaint(image_ArduinoLogo,67,4);
//  VFDpaint(image_globe,16,2);
  delay(20000);
  VFDclearscreen();
  
  VFD.print("Hello, Nurse! - 1");
  delay(1000);
  VFDnewline();

  VFDreverse(1);
  VFD.print("Hello, Nurse! - 2");
  delay(1000);
  VFDnewline();

  VFDreverse(0);
  VFD.print("Hello, Nurse! - 3");
  delay(1000);
  VFDnewline();

  VFDreverse(1);
  VFD.print("Hello, Nurse! - 4");
  delay(1000);
  VFDclearscreen();

  VFDreverse(0);
  
  VFDbright(1);
  VFD.print("** Bright 1 of 8 **");   
  delay(1000);
  VFDclearscreen();  
  
  VFDbright(2);
  VFD.print("** Bright 2 of 8 **");     
  delay(1000);
  VFDclearscreen();   
  
  VFDbright(3);
  VFD.print("** Bright 3 of 8 **");       
  delay(1000);
  VFDclearscreen();   
  
  VFDbright(4);
  VFD.print("** Bright 4 of 8 **");         
  delay(1000);
  VFDclearscreen();
  
  VFDbright(5);
  VFD.print("** Bright 5 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(6);
  VFD.print("** Bright 6 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(7);
  VFD.print("** Bright 7 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDbright(8);
  VFD.print("** Bright 8 of 8 **");
  delay(1000);
  VFDclearscreen();
  
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(1);
  VFDchars();
  VFDclearscreen();

  VFDkerning(2);
  VFDchars();
  VFDclearscreen();
  
  VFDkerning(3);
  VFDchars();
  VFDclearscreen();

  VFDkerning(0);

  VFDmagnify(2,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,1);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(1,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(2,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(3,2);
  VFDchars();
  VFDclearscreen();
  
  VFDmagnify(4,2);
  VFDchars();
  VFDclearscreen();
  VFDmagnify(1,1);
  
  /*
  
  VFDfontsel(1,0); // France
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(2,0); // Germany
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(3,0); // England
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(4,0); // Denmark 1
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(5,0); // Sweden
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(6,0); // Italy
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(7,0); // Spain 1
  VFDchars();
  VFDclearscreen();
  
  */
  
  VFDfontsel(8,1); // Japan
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(9,5); // Norway
  VFDchars();
  VFDclearscreen();
  
  /*
  
  VFDfontsel(10,0); // Denmark 2
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(11,0); // Spain 2 
  VFDchars();
  VFDclearscreen(); 
  
  VFDfontsel(12,0); // Latin America
  VFDchars();
  VFDclearscreen(); 
  
  */
  
  VFDfontsel(13,1); // Korea
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,17); // Cyrillic
  VFDchars();
  VFDclearscreen();
  
  VFDfontsel(0,0);

    
}

Got graphical scrolling working, which is important if you want to have graphics appear immediately and not watch them get painted over slow serial. (rate=0).

It leaves the display in a strange state where text isn’t showing and I’m not really sure why or the correct way to avoid or revert that, which is why i reinitialize the display after demonstrating it in my code.

For a bit i thought the way to deal with it was by setting the display mix mode (and, or, xor) but got nowhere with that, not sure if i have display mix implemented correctly yet.

Moved the text scrolling behavior setting into the resetVFD function.

GU_7k.ino (8.54 KB)

I have played around with your code and the Noritake VFD quite a bit.

I found that setting the baud rate to 19200 fixes all the issues.

Yes. I've noticed that as well. It might be nice to have flow control on the serial but it's certainly not necessary.

There are some more of these on ebay, by the way, and quite cheap:

http://www.ebay.com/itm/380952747150

I just tried your code, it works flawlessly for me. Many thanks for the work you've done.

Vit

Hi Vitreous and Timpanogos_Slim

I haev read through your postings and they have been most helpful thank you.

I have the same Noritake display board and it took awhile ot work out why I could not get characters on screen other than junk. For all who have same display, the unit does works direct from Arduino using these pins 3(SIN), 5(SBUSY) and 7(RESET) but most importantly is power has too be from external PSU NOT the Arduino as it only supports up to 200mA. Also 9600 and 19200 are the only baud I could get working.

The test program needs changing from VFD.write to vfd.print then it compiles ok, it too has been really helpful.

Thanks again for the information.

P.