Help with controlling display

Hi,

I am working with a nice display SCD 55104A, data sheet here: http://www.mouser.com/ds/2/311/0.145%20%20%20%20%2010-Character%205x5%20Dot%20Matrix%20Serial%20Input-335490.pdf)

I found a good 5x5 font to use, but I can only write up to the letter ‘T’ with the approach I cam using.

Here is my code:

// standard ascii 5x5 font
static unsigned char Font5x5[] = {
  // ' ':
  0x00, 0x20, 0x40, 0x60, 0x80,
  // '!':
  0x04, 0x24, 0x44, 0x60, 0x84,
  // '"':
  0x0A, 0x2A, 0x40, 0x60, 0x80,
  // '#':
  0x0A, 0x3F, 0x4A, 0x7F, 0x8A,
  // '

The idea is to get the five hex codes from the array and send them out to the display.

When I get to the part in this code where I expect to write ‘X’, I get a messy blob of a character on the display.
I expect the serial output to be

11
2A
44
6A
91

instead I get:

9E
19
3A
44
6B

I’ve probably left out crucial details, or made a silly mistake here. If anyone can help, I really appreciate it.

Thanks.
:
  0x0F, 0x34, 0x4E, 0x65, 0x9E,
  // ‘%’:
  0x19, 0x3A, 0x44, 0x6B, 0x93,
  // ‘&’:
  0x08, 0x34, 0x4D, 0x72, 0x8D,
  // ‘’’:
  0x04, 0x24, 0x40, 0x60, 0x80,
  // ‘(’:
  0x02, 0x24, 0x44, 0x64, 0x82,
  // ‘)’:
  0x08, 0x24, 0x44, 0x64, 0x88,
  // '’:
  0x15, 0x2E, 0x5F, 0x6E, 0x95,
  // ‘+’:
  0x04, 0x24, 0x5F, 0x64, 0x84,
  // ‘,’:
  0x00, 0x20, 0x40, 0x64, 0x84,
  // ‘-’:
  0x00, 0x20, 0x4E, 0x60, 0x80,
  // ‘.’:
  0x00, 0x20, 0x40, 0x60, 0x84,
  // ‘/’:
  0x01, 0x22, 0x44, 0x68, 0x90,
  // ’ 0 ':
  0x0E, 0x33, 0x55, 0x79, 0x8E,
  // ’ 1 ':
  0x04, 0x2C, 0x44, 0x64, 0x8E,
  // ’ 2 ':
  0x1E, 0x21, 0x46, 0x68, 0x9F,
  // ’ 3 ':
  0x1E, 0x21, 0x4E, 0x61, 0x9E,
  // ’ 4 ':
  0x06, 0x2A, 0x5F, 0x62, 0x82,
  // ’ 5 ':
  0x1F, 0x30, 0x5E, 0x61, 0x9E,
  // ’ 6 ':
  0x06, 0x28, 0x5E, 0x71, 0x8E,
  // ’ 7 ':
  0x1F, 0x22, 0x44, 0x68, 0x88,
  // ’ 8 ':
  0x0E, 0x31, 0x4E, 0x71, 0x8E,
  // ’ 9 ':
  0x0E, 0x31, 0x4F, 0x62, 0x8C,
  // ‘:’:
  0x00, 0x24, 0x40, 0x64, 0x80,
  // ‘;’:
  0x00, 0x24, 0x40, 0x6C, 0x80,
  // ’ < ':
  0x02, 0x24, 0x48, 0x64, 0x82,
  // ’ = ':
  0x00, 0x3F, 0x40, 0x7F, 0x80,
  // ’ > ‘:
  0x08, 0x24, 0x42, 0x64, 0x88,
  // ‘?’:
  0x0E, 0x31, 0x42, 0x64, 0x84,
  // ‘@’:
  0x0E, 0x35, 0x57, 0x70, 0x8E,
  // ‘A’:
  0x04, 0x2A, 0x5F, 0x71, 0x91, 
  // ‘B’:
  0x1E, 0x29, 0x4E, 0x69, 0x9E, 
  // ‘C’:
  0x0F, 0x30, 0x50, 0x70, 0x8F, 
  // ‘D’:
  0x1E, 0x29, 0x49, 0x69, 0x9E, 
  // ‘E’:
  0x1F, 0x30, 0x5E, 0x70, 0x9F, 
  // ‘F’:
  0x1F, 0x30, 0x5E, 0x70, 0x90, 
  // ‘G’:
  0x0F, 0x30, 0x53, 0x71, 0x8F, 
  // ‘H’:
  0x11, 0x31, 0x5F, 0x71, 0x91, 
  // ‘I’:
  0x0E, 0x24, 0x44, 0x64, 0x8E, 
  // ‘J’:
  0x01, 0x21, 0x41, 0x71, 0x8E, 
  // ‘K’:
  0x13, 0x34, 0x58, 0x74, 0x93, 
  // ‘L’:
  0x10, 0x30, 0x50, 0x70, 0x9F, 
  // ‘M’:
  0x11, 0x3B, 0x55, 0x71, 0x91, 
  // ‘N’:
  0x11, 0x39, 0x55, 0x73, 0x91, 
  // ‘O’:
  0x0E, 0x31, 0x51, 0x71, 0x8E, 
  // ‘P’:
  0x1E, 0x31, 0x5E, 0x70, 0x90, 
  // ‘Q’:
  0x0C, 0x32, 0x56, 0x72, 0x8D, 
  // ‘R’:
  0x1E, 0x31, 0x5E, 0x74, 0x92, 
  // ‘S’:
  0x0F, 0x30, 0x4E, 0x61, 0x9E, 
  // ‘T’:
  0x1F, 0x24, 0x44, 0x64, 0x84, 
  // ‘U’:
  0x11, 0x31, 0x51, 0x71, 0x8E, 
  // ‘V’:
  0x11, 0x31, 0x51, 0x6A, 0x84, 
  // ‘W’:
  0x11, 0x31, 0x55, 0x7B, 0x91, 
  // ‘X’:
  0x11, 0x2A, 0x44, 0x6A, 0x91, 
  // ‘Y’:
  0x11, 0x2A, 0x44, 0x64, 0x84, 
  // ‘Z’:
  0x1F, 0x22, 0x44, 0x68, 0x9F, 
  // ‘[’:
  0x07, 0x24, 0x44, 0x64, 0x87,
  // ‘’ :
  0x10, 0x28, 0x44, 0x62, 0x81,
  // ‘]’ :
  0x1C, 0x24, 0x44, 0x64, 0x9C,
  // ‘^’:
  0x04, 0x2A, 0x51, 0x60, 0x80,
  // ‘_’:
  0x00, 0x20, 0x40, 0x60, 0x9F,
  // ‘’’:
  0x0A, 0x2A, 0x40, 0x60, 0x80,
  // ‘a’:
  0x00, 0x2E, 0x52, 0x72, 0x8D, 
  // ‘b’:
  0x10, 0x30, 0x5E, 0x71, 0x9E, 
  // ‘c’:
  0x00, 0x2F, 0x50, 0x70, 0x8F, 
  // ‘d’:
  0x01, 0x21, 0x4F, 0x71, 0x8F, 
  // ‘e’:
  0x00, 0x2E, 0x5F, 0x70, 0x8E, 
  // ‘f’:
  0x04, 0x2A, 0x48, 0x7C, 0x88, 
  // ‘g’:
  0x00, 0x2F, 0x50, 0x73, 0x8F, 
  // ‘h’:
  0x10, 0x30, 0x56, 0x79, 0x91, 
  // ‘i’:
  0x04, 0x20, 0x4C, 0x64, 0x8E, 
  // ‘j’:
  0x00, 0x26, 0x42, 0x72, 0x8C, 
  // ‘k’:
  0x10, 0x30, 0x56, 0x78, 0x96, 
  // ‘l’:
  0x0C, 0x24, 0x44, 0x64, 0x8E, 
  // ‘m’:
  0x00, 0x2A, 0x55, 0x71, 0x91, 
  // ‘n’:
  0x00, 0x36, 0x59, 0x71, 0x91, 
  // ‘o’:
  0x00, 0x2E, 0x51, 0x71, 0x8E, 
  // ‘p’:
  0x00, 0x3E, 0x51, 0x7E, 0x90, 
  // ‘q’:
  0x00, 0x2F, 0x51, 0x6F, 0x81, 
  // ‘r’:
  0x00, 0x33, 0x54, 0x78, 0x90, 
  // ‘s’:
  0x00, 0x23, 0x44, 0x62, 0x8C, 
  // ‘t’:
  0x08, 0x3C, 0x48, 0x6A, 0x84, 
  // ‘u’:
  0x00, 0x32, 0x52, 0x72, 0x8D, 
  // ‘v’:
  0x00, 0x31, 0x51, 0x6A, 0x84, 
  ///

  // ‘w’:
  0x00, 0x31, 0x55, 0x7B, 0x91, 
  // ‘x’:
  0x00, 0x32, 0x4C, 0x6C, 0x92, 
  // ‘y’:
  0x00, 0x31, 0x4A, 0x64, 0x98, 
  // ‘z’:
  0x00, 0x3E, 0x44, 0x68, 0x9E, 
  // ’ { ':
  0x06, 0x24, 0x48, 0x64, 0x86,
  // ‘|’:
  0x04, 0x24, 0x44, 0x64, 0x84,
  // ’ } ':
  0x0C, 0x24, 0x42, 0x64, 0x8C,
  // ‘~’:
  0x00, 0x27, 0x5C, 0x60, 0x80,
};

