Project tutorial
Big LED Matrix Clock

Big LED Matrix Clock © GPL3+

Alarm clock on homemade 24x6 matrix with 144 8mm white LEDs.

  • 16 views
  • 0 comments
  • 0 respects

Components and supplies

Necessary tools and machines

09507 01
Soldering iron (generic)

Apps and online services

About this project

About five years ago I made a Led matrix 24x6 according to descriptions on instructales (https://www.instructables.com/id/Make-a-24X6-LED-matrix/) and I modified the project by adding a Bluetooth connection so that the content of the text can be entered wirelessly via a smartphone.

This device, by adding only real-time clock module we can convert it into a nice big alarm clock so that depending on which code is uploaded it can be switched between clock or moving text matrix. Idea and code for this modification I got from the last clock context also on the Instructables from autor Cermakamara, where this project got Second Prize.

Тo make the LED matrix driver we use 3 shift registers 74HC595 which multiply the number of outputs and save lots of arduino pins. Each shift register has 8 outputs and you only need 3 arduino pins to control almost an limited numbers of shift registers. We also use the 4017 decade counter to scan the rows, and you can scan up to 10 rows with it because you have only 10 outputs but to control it you need only 2 pins. More details on making the matrix itself can be found on my former project at: https://create.arduino.cc/projecthub/mircemk/diy-24x6-144-big-leds-matrix-with-scrolling-text-d0076a?ref=user&ref_id=168805&offset=32.

Code

Alarm Clock codeC/C++
/*
 * LED Matrix Alarm Clock with MP3 shield
 * The LED matrix is controlled by shift registers
 * Marek Cermak
 */
#include <SPI.h>
#include <MD_DS1307.h>

//---------------------------------GENERAL-----------------------------------
int allBtnStates;
unsigned long btnTimeStamp = 0;
#define ButtonA 5
#define ButtonB 6
#define ButtonC 7
#define playPin 2
#define stopPlay 3
uint8_t A;
uint8_t B;
uint8_t C;
uint8_t alarmHours = 7;
uint8_t alarmMinutes = 0;
uint8_t i = 0;
bool menuEntered = false;
bool isAlarmSet = false;
bool alarmNow = false;
bool stopAlarm = false;

//--------------------------------LED MATRIX----------------------------------

uint8_t hours;
uint8_t minutes;
uint8_t letA;
uint8_t letB;
uint8_t letC;
uint8_t letD;
//Pin connected to ST_CP of 74HC595
const uint8_t g_nPin_ShiftLatch = 10;
//Pin connected to SH_CP of 74HC595
const uint8_t g_nPin_ShiftClock = 13;
////Pin connected to DS of 74HC595
const uint8_t g_nPin_ShiftData = 11;
const uint8_t g_nPin_CounterClock = 9;
const uint8_t g_nPin_CounterReset = 8;
const uint8_t g_nRows = 6;
const uint8_t g_nColumns = 24;
uint32_t g_pDisplayBuffer[g_nRows] = { 0 };

typedef enum DISPLAY_CHAR : uint8_t
{
  DISPLAY_CHAR_0 = 0,
  DISPLAY_CHAR_1,
  DISPLAY_CHAR_2,
  DISPLAY_CHAR_3,
  DISPLAY_CHAR_4,
  DISPLAY_CHAR_5,
  DISPLAY_CHAR_6,
  DISPLAY_CHAR_7,
  DISPLAY_CHAR_8,
  DISPLAY_CHAR_9,
  DISPLAY_CHAR_A,
  DISPLAY_CHAR_B,
  DISPLAY_CHAR_C,
  DISPLAY_CHAR_D,
  DISPLAY_CHAR_E,
  DISPLAY_CHAR_F,
  DISPLAY_CHAR_G,
  DISPLAY_CHAR_H,
  DISPLAY_CHAR_I,
  DISPLAY_CHAR_J,
  DISPLAY_CHAR_K,
  DISPLAY_CHAR_L,
  DISPLAY_CHAR_M,
  DISPLAY_CHAR_N,
  DISPLAY_CHAR_O,
  DISPLAY_CHAR_P,
  DISPLAY_CHAR_Q,
  DISPLAY_CHAR_R,
  DISPLAY_CHAR_S,
  DISPLAY_CHAR_T,
  DISPLAY_CHAR_U,
  DISPLAY_CHAR_V,
  DISPLAY_CHAR_W,
  DISPLAY_CHAR_X,
  DISPLAY_CHAR_Y,
  DISPLAY_CHAR_Z,
  DISPLAY_CHAR_BLANK,
  DISPLAY_CHAR_FULL,
  DISPLAY_CHAR_DOT,
  DISPLAY_CHAR_DOUBLEDOT,


  DISPLAY_CHAR_COUNT,
} DISPLAY_CHAR;

const uint8_t g_pChar_Blank[] = { B00000000, B00000000, B00000000, B00000000, B00000000, B00000000};
const uint8_t g_pChar_1[] = { B00100000, B01100000, B00100000, B00100000, B00100000, B00000000};
const uint8_t g_pChar_2[] = { B11110000, B00010000, B11110000, B10000000, B11110000, B00000000};
const uint8_t g_pChar_3[] = { B11110000, B00010000, B11110000, B00010000, B11110000, B00000000 };
const uint8_t g_pChar_4[] = { B10010000, B10010000, B11110000, B00010000, B00010000, B00000000 };
const uint8_t g_pChar_5[] = { B11110000, B10000000, B11110000, B00010000, B11110000, B00000000 };
const uint8_t g_pChar_6[] = { B11110000, B10000000, B11110000, B10010000, B11110000, B00000000 };
const uint8_t g_pChar_7[] = { B11110000, B10010000, B00010000, B00010000, B00010000, B00000000 };
const uint8_t g_pChar_8[] = { B11110000, B10010000, B11110000, B10010000, B11110000, B00000000 };
const uint8_t g_pChar_9[] = { B11110000, B10010000, B11110000, B00010000, B11110000, B00000000 };
const uint8_t g_pChar_0[] = { B11110000, B10010000, B10010000, B10010000, B11110000, B00000000 };
const uint8_t g_pChar_A[] = { B01100000, B10010000, B11110000, B10010000, B10010000, B00000000 };
const uint8_t g_pChar_B[] = { B11100000, B10010000, B11100000, B10010000, B11100000, B00000000 };
const uint8_t g_pChar_C[] = { B01100000, B10010000, B10000000, B10010000, B01100000, B00000000 };
const uint8_t g_pChar_D[] = { B11100000, B10010000, B10010000, B10010000, B11100000, B00000000 };
const uint8_t g_pChar_E[] = { B11100000, B10000000, B11000000, B10000000, B11100000, B00000000 };
const uint8_t g_pChar_F[] = { B11100000, B10000000, B11000000, B10000000, B10000000, B00000000 };
const uint8_t g_pChar_G[] = { B01100000, B10000000, B10110000, B10010000, B01100000, B00000000 };
const uint8_t g_pChar_H[] = { B10010000, B10010000, B11110000, B10010000, B10010000, B00000000 };
const uint8_t g_pChar_I[] = { B11100000, B01000000, B01000000, B01000000, B11100000, B00000000 };
const uint8_t g_pChar_J[] = { B11100000, B00100000, B00100000, B10100000, B01000000, B00000000 };
const uint8_t g_pChar_K[] = { B10010000, B10100000, B11000000, B10100000, B10010000, B00000000 };
const uint8_t g_pChar_L[] = { B10000000, B10000000, B10000000, B10000000, B11100000, B00000000 };
const uint8_t g_pChar_M[] = { B10010000, B11110000, B10010000, B10010000, B10010000, B00000000 };
const uint8_t g_pChar_N[] = { B10010000, B11010000, B11110000, B10110000, B10010000, B00000000 };
const uint8_t g_pChar_O[] = { B01100000, B10010000, B10010000, B10010000, B01100000, B00000000 };
const uint8_t g_pChar_P[] = { B11000000, B10100000, B11000000, B10000000, B10000000, B00000000 };
const uint8_t g_pChar_Q[] = { B01100000, B10010000, B10010000, B10100000, B01110000, B00000000 };
const uint8_t g_pChar_R[] = { B11000000, B10100000, B11000000, B10100000, B10100000, B00000000 };
const uint8_t g_pChar_S[] = { B01100000, B10000000, B11000000, B00100000, B11000000, B00000000 };
const uint8_t g_pChar_T[] = { B11100000, B01000000, B01000000, B01000000, B01000000, B00000000 };
const uint8_t g_pChar_U[] = { B10010000, B10010000, B10010000, B10010000, B01100000, B00000000 };
const uint8_t g_pChar_V[] = { B10100000, B10100000, B10100000, B01000000, B01000000, B00000000 };
const uint8_t g_pChar_W[] = { B10010000, B10010000, B11110000, B11110000, B01100000, B00000000 };
//const uint8_t g_pChar_X[] = { B10100000, B10100000, B01000000, B10100000, B10100000, B00000000 };
const uint8_t g_pChar_X[] = { B00000000, B01000000, B00000000, B00000000, B00000000, B00010000 };
const uint8_t g_pChar_Y[] = { B10100000, B10100000, B01000000, B01000000, B01000000, B00000000 };
const uint8_t g_pChar_Z[] = { B11100000, B00100000, B01000000, B10000000, B11100000, B00000000 };
const uint8_t g_pChar_Full[] = { B11110000, B11110000, B11110000, B11110000, B11110000, B11110000 };
const uint8_t g_pChar_Dot[] = { B00000000, B00000000, B00000000, B00000000, B00000000, B00010000 };
const uint8_t g_pChar_DoubleDot[] = { B00000000, B11000000, B00000000, B11000000, B00000000, B00000000 };

const uint8_t* g_pDisplayChars[] =
{
  g_pChar_0,
  g_pChar_1,
  g_pChar_2,
  g_pChar_3,
  g_pChar_4,
  g_pChar_5,
  g_pChar_6,
  g_pChar_7,
  g_pChar_8,
  g_pChar_9,
  g_pChar_A,
  g_pChar_B,
  g_pChar_C,
  g_pChar_D,
  g_pChar_E,
  g_pChar_F,
  g_pChar_G,
  g_pChar_H,
  g_pChar_I,
  g_pChar_J,
  g_pChar_K,
  g_pChar_L,
  g_pChar_M,
  g_pChar_N,
  g_pChar_O,
  g_pChar_P,
  g_pChar_Q,
  g_pChar_R,
  g_pChar_S,
  g_pChar_T,
  g_pChar_U,
  g_pChar_V,
  g_pChar_W,
  g_pChar_X,
  g_pChar_Y,
  g_pChar_Z,
  g_pChar_Blank,
  g_pChar_Full,
  g_pChar_Dot,
  g_pChar_DoubleDot,
};

uint32_t g_nTimer_UpdateDisplay = 0;
const uint8_t g_nTimerPeriod_UpdateDisplay = 1;
uint32_t g_nTimer_UpdateText = 0;
const uint8_t g_nTimerPeriod_UpdateText = 130;
uint8_t g_nCharToDisplay = DISPLAY_CHAR_1;
uint8_t g_nCharPosition = 0;


void ClearDisplay(void)
{
  for (uint8_t i = 0; i < g_nRows; i++)
  {
    g_pDisplayBuffer[i] = 0;
  }
}

void DisplayChar(uint8_t nColumn, uint8_t nChar)
{

  if ((nColumn < g_nColumns) && (nChar < DISPLAY_CHAR_COUNT))
  {
    uint8_t* pChar = (uint8_t*)g_pDisplayChars[nChar];
    for (uint8_t i = 0; i < g_nRows; i++)
    {
      g_pDisplayBuffer[i] |= ((uint32_t)pChar[i]) << (24 - nColumn);
      //  Serial.println(g_pDisplayBuffer[i], BIN);
    }
  }
}

void UpdateDisplay(void)
{
  for (uint8_t nRow = 0; nRow < g_nRows; nRow++)
  {


    digitalWrite(g_nPin_ShiftLatch, LOW);
    SPI.transfer((uint8_t)((g_pDisplayBuffer[nRow] >> 24)));
    SPI.transfer((uint8_t)((g_pDisplayBuffer[nRow] >> 16)));
    SPI.transfer((uint8_t)((g_pDisplayBuffer[nRow] >> 8)));
    digitalWrite(g_nPin_ShiftLatch, HIGH);
    delayMicroseconds(500);
    
    digitalWrite(g_nPin_ShiftLatch, LOW);
    SPI.transfer(0);
    SPI.transfer(0);
    SPI.transfer(0);

    digitalWrite(g_nPin_ShiftLatch, HIGH);  
    digitalWrite(g_nPin_CounterClock, HIGH);  
    digitalWrite(g_nPin_CounterClock, LOW);
   
  }
  digitalWrite(g_nPin_CounterReset, HIGH);
  digitalWrite(g_nPin_CounterReset, LOW);

}


void setup()
{
  Serial.begin(115200);
  if (!RTC.isRunning())
    RTC.control(DS1307_CLOCK_HALT, DS1307_OFF);

  pinMode(g_nPin_ShiftLatch, OUTPUT);
  pinMode(g_nPin_ShiftClock, OUTPUT);
  pinMode(g_nPin_ShiftData, OUTPUT);
  pinMode(g_nPin_CounterClock, OUTPUT);
  pinMode(g_nPin_CounterReset, OUTPUT);
  digitalWrite(g_nPin_CounterReset, HIGH);
  digitalWrite(g_nPin_CounterReset, LOW);

  pinMode(ButtonA, INPUT_PULLUP);
  pinMode(ButtonB, INPUT_PULLUP);
  pinMode(ButtonC, INPUT_PULLUP);
  pinMode(playPin, OUTPUT);
  pinMode(stopPlay, OUTPUT);
  digitalWrite(playPin, HIGH);
  digitalWrite(stopPlay, LOW);

  SPI.begin();
  SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
  ClearDisplay();

  g_nTimer_UpdateDisplay = millis();
  g_nTimer_UpdateText = millis();
}

void ParseTime() {


  if (menuEntered == true) {
    hours = alarmHours;
  }

  //Serial.println(hours);
  if (hours < 10) {
    letB = hours;
    letA = 0;
  }
  else if (hours < 20) {
    letA = 1;
    letB = hours - 10;
  }
  else {
    letA = 2;
    letB = hours - 20;
  }


  if (menuEntered == true) {
    minutes = alarmMinutes;
  }

  if (minutes < 10) {
    letC = 0;
    letD = minutes;
  }
  else if (minutes < 20) {
    letC = 1;
    letD = minutes - 10;
  }
  else if (minutes < 30) {
    letC = 2;
    letD = minutes - 20;
  }
  else if (minutes < 40) {
    letC = 3;
    letD = minutes - 30;
  }
  else if (minutes < 50) {
    letC = 4;
    letD = minutes - 40;
  }
  else {
    letC = 5;
    letD = minutes - 50;
  }
}

void IsButtonPressed() {




  A = 1 - digitalRead(ButtonA);
  B = 1 - digitalRead(ButtonB);
  C = 1 - digitalRead(ButtonC);

  allBtnStates = A + 2 * B + 4 * C;
  if (allBtnStates < 7) { //Any button pressed
    if (btnTimeStamp == 0) btnTimeStamp = millis(); //Create timestamp
    else if (millis() - btnTimeStamp > 250) {
      switch (allBtnStates) {
        case 3: if (menuEntered) { //button to control hours
            if (alarmHours == 24) {
              alarmHours = 0;
            } else {
              alarmHours++;
            }
            ClearDisplay();
          } else if (alarmNow) { // snooze
           // Serial.println("snooze");
            alarmMinutes = alarmMinutes + 1;
            alarmNow = false;
            menuEntered = false;
            digitalWrite(playPin, HIGH); 
            digitalWrite(stopPlay, HIGH);
            if (alarmMinutes > 59) {
              alarmMinutes = alarmMinutes - 60;
            }
          }
          ; break;
        case 5: if (menuEntered) { //button to control minutes

            if (alarmMinutes == 60) {
              alarmMinutes = 0;
            } else {
              alarmMinutes++;
            }
            ClearDisplay();
          } else if (alarmNow) {//end alarm
           // Serial.println("endAlarm");
            alarmNow = false;
            stopAlarm = true;
            isAlarmSet = false;
            menuEntered = false;
            digitalWrite(playPin, HIGH);
            ClearDisplay();
            digitalWrite(stopPlay, HIGH);

          }
          ; break; 
        case 6: if (menuEntered) { // button right  .

            while (1 - digitalRead(ButtonA) == 0) {
              delay(100);
              i++;
              if (i == 15) {
                menuEntered = false;
                isAlarmSet = true;
              }
            }
          }; break;
        case 4: if (menuEntered == false) {//Both Left and Middle button pressed simultanously
            menuEntered = true;
            i = 0; break;

          } else {

            while ((1 - digitalRead(ButtonA) == 0) && (1 - digitalRead(ButtonB) == 0)) {// button right and center pressed together.
              delay(100);
              i++;
              if (i == 15) {
                menuEntered = false;
                isAlarmSet = false;
              }
            }

          }
          ; break;

      }
      btnTimeStamp = 0; //Reset timestamp
    }
  }

  if (menuEntered) {
    ParseTime();
  }

}

void loop()
{


  //DisplayChar(1, DISPLAY_CHAR_DOT);
  if (millis() > g_nTimer_UpdateDisplay)
  {
    IsButtonPressed();
    RTC.readTime();

    if (RTC.m != minutes && menuEntered == false) {
      hours = RTC.h;
      minutes = RTC.m;
      ClearDisplay();
      ParseTime();
      stopAlarm = false;
      digitalWrite(stopPlay, LOW);
    }

    DisplayChar(1, letA);
    DisplayChar(6, letB);
    DisplayChar(11, DISPLAY_CHAR_DOUBLEDOT);
    DisplayChar(14, letC);
    DisplayChar(19, letD);

    if (isAlarmSet) {

      DisplayChar(20, DISPLAY_CHAR_DOT);
      if (hours == alarmHours && minutes == alarmMinutes && stopAlarm == false && menuEntered == false) {
        alarmNow = true;
        digitalWrite(playPin, LOW);
      }
    }

    g_nTimer_UpdateText += g_nTimerPeriod_UpdateText;

    UpdateDisplay();
    g_nTimer_UpdateDisplay += g_nTimerPeriod_UpdateDisplay;
  }
}
Bluetooth moving text codeC/C++
#define BA {B01110000,B10001000,B10001000,B11111000,B10001000,B10001000}
#define BB {B11110000,B10001000,B10001000,B11110000,B10001000,B11111000}
#define BC {B11111000,B10000000,B10000000,B10000000,B10000000,B11111000}
#define BD {B11110000,B10001000,B10001000,B10001000,B10001000,B11110000}
#define BE {B11111000,B10000000,B10000000,B11110000,B10000000,B11111000}
#define BF {B11111000,B10000000,B10000000,B11110000,B10000000,B10000000}
#define BG {B01110000,B10001000,B10000000,B10011000,B10001000,B01110000}
#define BH {B10001000,B10001000,B11111000,B10001000,B10001000,B10001000}
#define BI {B11111000,B00100000,B00100000,B00100000,B00100000,B11111000}
#define BJ {B00111000,B00010000,B00010000,B00010000,B10010000,B01100000}
#define BM {B10001000,B11011000,B10101000,B10101000,B10001000,B10001000}
#define BN {B10001000,B11001000,B10101000,B10101000,B10011000,B10001000}
#define BL {B10000000,B10000000,B10000000,B10000000,B10000000,B11111000}
#define BO {B01110000,B10001000,B10001000,B10001000,B10001000,B01110000}
#define BP {B11110000,B10001000,B10001000,B11110000,B10000000,B10000000}
#define BQ {B01110000,B10001000,B10101000,B10011000,B01111000,B00001000}
#define BR {B11110000,B10001000,B10001000,B11110000,B10001000,B10001000}
#define BS {B01110000,B10001000,B01100000,B00010000,B10001000,B01110000}
#define BK {B10001000,B10010000,B11100000,B11100000,B10010000,B10001000}
#define BT {B11111000,B00100000,B00100000,B00100000,B00100000,B00100000}
#define BU {B10001000,B10001000,B10001000,B10001000,B10001000,B01110000}
#define BV {B10001000,B10001000,B10001000,B10001000,B01010000,B00100000}
#define BW {B10001000,B10001000,B10101000,B10101000,B10101000,B01010000}
#define BX {B10001000,B01010000,B00100000,B00100000,B01010000,B10001000}
#define BY {B10001000,B01010000,B00100000,B00100000,B00100000,B00100000}
#define BZ {B11111000,B00001000,B00110000,B01100000,B10000000,B11111000}
#define LA{B00000000,B01110000,B00001000,B01111000,B10001000,B01111000}
#define LB{B10000000,B10000000,B10110000,B11001000,B10001000,B11110000}
#define LC{B00000000,B01110000,B10000000,B10000000,B10001000,B01110000}
#define LD{B00001000,B00001000,B01111000,B10001000,B10001000,B01111000}
#define LE{B00000000,B01110000,B10001000,B11111000,B10000000,B01110000}
#define LF{B00110000,B01001000,B01000000,B11100000,B01000000,B01000000}
#define LG{B00000000,B01111000,B10001000,B01111000,B00001000,B01110000}
#define LH{B10000000,B10000000,B10110000,B11001000,B10001000,B10001000}
#define LI{B00100000,B00000000,B01100000,B00100000,B00100000,B01111000}
#define LJ{B00010000,B00000000,B00111000,B00010000,B10010000,B01100000}
#define LK{B10000000,B10010000,B10100000,B11000000,B10100000,B10010000}
#define LL{B01100000,B00100000,B00100000,B00100000,B00100000,B01111000}
#define LM{B00000000,B00000000,B11010000,B10101000,B10101000,B10001000}
#define LN{B00000000,B00000000,B10110000,B11001000,B10001000,B10001000}
#define LO{B00000000,B01110000,B10001000,B10001000,B10001000,B01110000}
#define LP{B00000000,B11110000,B10001000,B11110000,B10000000,B10000000}
#define LQ{B00000000,B01101000,B10011000,B01111000,B00001000,B00001000}
#define LR{B00000000,B00000000,B10110000,B11001000,B10000000,B10000000}
#define LS{B00000000,B01110000,B10000000,B01110000,B00001000,B11110000}
#define LT{B01000000,B01000000,B11100000,B01000000,B01001000,B00110000}
#define LU{B00000000,B00000000,B10001000,B10001000,B10011000,B01101000}
#define LV{B00000000,B00000000,B10001000,B10001000,B01010000,B00100000}
#define LW{B00000000,B00000000,B10001000,B10101000,B10101000,B01010000}
#define LX{B00000000,B10001000,B01010000,B00100000,B01010000,B10001000}
#define LY{B00000000,B10001000,B10001000,B01111000,B00001000,B01110000}
#define LZ{B00000000,B11111000,B00010000,B00100000,B01000000,B11111000}
#define SPACE{B00000000,B00000000,B00000000,B00000000,B00000000,B00000000}
#define NUM0{B01110000,B10011000,B10101000,B10101000,B11001000,B01110000}
#define NUM1{B00100000,B01100000,B10100000,B00100000,B00100000,B01110000}
#define NUM2{B01110000,B10001000,B00001000,B01110000,B10000000,B11111000}
#define NUM3{B11110000,B00001000,B00001000,B01111000,B00001000,B11110000}
#define NUM4{B10001000,B10001000,B10001000,B11111000,B00001000,B00001000}
#define NUM5{B11111000,B10000000,B11110000,B00001000,B10001000,B01110000}
#define NUM6{B11111000,B10000000,B11111000,B10001000,B10001000,B11111000}
#define NUM7{B11111000,B00001000,B00001000,B01111000,B00001000,B00001000}
#define NUM8{B11111000,B10001000,B11111000,B10001000,B10001000,B11111000}
#define NUM9{B11111000,B10001000,B11111000,B00001000,B00001000,B11111000}
#define DEVIDE{B00001000,B00010000,B00100000,B00100000,B01000000,B10000000}
#define TWODOTS{B01100000,B01100000,B00000000,B00000000,B01100000,B01100000}
#define DOT{B00000000,B00000000,B00000000,B00000000,B01100000,B01100000}
#define COMA{B00000000,B00000000,B00000000,B00110000,B00110000,B01100000}
#define LINE{B00000000,B00000000,B11111000,B11111000,B00000000,B00000000}
#define QUASTION{B01110000,B10001000,B00010000,B00100000,B00000000,B00100000}
#define MARK{B00100000,B01110000,B01110000,B00100000,B00000000,B00100000}

int latchPin = 10;
int clockPin = 13;
int dataPin = 11;
int clock = 9;
int Reset = 8;
int latchPinPORTB = latchPin - 8;
int clockPinPORTB = clockPin - 8;
int dataPinPORTB = dataPin - 8;
int i = 0;
int incomingByte[44];
long scrolling_word[6];
int array_turn=0;

boolean novZbor=false;

byte patterns[100][6];
byte dummy_array[70][6] ={BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ,BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,SPACE,NUM0,NUM1,NUM2,NUM3,NUM4,NUM5,NUM6,NUM7,NUM8,NUM9,DEVIDE,TWODOTS,DOT,COMA,LINE,QUASTION,MARK,LA,LB,LC,LD,LE,LF,LG,LH,LI,LJ,LK,LL,LM,LN,LO,LP,LQ,LR,LS,LT,LU,LV,LW,LX,LY,LZ};
void setup(){
  Serial.begin(9600);
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(latchPin,OUTPUT);
  pinMode(clock,OUTPUT);
  pinMode(Reset,OUTPUT);
  digitalWrite(Reset,HIGH);
  digitalWrite(Reset,LOW);
  setupSPI();
}

void display_word(int loops,byte word_print[][6],int num_patterns,int delay_langth){// this function displays your symbols
  i = 0;// resets the counter fot the 4017
  for(int g=0;g<6;g++)//resets the the long int where your word goes
    scrolling_word[g] = 0;
  for(int x=0;x<num_patterns;x++){//main loop, goes over your symbols
   // you will need to find a better way to make the symbols scroll my way is limited for 24 columns

   for(int r=0;r<6;r++)//puts the buildes the first symbol
      scrolling_word[r] |= word_print[x][r]; 
    for (int z=0;z<6;z++){//the sctolling action
        for(int p=0;p<6;p++)
          scrolling_word[p] = scrolling_word[p] << 1;
// end of the scrolling funcion
      for(int t=0;t<delay_langth;t++){// delay function, it just loops over the same display
        for(int y=0;y<6;y++){// scaning the display
          if(i == 6){// counting up to 6 with the 4017
            digitalWrite(Reset,HIGH);
            digitalWrite(Reset,LOW);
            i = 0;
          }
          latchOff();
          spi_transfer(make_word(0x01000000,y));// sending the data
          spi_transfer(make_word(0x00010000,y));
          spi_transfer(make_word(0x00000100,y));
          latchOn();
          delayMicroseconds(800);//waiting a bit
          latchOff();
          spi_transfer(0);// clearing the data
          spi_transfer(0);
          spi_transfer(0);
          latchOn();
          digitalWrite(clock,HIGH);//counting up with the 4017
          digitalWrite(clock,LOW);
          i++;
        }
      }
    }
  }
  finish_scroll(delay_langth);
}

void finish_scroll(int delay_scroll){// this function is the same as the funcion above, it just finishing scrolling
  for (int n=0;n<24;n++){
        for(int h=0;h<6;h++)
          scrolling_word[h] = scrolling_word[h] << 1;
      for(int w=0;w<delay_scroll;w++){
        for(int k=0;k<6;k++){
          if(i == 6){
            digitalWrite(Reset,HIGH);
            digitalWrite(Reset,LOW);
            i = 0;
          }
          latchOff();
          spi_transfer(make_word(0x01000000,k));
          spi_transfer(make_word(0x00010000,k));
          spi_transfer(make_word(0x00000100,k));
          latchOn();
          delayMicroseconds(800);
          latchOff();
          spi_transfer(0);
          spi_transfer(0);
          spi_transfer(0);
          latchOn();
          digitalWrite(clock,HIGH);
          digitalWrite(clock,LOW);
          i++;
        }
      }
    }
}

byte make_word (long posistion,byte turn){
  byte dummy_word = 0;
  for(int q=0;q<8;q++){
    if(scrolling_word[turn] & (posistion<<q))
      dummy_word |= 0x01<<q;
  }
  return dummy_word;
}   


  void loop() {

	// send data only when you receive data:
	if(Serial.available() > 0){
		
                if (novZbor == true){
			array_turn=0;
			novZbor = false;
		}
		
		delay(100);
		incomingByte[array_turn] = Serial.read();
                array_turn++;
	}
           else{
            
             if(array_turn != 0){ 
				novZbor = true;
               for(int az=0;az<array_turn;az++){
                 if((incomingByte[az] > 64 && incomingByte[az] < 91) || (incomingByte[az] > 96 && incomingByte[az] < 123)){
                  if(incomingByte[az] > 64 && incomingByte[az] < 91){
                   for(int lal=0;lal<6;lal++)                 
                 patterns[az][lal] = dummy_array[incomingByte[az] - 65][lal];
               }
               else{
                 for(int lal=0;lal<6;lal++)                 
                 patterns[az][lal] = dummy_array[incomingByte[az] - 53][lal];
               }}
               else{
                 switch(incomingByte[az]){
                case 32://space
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[26][lol];
                 break;
                case 33://mark
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[43][lol];
                 break;
                case 45://line
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[41][lol];
                 break;                 
                 case 44://coma
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[40][lol];
                 break;
                 case 46://dot
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[39][lol];
                 break;
                 case 47://dvide
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[37][lol];
                 break;
                 case 48://0
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[27][lol];
                 break;
                 case 49://1
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[28][lol];
                 break;
                 case 50://2
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[29][lol];
                 break;
                 case 51://3
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[30][lol];
                 break;
                 case 52://4
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[31][lol];
                 break;
                 case 53://5
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[32][lol];
                 break;
                 case 54://6
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[33][lol];
                 break;
                 case 55://7
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[34][lol];
                 break;
                 case 56://8
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[35][lol];
                 break;
                 case 57://9
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[36][lol];
                 break;
                 case 58://tow dots
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[38][lol];
                 break;
                 case 63://quastion
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[42][lol];
                 break;
                 default:
                 for(int lol=0;lol<6;lol++)                 
                 patterns[az][lol] = dummy_array[26][lol];
                 break; 
                 }
               }               
             }
           }
          
          
          display_word(1,patterns,array_turn,15);
          
          novZbor = true;
          // array_turn =0; 
         
       
     } 
      
     }
  
  //display_word(1,patterns,43,15);// calls for the display_pattern function and says that int loop = 15(if you do more loop the pattern whould scrrol slower).

void latchOn(){
  bitSet(PORTB,latchPinPORTB);
}

void latchOff(){
  bitClear(PORTB,latchPinPORTB);
}


void setupSPI(){
  byte clr;
  SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
  //SPCR |= ( (1<<SPR1) | (1<<SPR0) ); // set prescaler bits
  SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
  clr=SPSR; // clear SPI status reg
  clr=SPDR; // clear SPI data reg
  SPSR |= (1<<SPI2X); // set prescaler bits
  //SPSR &= ~(1<<SPI2X); // clear prescaler bits

  delay(10);
}
byte spi_transfer(byte data)
{
  SPDR = data;			  // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;			  // return the received byte, we don't need that
}

Schematics

Fritzing schematic
Untitled sketch bbic kbe3kg9jo7
matrix driver
Fugnp1xgbvj2558 large (1) nxkoaggdlk
matrix
Fii18vggbvj806p large udkuc7ewpw

Comments

Similar projects you might like

Arduino Word Clock on 8x8 RGB LED Matrix

Project tutorial by Mirko Pavleski

  • 7,119 views
  • 4 comments
  • 28 respects

Arduino Nano "One Digit" Big LED Clock

Video tutorial by Mirko Pavleski

  • 2,439 views
  • 0 comments
  • 6 respects

Mini LED Matrix Clock

Project tutorial by Mirko Pavleski

  • 19,330 views
  • 14 comments
  • 58 respects

Single LED Matrix Arduino Flip Clock

Project tutorial by Mirko Pavleski

  • 4,535 views
  • 2 comments
  • 16 respects

Analog Clock with LED Matrix and Arduino

Project tutorial by LAGSILVA

  • 18,833 views
  • 17 comments
  • 67 respects

Arduino Nano Clock with 4x64 LED Matrix

Project tutorial by M.V.P.

  • 19,055 views
  • 30 comments
  • 44 respects
Add projectSign up / Login