Direct drive 8x8 Led matrix message - changing text

I'm a newbie trying to figure out how to change the message being displayed on this direct drive 8x8 led matrix.
In the example code below it only works with the patterns variable that I need some help to figure out how to update in the void loop. What I'm looking to do is just display the time taken from an RTC (ds1307).

Any help would be much appreciated!

http://playground.arduino.cc/Main/DirectDriveLEDMatrix

/*
 * Show messages on an 8x8 led matrix,
 * scrolling from right to left.
 *
 * Uses FrequencyTimer2 library to
 * constantly run an interrupt routine
 * at a specified frequency. This
 * refreshes the display without the
 * main loop having to do anything.
 *
 */

#include <FrequencyTimer2.h>

#define SPACE { \
    {0, 0, 0, 0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0} \
}

#define H { \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}  \
}

#define E  { \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define L { \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}

#define O { \
    {0, 0, 0, 1, 1, 0, 0, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 0, 0, 1, 1, 0, 0, 0}  \
}

byte col = 0;
byte leds[8][8];

// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[17]= {-1, 5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};

// col[xx] of leds = pin yy on led matrix
int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[06], pins[11], pins[15], pins[16]};

// row[xx] of leds = pin yy on led matrix
int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};

const int numPatterns = 6;
byte patterns[numPatterns][8][8] = {
  H,E,L,L,O,SPACE
};

int pattern = 0;

void setup() {
  // sets the pins as output
  for (int i = 1; i <= 16; i++) {
    pinMode(pins[i], OUTPUT);
  }

  // set up cols and rows
  for (int i = 1; i <= 8; i++) {
    digitalWrite(cols[i - 1], LOW);
  }

  for (int i = 1; i <= 8; i++) {
    digitalWrite(rows[i - 1], LOW);
  }

  clearLeds();

  // Turn off toggling of pin 11
  FrequencyTimer2::disable();
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(display);

  setPattern(pattern);
}

void loop() {
    pattern = ++pattern % numPatterns;
    slidePattern(pattern, 60);
}

void clearLeds() {
  // Clear display array
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = 0;
    }
  }
}

void setPattern(int pattern) {
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = patterns[pattern][i][j];
    }
  }
}

void slidePattern(int pattern, int del) {
  for (int l = 0; l < 8; l++) {
    for (int i = 0; i < 7; i++) {
      for (int j = 0; j < 8; j++) {
        leds[j][i] = leds[j][i+1];
      }
    }
    for (int j = 0; j < 8; j++) {
      leds[j][7] = patterns[pattern][j][0 + l];
    }
    delay(del);
  }
}

// Interrupt routine
void display() {
  digitalWrite(cols[col], LOW);  // Turn whole previous column off
  col++;
  if (col == 8) {
    col = 0;
  }
  for (int row = 0; row < 8; row++) {
    if (leds[col][7 - row] == 1) {
      digitalWrite(rows[row], LOW);  // Turn on this led
    }
    else {
      digitalWrite(rows[row], HIGH); // Turn off this led
    }
  }
  digitalWrite(cols[col], HIGH); // Turn whole column on at once (for equal lighting times)
}

Hi, 2 things to work on next: 1. Define the shapes you want for the digits 0 to 9, colon, am/pm indicator or whatever. 2. Get a simple rtc sketch working which reads the time from the rtc and prints the time to the serial monitor. Then post them here and we can look at how to merge to two sketches.

If you have not purchased an rtc yet, get a ds3231 module rather than ds1307. Just as cheap but more accurate and has built-in temperature sensor so you could display that too.

Paul

thanks,
So this is how I get the time from the RTC. I'm basically taking the time and converting to a four digit INT, then over to an text array. So the problem is in how to update this "hard coded" variable char patterns on line 156.

I've tried calling the different functions inside the void loop to set the time, but no luck.

/*
 * Show messages on an 8x8 led matrix,
 * scrolling from right to left.
 *
 * Uses FrequencyTimer2 library to
 * constantly run an interrupt routine
 * at a specified frequency. This
 * refreshes the display without the
 * main loop having to do anything.
 *
 */