// Pin connections to display
const int loadPin  = 7;
const int sdataPin = 8;
const int sdclkPin = 9;

void setup(){
  //pull RST and CLKSEL HIGH
  pinMode(3, OUTPUT);
  digitalWrite(3, HIGH);
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  Serial.begin(9600);
}

void writeByte(const char a) {
  digitalWrite(loadPin, LOW);
  for (int b = 0; b <= 7; b++) {
    digitalWrite(sdataPin, bitRead(a, b));
    digitalWrite(sdclkPin, HIGH);
    digitalWrite(sdclkPin, LOW);
  }
  digitalWrite(loadPin, HIGH);
}

void writeChar(byte c){
  byte d = (c - 0x20) *5;
  for (int i = 0; i < 5; i++) {
    writeByte(Font5x5[d + i]);
    Serial.println(Font5x5[d + i], HEX);
  }
  Serial.println();
}

void displayChar(const char myChar, int myPos){
  switch(myPos){
  case 0:
    writeByte(0xB0);
    break;
  case 1:
    writeByte(0xB1);
    break;
  case 2:
    writeByte(0xB2);
    break;
  case 3:
    writeByte(0xB3);
    break;
  case 4:
    writeByte(0xB4);
    break;
  case 5:
    writeByte(0xB5);
    break;
  case 6:
    writeByte(0xB6);
    break;
  case 7:
    writeByte(0xB7);
    break;
  case 8:
    writeByte(0xB8);
    break;
  case 9:
    writeByte(0xB9);
    break;
  }
  writeChar(myChar);
  delay(1000);
}

