1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Arduino Micro & Noritake VFD

Discussion in 'Papers' started by Stéphane Lenclud, Jun 5, 2017.

  1. Stéphane Lenclud

    Stéphane Lenclud Founder Staff Member

    Purpose & Scope

    Provide information about Arduino Micro as we attempt to use such a board to interface with a Noritake GU256x64D-3900 VFD module from a Windows PC over a USB HID connection.
    Software engineering skills and basic electronics knowledge are assumed.

    Motives

    After attempting to interface our VFD module from a PC over parallel port we came to the conclusion that it would be faster and cheaper to use a GPIO solution such as the one offered by Arduino Micro.

    Prerequesites

    In the following article we make use an Arduino Micro board and a Noritake GU256x64D-3900B VFD module. On top of that we will be needing a breadboard, jumper wires and an assortments of LEDs and resistors to be able to carry out our experiments.

    Getting started

    • Download the latest Arduino IDE from Arduino Software page.
    • Plug your Arduino Micro to one of your computer USB port.
    • Open Arduino IDE:
      • Go to menu Tools > Board and select Arduino/Genuino Micro.
      • From that same Tools menu select the Port you board is connected to.
      • Go to menu File > Examples > 01.Basics > Blink
    Congratulation you are now ready to start developing for your Arduino Micro board.
    Go do some reading about that Blink example you are looking at or just Upload it to your board and see what happens.

    upload_2017-6-5_13-52-42.png

    Arduino development is done using AVR language.
    See also that neat getting started guide.

    Digital I/O

    From the above Blink example you should be able to set your pins high and low as you wish and visualise the results using LEDs on your breadboard.
    Here are the Arduino functions involved with controlling Digital I/O on Arduino:
    Those APIs offer individual pin level control and will provide best code portability across various Arduino hardware.
    However for our VFD application we will need our micro-controller to pass on significant amount of data from the USB host to the Noritake hardware.
    Doing that communication one bit at a time would be rather inefficient so we will need a solution to upload our data one byte at a time as both our hardware are 8-bit.
    Luckily Arduino provides means to do port manipulations and tap directly into our ATmega32U4 8-bit registers.

    Port manipulation

    Looking at the ATmega32U4 to Arduino Micro pin mapping you'll notice that only two ports offer full byte control: port B and port D.
    We decided to use port B for our data byte. Here is how the port B pins are laid out on the Arduino Micro PCB.

    ArduinoMicroPinoutPortB.png

    Here is our breadboard test circuit using 560 Ohm resistors:

    ArduinoMicroPortBCircuit.jpg

    We modified the Blink example as follow to validate our cabling:
    Code (C):
    1. byte offset=0;
    2. int blinkPeriodInMs = 250;
    3.  
    4. // the setup function runs once when you press reset or power the board
    5. void setup() {
    6.   // initialize digital pin LED_BUILTIN as an output.
    7.   pinMode(LED_BUILTIN, OUTPUT);
    8.   // Set port B pins as output
    9.   DDRB = B11111111;
    10. }
    11.  
    12. // the loop function runs over and over again forever
    13. void loop() {
    14.   // Set the one bit corresponding to current offset in our port register
    15.   PORTB = B00000001 << offset;
    16.   digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    17.   delay(blinkPeriodInMs);                       // wait for a second
    18.   digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    19.   delay(blinkPeriodInMs);                       // wait for a second
    20.   offset++; // Increase our offset making sure we light up the next LED
    21.   offset%=8; // Keep it between 0 and 7
    22. }
    We are now satisfied that our data lines can be conveniently written to using our port B register. We still also need another 2 pins to implement our VFD module protocol.
    • An output pin, called /WR, to signal data has been written and is ready for the display module to read.
    • An input pin, called RDY. The VFD module will use it to notify when it's ready, high or busy, low.
    Here again since we care more about efficiency than portability for this project we will use a port rather than the Digital I/O APIs to control those 2 pins.
    We decided to use port C for that purpose since it has only two lines available anyway.
    PC6 controls Digital Pin 5 and will be used for /WR.
    PC7 controls Digital Pin 13 and will be used for RDY.

    Arduino to VFD communication

    We upgraded our circuit to connect the /WR and RDY pins and we hooked in our VFD module.
    We implemented an AVR Sketch to exercise and debug our communication protocol between our micro-controller and our VFD module.
    Without the call to delayMicroseconds() we would lose characters in the traffic and get the following result:
    bad-vfd-timing.jpg
    Once we solved our timing issue our output remains aligned:
    good-vfd-timing.jpg

    Code (C):
    1. /*
    2.  * Noritake GU256x64D-3900B
    3.  * Character writting test
    4.  * By Stéphane Lenclud
    5.  */
    6.  
    7. const byte KRdyOffset = 7;
    8. const byte KWrOffset = 6;
    9.  
    10. /*
    11.  * Send a single byte to our VFD module
    12.  */
    13. void sendByte(byte aByte)
    14.   {
    15.   // Write data
    16.   PORTB = aByte;
    17.   // Bring /WR down to tell our display data is ready
    18.   PORTC &= B10111111;
    19.   // Make sure we wait long enough for our display to kick in
    20.   // This very is important otherwise some characters will be lost
    21.   // 108us was not long enough, characters would get lost.
    22.   // 109us seems very reliable
    23.   delayMicroseconds(109);
    24.   // Set /WR high up again
    25.   PORTC |= 1 << KWrOffset;
    26.   }
    27.  
    28. /*
    29.  * Clear VFD module screen
    30.  */
    31. void clearScreen()
    32.   {
    33.   sendByte(0x0C);
    34.   }
    35.  
    36. /*
    37.  * The setup function runs once when you press reset or power the board
    38.  */
    39. void setup()
    40.   {
    41.   // Set port B pins as output
    42.   DDRB = B11111111;
    43.   // Set /WR pins as output
    44.   DDRC = DDRC | B01000000;
    45.   // Set RDY as input
    46.   DDRC = DDRC & B01111111;
    47.   // Clear our screen and wait a bit for it to be noticeable as we come online
    48.   clearScreen();
    49.   delay(1000);
    50.   }
    51.  
    52. /*
    53.  * The loop function runs over and over again forever
    54.  */
    55. void loop()
    56.   {
    57.   sendByte('O');
    58.   sendByte('K');
    59.   sendByte('-');
    60.   }

    Those timing issues could also have been caused by our usage of Serial port logs as we found out later Serial usage would corrupt our HID traffic it seems.

    PC to Arduino communication using HID over USB

    For high speed communication from PC to Arduino we need to use generic HID also known as raw HID.
    HID is basically the protocol that enables your mice, keyboards and joysticks.
    Raw HID is a subset of that same protocol typically used for application specific devices such as our display module for instance.
    For Arduino to use raw HID you need to setup that HID-Project library in your IDE.
    Go to Sketch > Include Library > Manage Libraries then search and install HID-Project library.
    It comes with examples that should get you started.

    We were not able to send HID reports larger than 64 bytes. So we need to send multiple reports to push a whole frame to our display.
    This 64 bytes limitation was detailed in a GitHub issue.
    Other than that the implementation was rather straight forward. You can find details in our GitHub repository, look for .ino files if you are interested in the Arduino source code.

    Graphic DMA mode

    The above testing were done using the VFD module normal command mode. However for better performance we had to switch to Graphic DMA command mode.
    DMA mode allows you to tap directly into the display RAM thus gaining access to its frame buffers, on-screen and off-screen ones.

    To enable DMA mode you need to toggle the switch number 6 on the DIP of the PCB. That DIP features below in the bottom left corner of that picture.

    Noritake-GU256x64D-3900-DIP-switch.jpg

    Conclusion

    We were able to squeeze a stable 30 FPS driving that Noritake GU256x64D-3900 from our PC over an Arduino Micro.
    It's two to three times as fast as devices like the Futaba GP1212A0x and their built-in USB interface.
    We are confident performance could be improved further. Given enough time and resources it would be interesting to see how the Arduino raw HID stack could be improved.
    Alternatively the Arduino Micro could be replaced by a Teensy 3.2 to see if that boosts performance.

    One issue remains, when running sustained high frame rate, we noticed rare occurrence single pixel noise similar to what was caused by using Arduino Serial.write() as explained above.
    We are pretty sure this is caused by some Arduino core library somehow. It would be nice to fix but is not a show stopper.

    We will most certainly deploy that solution in a production environment at some point to see how stable it is.
    Noritake-GU256x64-39xx-and-Arduino-Micro.jpg

    References

     
    Last edited: Jun 9, 2017
    JulianTT likes this.
  2. ChesLans

    ChesLans New Member

    Hi...in my case my pins are not labeled like in any Noritake/Arduino tutorial/project I could find.I am at this point unsure if I can or can not power it using the arduino's 5v and gnd on pins 2 and 1, and what the other 3 pins mentioned would be on mine. I am guessing RS is reset, and R/W is read write, but am lost with sbusy.

    percentage calculator
     
    Last edited: Jul 16, 2018
    Stéphane Lenclud likes this.
  3. Stéphane Lenclud

    Stéphane Lenclud Founder Staff Member

    @ChesLans Could you get it working?
    I'm not quite sure what you are trying to achieve and which hardware you are using.
    I seriously doubt you can power up such a display with any Arduino power output.
    That GU256x64D-3900 needs 5V and 850mA.
    While developing I used a Molex Power supply. For the final solution it's mounted in a PC and draws power from an ATX PSU via Molex too.
     
  4. JulianTT

    JulianTT New Member

    Can a ESP32 be used?
     
    Stéphane Lenclud likes this.
  5. Stéphane Lenclud

    Stéphane Lenclud Founder Staff Member

    I don't see why not. You may want to check that the voltage on your pins are compatible with your display.
    Having said that I'm not familiar with that ESP32. Does it support Arduino like the Teensy does or is it a different tool chain?
    Are you working with that same Noritake display?
     
    JulianTT likes this.
  6. JulianTT

    JulianTT New Member

    The ESP32 logic level is 3.3V and I end up get a logic level converter. Then I noticed that the display works with a logic level between 0.3 and 5v. I have GU256x128d-3000 (not the B Gen). there is a new update that make it easy to connect the esp32 with the Arduino ide. The reason I want to use the esp32 is the WIFI feature and I’m also not too familiar with it. It has Dual core 32-bit MCU, Frequency 160 MHz, and SRAM 512 KB. Im pretty new to how electrons work, so Im not sure what all this mean.
     
    Stéphane Lenclud likes this.
  7. Stéphane Lenclud

    Stéphane Lenclud Founder Staff Member

    @JulianTT It seems you are pretty far along already. Just let me know if you think I can help you out with some specifics.
    You've probably seen it already but there is a follow up article about Teensy.
     
    JulianTT likes this.

Share This Page