Question around special Characters

Hi guys, first post so please go easy!

I have no background in electronics or these things, but found it all quite interesting after seeing a post on youtube where someone connected his Arduino to his PC displaying all sorts of info using LCD Smartie. Ok so I thought I'd give it a go and got myself an Uno and a DFRobot 16 x 2 LCD Keypad Shield, which I believe is called a 1602 LCD??

Without too much trouble I managed to get a sample sketch altered to match the baud rate (9600) of the LCD and get the pins set up correctly. Setting LCD Smartie to use the Matrix Orbital DLL everything seems to work. I can get LCD Smartie to write to the LCD showing whatever information I want to display which is really neat.

The problem I have though is that when I go beyond the normal alphabet such as displaying a RSS weather feed, the 'degrees' symbol shows some garbage character. Also if I try to use any of the 'spectrum analyser' type plugins I get a lot of garbage. With the latter it all moves what seems to be correctly with sound output, but you don't get a nice graph interface etc.

Now from what I've understood from googling around is that this has something to do with special characters, but I am struggling to find information on how to solve this. I don't even know where to start.... does this have something to do with the Arduino sketch? Is is specific to the LCD, is it related to the MATRIX ORBITAL dll...?

In the sketch I found (which I am using) there are the following lines: case 104: //init horiz bar graph case 109: //init med size digits case 115: //init narrow vert bar graph case 118: //init wide vert bar graph

and I've not been able to find any documentation that explains the logic behind that. I've read through some Matrix Orbital documentation but could not quite figure out how that relates to the code...

Any help would be much appreciated.

PS. I am hoping to learn how to do something similar under Linux (without LCD SMARTIE of course) and then at a later stage see how to do the same using an OLED panel

BTW this is the sketch I am using with my alterations should that be of help?

A software emulator for Matrix Orbital character display commands on Arduino.

V1.5 28/12/2011
Added fixes by yosoyzenitram, prettified code a little and added all Matrix Obrital commands for display model LK204-25.

V1.0 6/2/2010
Coded by giannoug
Based on code by nuelectronics

You can use whatever screen size you want, but you will
have to make proper adjustments to both this file and at
LCDSmartie’s configuration menu or whatever program you
might use.

Matrix Orbital LK204-25 manual (for command reference):

The circuit (make sure to power the LCD):

  • LCD RS pin to digital pin 12
  • LCD E pin to digital pin 11
  • LCD D4 pin to digital pin 5
  • LCD D5 pin to digital pin 4
  • LCD D6 pin to digital pin 3
  • LCD D7 pin to digital pin 2
  • LCD Ve pin (contrast) to digital pin 6


#include <LiquidCrystal.h>

// You can define your own pins here.
#define RS 8
#define E 9
#define D4 4
#define D5 5
#define D6 6
#define D7 7
#define BR 0

#define VERSION 1

#define GPO1 8 // Not yet implemented. (pg. 18 of the manual)

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

