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
Serial.begin(9600);
Serial.flush();
//set pins to output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(potPin, INPUT);
pinMode(tempPin, INPUT);
analogReference(INTERNAL);
// defines the function that the Timer will run periodically
Timer1.initialize(10000);
Timer1.attachInterrupt(screenUpdate);
}
void loop() {
long counter1 = 0;
long counter2 = 0;
char reading[10];
char buffer[18];
if (counter1++ >=100000) {
counter2++;
}
if (counter2 >= 10000) {
counter1 = 0;
counter2 = 0;
}
getTemp(reading);
displayScrolledText(reading);
/* if (isKeyboardInput()) {
char readBuffer[50];
Serial.println ("read: ");
getKeyboardInput(readBuffer, 49);
Serial.print (readBuffer);
Serial.flush();
} */
}
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];
}
}
else
{
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];
}
else
{
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
shiftIt(~led[7-k]);
shiftIt(col);
digitalWrite(latchPin, HIGH); // Close the latch, sending the registers data to the matrix
col = col << 1;
}
digitalWrite(latchPin, LOW);
shiftIt(~0 );
shiftIt(255);
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++] = Serial.read();
}
}
// 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,tmpStr);
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}}; // .