#include <FrequencyTimer2.h>
#include <Time.h>  
#include <DS3232RTC.h>
#include <Wire.h> 
int nu = 8888; // time variable
char tiden[5] = "0000"; // for the time
String stringNu =  String('3333');  //for the time

#define S { \
    {0, 0, 0, 0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0} \
  }

#define Z { \  // zero
{0, 0, 0, 1, 1, 0, 0, 0}, \
{0, 0, 1, 0, 0, 1, 0, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 1, 0, 0, 1, 0, 0}, \
{0, 0, 0, 1, 1, 0, 0, 0}  \
}

#define A { \  // one
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 1, 1, 0, 0, 0, 0}, \
{0, 1, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 1, 1, 1, 1, 1, 0, 0}, \
}

#define B { \  // two
{0, 0, 0, 1, 1, 1, 0, 0}, \
{0, 0, 1, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 1, 0, 0}, \
{0, 0, 0, 0, 1, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 1, 0, 0, 0, 0, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
}

#define C { \   // three
{0, 0, 1, 1, 1, 0, 0, 0}, \
{0, 1, 0, 0, 0, 1, 0, 0}, \
{0, 0, 0, 0, 0, 1, 0, 0}, \
{0, 0, 1, 1, 1, 0, 0, 0}, \
{0, 0, 0, 0, 0, 1, 0, 0}, \
{0, 0, 0, 0, 0, 1, 0, 0}, \
{0, 1, 0, 0, 0, 1, 0, 0}, \
{0, 0, 1, 1, 1, 0, 0, 0}, \
}

#define D {\   // four
{0, 0, 0, 0, 0, 1, 1, 0}, \
{0, 0, 0, 0, 1, 0, 1, 0}, \
{0, 0, 0, 1, 0, 0, 1, 0}, \
{0, 0, 1, 0, 0, 0, 1, 0}, \
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
}


#define E {\  // five
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 1, 0, 0, 0, 0, 0, 0}, \
{0, 1, 0, 0, 0, 0, 0, 0}, \
{0, 1, 0, 1, 1, 1, 0, 0}, \
{0, 1, 1, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 1, 1, 1, 1, 1, 0, 0}, \
}

#define F {\  //six
{0, 0, 1, 1, 1, 0, 0, 0}, \
{0, 1, 0, 0, 0, 1, 0, 0}, \
{0, 1, 0, 0, 0, 0, 0, 0}, \
{0, 1, 0, 0, 0, 0, 0, 0}, \
{0, 1, 1, 1, 1, 0, 0, 0}, \
{0, 1, 0, 0, 0, 1, 0, 0}, \
{0, 1, 0, 0, 0, 1, 0, 0}, \
{0, 0, 1, 1, 1, 0, 0, 0}, \
}

#define G {\ //seven
{0, 1, 1, 1, 1, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 1, 0, 0}, \
{0, 0, 0, 0, 1, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
{0, 0, 0, 1, 0, 0, 0, 0}, \
}

#define H {\ //eight
{0, 0, 1, 1, 1, 1, 0, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 1, 1, 1, 1, 0, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 1, 1, 1, 1, 0, 0}, \
}

#define I {\   //nine
{0, 0, 1, 1, 1, 1, 0, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 1, 1, 1, 1, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 0, 0, 0, 0, 0, 1, 0}, \
{0, 1, 0, 0, 0, 0, 1, 0}, \
{0, 0, 1, 1, 1, 1, 0, 0}, \
}

byte col = 0;
byte leds[8][8];

// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[17] = { -1, 5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};

// col[xx] of leds = pin yy on led matrix
int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[06], pins[11], pins[15], pins[16]};

// row[xx] of leds = pin yy on led matrix
int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};

const int numPatterns = 5;
char patterns[numPatterns][8][8] = {
  Z, Z, Z, Z,
};

int pattern = 0;

void setup() {

  setSyncProvider(RTC.get); //get time from RTC
  Serial.begin (9600);

  // sets the pins as output
  for (int i = 1; i <= 16; i++) {
    pinMode(pins[i], OUTPUT);

  }

  // set up cols and rows
  for (int i = 1; i <= 8; i++) {
    digitalWrite(cols[i - 1], LOW);
  }

  for (int i = 1; i <= 8; i++) {
    digitalWrite(rows[i - 1], LOW);
  }

  clearLeds();

  // Turn off toggling of pin 11
  FrequencyTimer2::disable();
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(display);

  setPattern(pattern);
}

