Here is the code for this project

// Project 1 - Display Temperature on a scrolling 8x8 LED Matrix

#include <TimerOne.h>
#include <charEncodings.h>

//Pin connected to Pin 12 of 74HC595 (Latch)
int latchPin = 8;
//Pin connected to Pin 11 of 74HC595 (Clock)
int clockPin = 12;
//Pin connected to Pin 14 of 74HC595 (Data)
int dataPin = 11;

// pin for the potentiometer to control the scrolling speed
int potPin = 5;

// pin for reading the temperature
int tempPin = 4;

// this is the gobal array that represents what the matrix
// is currently displaying
uint8_t led[8];

void setup() {

  // set up for serial keyboard input

  //set pins to output
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(potPin, INPUT);
  pinMode(tempPin, INPUT);
  // defines the function that the Timer will run periodically

void loop() {

  long counter1 = 0;
  long counter2 = 0;

  char reading[10];
  char buffer[18];

  if (counter1++ >=100000) {
  if (counter2 >= 10000) {
    counter1 = 0;
    counter2 = 0;



  /*  if (isKeyboardInput()) {
   char readBuffer[50];
   Serial.println ("read: ");
   getKeyboardInput(readBuffer, 49);
   Serial.print (readBuffer);
   } */

void displayScrolledText(char* textToDisplay) {
  int textLen = strlen(textToDisplay);
  char charLeft, charRight;

  // scan through entire string one column at a time and call
  // function to display 8 columns to the right
  for (int col = 1; col <= textLen*8; col++) {

    // if (col-1) is exact multiple of 8 then only one character
    // involved, so just display that one
    if ((col-1) % 8 == 0 ) {
      char charToDisplay = textToDisplay[(col-1)/8];
      for (int j=0; j<8; j++)
        led[j] = charBitmaps[charToDisplay][j];
      int charLeftIndex = (col-1)/8;
      int charRightIndex = (col-1)/8+1;

      charLeft = textToDisplay[charLeftIndex];

      // check we are not off the end of the string
      if (charRightIndex <= textLen)
        charRight = textToDisplay[charRightIndex];
        charRight = ' ';
      setMatrixFromPosition(charLeft, charRight, (col-1) % 8);

    int delayTime = analogRead(potPin);

    delay (delayTime);

void setMatrixFromPosition(char charLeft, char charRight, int col) {

  // take col left most columns from left character and bitwise OR with 8-col from
  // the right character
  for (int j=0; j<8; j++) {
    led[j] = charBitmaps[charLeft][j] << col | charBitmaps[charRight][j] >> 8-col;

void screenUpdate() {

  uint8_t col = B00000001;

  for (byte k = 0; k < 8; k++) {
    digitalWrite(latchPin, LOW); // Open up the latch ready to receive data


    digitalWrite(latchPin, HIGH); // Close the latch, sending the registers data to the matrix
    col = col << 1;
  digitalWrite(latchPin, LOW);
  shiftIt(~0 );
  digitalWrite(latchPin, HIGH);

void shiftIt(byte dataOut) {
  // Shift out 8 bits LSB first,
  // on rising edge of clock

  boolean pinState;

  //clear shift register read for sending data
  digitalWrite(dataPin, LOW);

  // for each bit in dataOut send out a bit
  for (int i=0; i<=7; i++)  {
    //set clockPin to LOW prior to sending bit
    digitalWrite(clockPin, LOW);

    // if the value of DataOut and (logical AND) a bitmask
    // are true, set pinState to 1 (HIGH)
    if ( dataOut & (1<<i) ) {
      pinState = HIGH;
    else {
      pinState = LOW;

    //sets dataPin to HIGH or LOW depending on pinState
    digitalWrite(dataPin, pinState);
    //send bit out on rising edge of clock
    digitalWrite(clockPin, HIGH);
    digitalWrite(dataPin, LOW);

  //stop shifting
  digitalWrite(clockPin, LOW);

boolean isKeyboardInput() {

  // returns true is there is any characters in the keyboard buffer
  return (Serial.available() > 0);

void getKeyboardInput(char* readString, int readStringLen)
  // take a buffer readString and fill it with characters from the
  // keyboard stream up to readStringLen characters
  int index=0;
  int numChar;
  delay (500);
  while (numChar = Serial.available()) {
    while (numChar-- && (index < readStringLen)) {
      readString[index++] =;

  // terminate the string
  readString[index] = '\0';

void getTemp(char* reading) {

  int span = 20;
  int aRead = 0;
  long temp;
  char tmpStr[10];

  // average out several readings
  for (int i = 0; i < span; i++) {
    aRead = aRead+analogRead(tempPin);

  aRead = aRead / span;

  temp = ((100*1.1*aRead)/1024)*10;

  reading[0] = '\0';

  itoa(temp/10, tmpStr, 10);
  strcat(reading, ".");
  itoa(temp % 10, tmpStr, 10);
  strcat(reading, tmpStr);
  strcat(reading, "C");


The charEncodings.h file is as follows; I think there are a few errors in this but was good enough for my purposes.

 uint8_t charBitmaps[128][8] = {
 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // .
 {0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E}, // .
 {0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E}, // .
 {0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00}, // .
 {0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00}, // .
 {0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C}, // .
 {0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C}, // .
 {0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00}, // .
 {0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF}, // .
 {0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00}, // .
 {0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF}, // .
 {0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78}, // .
 {0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18}, // .
 {0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0}, // .
 {0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0}, // .
 {0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99}, // .
 {0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00}, // .
 {0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00}, // .
 {0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18}, // .
 {0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00}, // .
 {0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00}, // .
 {0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78}, // .
 {0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00}, // .
 {0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF}, // .
 {0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00}, // .
 {0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00}, // .
 {0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00}, // .
 {0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00}, // .
 {0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00}, // .
 {0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00}, // .
 {0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00}, // .
 {0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00}, // .
 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, //
 {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00}, // !
 {0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00}, // "
 {0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00}, // #
 {0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00}, // $
 {0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00}, // %
 {0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00}, // &
 {0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00}, // '
 {0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00}, // (
 {0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00}, // )
 {0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // *
 {0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00}, // +
 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60}, // ,
 {0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00}, // -
 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00}, // .
 {0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00}, // /
 {0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00}, // 0
 {0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00}, // 1
 {0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00}, // 2
 {0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00}, // 3
 {0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00}, // 4
 {0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00}, // 5
 {0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00}, // 6
 {0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00}, // 7
 {0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00}, // 8
 {0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00}, // 9
 {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00}, // :
 {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60}, // //
 {0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00}, // <
 {0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00}, // =
 {0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00}, // >
 {0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00}, // ?
 {0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00}, // @
 {0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00}, // A
 {0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00}, // B
 {0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00}, // C
 {0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00}, // D
 {0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00}, // E
 {0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00}, // F
 {0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00}, // G
 {0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00}, // H
 {0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, // I
 {0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00}, // J
 {0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00}, // K
 {0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00}, // L
 {0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00}, // M
 {0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00}, // N
 {0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00}, // O
 {0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00}, // P
 {0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00}, // Q
 {0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00}, // R
 {0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00}, // S
 {0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, // T
 {0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00}, // U
 {0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00}, // V
 {0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00}, // W
 {0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00}, // X
 {0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00}, // Y
 {0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00}, // Z
 {0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00}, // [
 {0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00}, // \
 {0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00}, // ]
 {0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00}, // ^
 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // _
 {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // `
 {0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00}, // a
 {0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00}, // b
 {0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00}, // c
 {0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00}, // d
 {0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00}, // e
 {0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00}, // f
 {0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8}, // g
 {0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00}, // h
 {0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00}, // i
 {0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78}, // j
 {0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00}, // k
 {0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, // l
 {0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00}, // m
 {0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00}, // n
 {0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00}, // o
 {0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0}, // p
 {0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E}, // q
 {0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00}, // r
 {0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00}, // s
 {0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00}, // t
 {0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00}, // u
 {0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00}, // v
 {0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00}, // w
 {0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00}, // x
 {0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8}, // y
 {0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00}, // z
 {0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00}, // {
 {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // |
 {0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00}, // }
 {0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ~
 {0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00}}; // .
JSN Boot template designed by