void displayBegin()
{
  pinMode(loadPin,  OUTPUT);
  pinMode(sdataPin, OUTPUT);
  pinMode(sdclkPin, OUTPUT);
  //reset the display
  writeByte(0xC0);

}

void loop(){
  displayBegin();
  displayChar(‘A’, 0);
  displayChar(‘B’, 1);
//THIS DOESN’T WORK
  displayChar(‘X’, 2);
  displayChar(‘1’, 3);
  displayChar(‘S’, 4);
  displayChar(‘T’, 5);
  displayChar(‘M’, 6);

//move to digit 9
  writeByte(0xB9);
  //and write a “Z”
  writeByte(0x1F);
  writeByte(0x22);
  writeByte(0x44);
  writeByte(0x68);
  writeByte(0x9F);
  delay(10000);

}


The idea is to get the five hex codes from the array and send them out to the display. 

When I get to the part in this code where I expect to write 'X', I get a messy blob of a character on the display. 
I expect the serial output to be 

11
2A
44
6A
91

instead I get:

9E
19
3A
44
6B

I've probably left out crucial details, or made a silly mistake here. If anyone can help, I really appreciate it. 

Thanks.

You are using a byte for 'd'. When you get to character 83 ('S') and do the math you get an index of 255, the largest number that will fit in a byte. When you go to character 84 ('T') you get 260 which gets truncated to 4 to fit in the byte.

Change 'd' from byte to int.

Wow! Thanks you very much. I figured I was rolling over somewhere. I didn't even think about the index.

You are exactly correct.

As a bonus question, does anyone know how I could change this to put the array in PROGMEM, and then reference it? I'd like to save some space.

Thanks!

Jimmy

Hi Jimmy

Try this ...

PROGMEM static unsigned char Font5x5[] = {
    writeByte(pgm_read_byte(&Font5x5[d + i]));
    Serial.println(pgm_read_byte(&Font5x5[d + i]), HEX);

Regards

Ray

Seems like if I go

#include <avr/pgmspace.h>

static unsigned char Font5x5[] PROGMEM = { ...... }

and then access it by:

writeByte(pgm_read_word(&Font5x5[d + i]));

It works, but I don’t know how I can tell if I’m saving SRAM?

Thanks Hackscribble, Looks like we posted at the same time. This seems to work.

You can use this function to check how much SRAM is available. Include it in both versions of your program (original and PROGMEM) and compare the values returned.

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}
Serial.println(freeRam());

Free = 1839 vs. 1363

How cool is that?

Thanks very much for the info.

Jimmy