void loop() {

  nu = hour() * 100 + minute(); // convert time to 4 digit int
  stringNu =  String(nu); // convert time to string
  stringNu.toCharArray(tiden, 5); //
  for (int i = 0; i < 4; i++) {
    if (tiden[i] == '0') tiden[i] = 'Z';
    if (tiden[i] == '1') tiden[i] = 'A';
    if (tiden[i] == '2') tiden[i] = 'B';
    if (tiden[i] == '3') tiden[i] = 'C';
    if (tiden[i] == '4') tiden[i] = 'D';
    if (tiden[i] == '5') tiden[i] = 'E';
    if (tiden[i] == '6') tiden[i] = 'F';
    if (tiden[i] == '7') tiden[i] = 'G';
    if (tiden[i] == '8') tiden[i] = 'H';
    if (tiden[i] == '9') tiden[i] = 'I';
   }
  
  char patterns[numPatterns][8][8] = {
    tiden[0], tiden[1], tiden[2], tiden[3],
  };

  pattern = ++pattern % numPatterns;
  slidePattern(pattern, 60);
}

void clearLeds() {
  // Clear display array
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = 0;
    }
  }
}

void setPattern(int pattern) {

  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = patterns[pattern][i][j];
    }
  }
}

void slidePattern(int pattern, int del) {
  for (int l = 0; l < 8; l++) {
    for (int i = 0; i < 7; i++) {
      for (int j = 0; j < 8; j++) {
        leds[j][i] = leds[j][i + 1];
      }
    }
    for (int j = 0; j < 8; j++) {

      leds[j][7] = patterns[pattern][j][0 + l];
    }
    delay(del);
  }
}

// Interrupt routine
void display() {
  digitalWrite(cols[col], LOW);  // Turn whole previous column off
  col++;
  if (col == 8) {
    col = 0;
  }
  for (int row = 0; row < 8; row++) {
    if (leds[col][7 - row] == 1) {
      digitalWrite(rows[row], LOW);  // Turn on this led
    }
    else {
      digitalWrite(rows[row], HIGH); // Turn off this led
    }
  }
  digitalWrite(cols[col], HIGH); // Turn whole column on at once (for equal lighting times)
}

I've tried to call the various functions in this example but I can't seem to update the text this 8x8 led display.
Anybody got an idea?

Hi,

I have tried to fix it for you but I can't test it, so it may take some debugging!

I have condensed the patterns so they are packed into bytes to reduce the amount of memory needed. I have also attempted to simplify things in various ways, so feel free to ask about any particular changes. Other than that I tried to keep my changes to a minimum, but there turned out to be quite a few by the end.

/*
 * Show messages on an 8x8 led matrix,
 * scrolling from right to left.
 *
 * Uses FrequencyTimer2 library to
 * constantly run an interrupt routine
 * at a specified frequency. This
 * refreshes the display without the
 * main loop having to do anything.
 *
 */

#include <FrequencyTimer2.h>
#include <Time.h>  
#include <DS3232RTC.h>
#include <Wire.h> 

