Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 144 | ||||
| × | 1 | ||||
| × | 3 | ||||
| × | 6 | ||||
| × | 24 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
|
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.
/*
* 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;
}
}
#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
}
Comments