void setup() {
// ford Serial.begin(19200); // Default baudrate.
Serial.begin(9600); // Default baudrate.
lcd.begin(16, 2); // Change this for other screen sizes.

analogWrite(BR, 0); // Set maximum brightness.

lcd.setCursor(1, 1);
lcd.print(“Matrix Orbital!”);

void loop() {
byte rxbyte = serial_getch(); // Command
byte temp; // Parameter

if (rxbyte == 254) {
switch (serial_getch()) {
case 71: // Set cursor position (2 parameters, column, row)
lcd.setCursor(serial_getch() - 1, serial_getch() - 1);
case 72: // Cursor home (doesn’t clear the screen!)
case 74: // Underline cursor on
case 75: // Underline cursor off
case 83: // Block cursor on
case 84: // Block cursor off
case 76: // Move cursor left
case 77: // Move cursor right
case 78: // Define custom character (2 parameters, id, data)
lcd.command(64 + (serial_getch() * 8));
for (temp = 7; temp != 0; temp—) {
//case 35: // Read serial number
//case 36: // Read version number
case 54: // Read version number
case 55: // Read module type
Serial.print(9); // 9 for LK204-25
case 80: // Set contrast (1 parameter, contrast)
analogWrite(BR, 0xFF-serial_getch());
case 81: // Auto scroll on
case 82: // Auto scroll off
case 86: // General Purpose Output off (1 parameter, number)
//temp = serial_getch();
//if (temp == 1) {
// digitalWrite(GPO1, LOW);
case 87: // General Purpose Output on (1 parameter, number)
//temp = serial_getch();
//if (temp == 0) {
// digitalWrite(GPO1, HIGH);
case 88: // Clear screen
case 35: // Place large number
case 38: // Poll key presses
case 51: // Change I2C slave address (1 parameter, address)
case 57: // Change baud rate (1 parameter, baud rate)
case 59: // Exit flow-control mode
case 61: // Place vertical bar (2 parameters, column, length)
case 64: // Change the startup screen
case 65: // Auto transmit keypresses on
case 67: // Auto line wrap on
case 68: // Auto line wrap off
case 66: // Backlight on (1 parameter, minutes)
case 69: // Clear key buffer
case 70: // Backlight off
case 79: // Auto transmit keypress off
case 85: // Set debounce time (1 paramater, time)
case 96: // Auto repeat mode off
case 152: // Set and save brightness (1 parameter, brightness)
case 153: // Set backlight brightness (1 parameter, brightness)
case 104: // Initialize horizontal bar
case 109: // Initialize medium number
case 110: // Initialize lange numbers
case 111: // Place medium numbers
case 115: // Initialize narrow vertical bar
case 118: // Initialize wide vertical bar
case 124: // Place horizontal bar graph (4 parameters, column, row, direction, length)
case 126: // Set auto repeat mode (1 parameter, mode)
case 145: // Set and save contrast (1 parameter, contrast)
case 160: // Transmission protocol select (1 parameter, protocol)
case 192: // Load custom characters (1 parameter, bank)
case 164: // Setting a non-standart baudrate (1 parameter, speed)
case 193: // Save custom character (3 parameters, bank, id, data)
case 194: // Save startup screen custom characters (2 parameters, id, data)
case 195: // Set startup GPO state (2 parameters, number, state)
case 200: // Dallas 1-Wire
switch (serial_getch()) {
case 1: // Dallas 1-Wire transaction (6 parameters, flags, send, bits, receive, bits, data)
case 2: // Search for a 1-Wire device
case 213: // Assign keypad codes
/* All other commands are ignored
and parameter byte is discarded. */
temp = serial_getch();
return; // Stop and start again.

// Otherwise its a plain char so we print it to the LCD.


  • Waits for a byte to be available, reads and returns it.
    byte serial_getch() {
    while (Serial.available() == 0);


Maybe this will help,135955.0.html

If you want something more than plain vanilla alphanumeric, you might be better off with a graphics LCD like the 5110

I eventually found the answer to the garbage characters so hopefully this will help someone:

I just changed the 'print' to 'write' in the code:

case 78: // Define custom character (2 parameters, id, data) lcd.command(64 + (serial_getch() * 8)); for (temp = 7; temp != 0; temp--) { //lcd.print(serial_getch()); lcd.write(serial_getch()); } break;

So just to re-iterate the problem (which might give the Google Spider half a chance to pick it up)

Using a DR Robot (DFRobot) LCD Keypad Shield with the sample code above / below to get info from LCD Smartie I got rubbish / garbage characters when implementing any of the various LCD Smartie plugins for 'Spectrum Analyser' type results.

To interface with LCD Smartie I used the Matrix Orbital driver and to get bar graphs showing correctly the special character line in the code above seems to fail when using lcd.print.

To get LCD Smartie to show a spectrum analyser for any sound coming out of your machine I used the Volume7.dll implemented like this for example '$Bar($dll(Volume7.dll,2,,),100,30)' or the SPC plugin like this '$dll(SPC,1,1#1#10,16)' etc.