const byte patterns[12][8] = { 
  {
    0b00011000,
    0b00100100,
    0b01000010,
    0b01000010,
    0b01000010,
    0b01000010,
    0b00100100,
    0b00011000
  },   
  {
    0b00010000,
    0b00110000,
    0b01010000,
    0b00010000,
    0b00010000,
    0b00010000,
    0b00010000,
    0b01111100
  },
  {
    0b00011100,
    0b00100010,
    0b00000010,
    0b00000100,
    0b00001000,
    0b00010000,
    0b00100000,
    0b01111110
  },
  {
    0b00111000,
    0b01000100,
    0b00000100,
    0b00111000,
    0b00000100,
    0b00000100,
    0b01000100,
    0b00111000
  },
  {
    0b00000110,
    0b00001010,
    0b00010010,
    0b00100010,
    0b01111110,
    0b00000010,
    0b00000010,
    0b00000010
  },
  {
    0b01111110,
    0b01000000,
    0b01000000,
    0b01011100,
    0b01100010,
    0b01000010,
    0b00000010,
    0b01111100
  },
  {  
    0b00111000,
    0b01000100,
    0b01000000,
    0b01000000,
    0b01111000,
    0b01000100,
    0b01000100,
    0b00111000
  },
  {
    0b01111110,
    0b00000010,
    0b00000100,
    0b00001000,
    0b00010000,
    0b00010000,
    0b00010000,
    0b00010000
  },
  {
    0b00111100,
    0b01000010,
    0b01000010,
    0b00111100,
    0b01000010,
    0b01000010,
    0b01000010,
    0b00111100
  },
  {
    0b00111100,
    0b01000010,
    0b01000010,
    0b00111110,
    0b00000010,
    0b00000010,
    0b01000010,
    0b00111100
  },
  {
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000,
    0b00000000
  },
  {
    0b00000000,
    0b00011000,
    0b00011000,
    0b00000000,
    0b00000000,
    0b00011000,
    0b00011000,
    0b00000000
  }
};

#define COLON 10
#define SPACE 11
 
byte col = 0;
byte leds[8][8];

// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[17] = { -1, 5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};

// col[xx] of leds = pin yy on led matrix
int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[06], pins[11], pins[15], pins[16]};

// row[xx] of leds = pin yy on led matrix
int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};

void setup() {

  setSyncProvider(RTC.get); //get time from RTC
  Serial.begin (9600);

  // sets the pins as output
  for (int i = 1; i <= 16; i++) {
    pinMode(pins[i], OUTPUT);

  }

  // set up cols and rows
  for (int i = 1; i <= 8; i++) {
    digitalWrite(cols[i - 1], LOW);
  }

  for (int i = 1; i <= 8; i++) {
    digitalWrite(rows[i - 1], LOW);
  }

  clearLeds();

  // Turn off toggling of pin 11
  FrequencyTimer2::disable();
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(display);

}

void loop() {

  slidePattern(hour() / 10, 60);
  slidePattern(hour() % 10, 60);
  slidePattern(COLON, 60);
  slidePattern(minute() / 10, 60);
  slidePattern(minute() % 10, 60);
  slidePattern(SPACE, 60);

}

void clearLeds() {
  // Clear display array
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = 0;
    }
  }
}

void setPattern(int pattern) {

  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = bitRead(patterns[pattern][i], j);
    }
  }
}

void slidePattern(int pattern, int del) {
  for (int l = 0; l < 8; l++) {
    for (int i = 0; i < 7; i++) {
      for (int j = 0; j < 8; j++) {
        leds[j][i] = leds[j][i + 1];
      }
    }
    for (int j = 0; j < 8; j++) {

      leds[j][7] = bitRead(patterns[pattern][j],l);
    }
    delay(del);
  }
}

// Interrupt routine
void display() {
  digitalWrite(cols[col], LOW);  // Turn whole previous column off
  col++;
  if (col == 8) {
    col = 0;
  }
  for (int row = 0; row < 8; row++) {
    if (leds[col][7 - row] == 1) {
      digitalWrite(rows[row], LOW);  // Turn on this led
    }
    else {
      digitalWrite(rows[row], HIGH); // Turn off this led
    }
  }
  digitalWrite(cols[col], HIGH); // Turn whole column on at once (for equal lighting times)
}

Wow thanks, Paul! It works with a little twist. The sequence of the numbers are correct, but the digits are mirrored.
As you mentioned the ds3231 I went to get one so now I'll try to integrate the temperature to display.

korv:
the digits are mirrored.

Ah, ok, change:

void slidePattern(int pattern, int del) {
  for (int l = 0; l < 8; l++) {

to:

void slidePattern(int pattern, int del) {
  for (int l = 7; l >= 0; l--) {

Also I noticed I made a mistake, so make these changes:

#define COLON 11
#define SPACE 10

If that fixes it, it would be good to see a video of it working.

Just had 5 minutes to test and yes it works fine! Thanks for your help.