Matrix Clock
#include <LedControl.h>
/*H*******************************************************
Name: ArduinoMatrixClock.ino
Created: 12.06.2018 20:56:49
Author: mylms.cz
From: https://abidcg.blogspot.com/2019/05/hello-weMtrxome-to-abid-cg-creator-blog.html
https://www.mylms.cz/text-arduino-hod iny-s-maticovym-displejem/
5V = common for all modules, 5V supply connected via 1N4148
********************************************************/
#include <EEPROM.h>
#include <Wire.h>
#include <LedControl.h>
//************************* DEFINES ************************************
#define NBRDEVS 4
#define DS3231_I2C_ADDRESS 0x68 // DS3231 MODULE ADDR
#define BTN1 D2 // (SET INTERNAL_PULLUP)
#define BTN2 D3 // (SET INTERNAL_PULLUP)
#define MTXDIN D4 // MATRIX DISPLAY, pin DIN
#define MTXCLK D5 // MATRIX DISPLAY, pin CLK
#define MTXCS D6 // MATRIX DISPLAY, Pin CS
#define RTCSDA A4 // RTC MODULE, PIN SDA
#define RTCCLK A5 // RTC MODULE, PIN SCL
//************************* PROTOTYPES ************************************
void GetButton();
void WriteTime();
void Intro();
void DrawSymbol( byte adr, byte symbol, byte offset );
byte ByteRevers( byte in );
void SetRtc( byte Sec, byte Min, byte Hr, byte Dow, byte Dom, byte Mon
, byte Yr);
void GetRtc();
byte decToBcd( byte val );
byte bcdToDec( byte val );
void SerialComm();
//************************* VARIABLES ************************************
LedControl Mtrx = LedControl( 4, 5,6, NBRDIVS);//DIN, CLK, CS, DISPLAY COUNT
byte Bright = 0;
bool ShowDots;
byte Sec, Min, Hr, Dow, Dom, Mon, Yr;
unsigned long CurrTim;
unsigned long DsplTim; // DRAWING
bool LstInp1; // LAST STATE OF #1 INPUT
bool lastInput2; // LAST STATE OF #2 INPUT
bool CurrInp1; // ACTUAL STATE OF INPUT #1
bool CurrInp2; // ACTUAL STATE OF INPUT #2
byte State;
/*F********************************************************************
*
**********************************************************************/
void
setup()
{
Wire.begin(); // START I2C COMM
Serial.begin( 9600 );
pinMode( BTN1, INPUT_PULLUP);
pinMode( BTN2, INPUT_PULLUP);
Bright = EEPROM.read( 0 ); // LOAD LIGHT INTENSITY FROM EEPROM
delay( 10 );
for( byte address = 0; address < devices; address++)
{
Mtrx.shutdown( address, false); // POWERSAVING
Mtrx.setIntensity( address, Bright );// SET LIGHT INTENS MIN: 0 MAX:15
Mtrx.clearDisplay( address ); // CLEAR DISPLAY
}
//INIT TIME SETTING
// SetRtc( 15, 41, 8, 6, 30, 3, 18); // sec, min, Hr, Dow, Dom, Mon, Yr
//Intro(); //show LMS!
}
/*F********************************************************************
*
**********************************************************************/
void
loop()
{
CurrInp1 = digitalRead( BTN1 ); // STORE INPUT TO VAR
CurrInp2 = digitalRead( BTN2 );
switch( State )
{
case 0:
CurrTim = millis(); // SHOW ACTUAL TIME
if( CurrTim - DsplTim >= 500)
{
DsplTim = CurrTim; // "MULTASKING"
GetRtc(); // GET ACTUAL TIME
WriteTime(); // WRITE ACTUAL TIME TO MATRIX DISPLAY
}
if( !CurrInp1 && !CurrInp2 )
{
delay( 20 );
State = 1; // GO TO "pre" MENU
}
break;
case 1:
if( CurrInp1 && CurrInp2)
{
delay( 20 );
State = 2; // GO TO MENU
DrawSymbol( 1, 0, 0); // SPACE
DrawSymbol( 0, 72 - 32, 0); // H
}
break;
case 2: // MENU 1
WriteTime(); // SET HRS
if( CurrInp1 != LstInp1 )
{ // CHANGE DETECTED BTN1
delay( 20 );
if( CurrInp1 )
{
delay( 20 );
State = 3; // RISING EDGE DETECTED
DrawSymbol( 3, 77 - 32, 0 ); // M
DrawSymbol( 2, 0, 0 ); // SPACE
}
}
if( CurrInp2 != lastInput2 )
{ // CHANGE DETECTED BTN2
delay( 20 );
if( CurrInp2 )
{ // RISING EDGE DETECTED
Hr++; // ADD HR
if( Hr > 23 )
Hr = 0;
}
}
break;
case 3: // MENU 2
WriteTime(); // SET Mins
if( CurrInp1 != LstInp1 )
{
delay( 20 );
// CHANGE DETECTED BTN1
if( CurrInp1 )
{ // RISING EDGE DETECTED
State = 4;
DrawSymbol( 3, 66 - 32, 0); // B
DrawSymbol( 2, 0, 0); //space
DrawSymbol( 0, (Bright % 10) + 16, 1);// ACTUAL LIGHT INTENS
DrawSymbol(1, (Bright / 10) + 16, 1);// ACTUAL LIGHT INTENS
}
}
if( CurrInp2 != lastInput2)
{
delay(20);
if( CurrInp2 ) // CHANGE DETECTED BTN2
{ // RISING EDGE DETECTED
Min++; // ADD HR
if( Min > 59 )
Min = 0;
}
}
break;
case 4: // MENU 3
if( CurrInp1 != LstInp1 ) // SET BRIGHTNESS
{ // CHANGE DETECTED BTN1
delay(2 0 );
if( CurrInp1 )
{ // RISING EDGE DETECTED
State = 5;
DrawSymbol( 3, 83 - 32, 0 ); // S
DrawSymbol( 2, 116 - 32, 0 ); // t
DrawSymbol( 1, 114 - 32, 0 ); // r
DrawSymbol(0, 116 - 32, 0 ); // t
}
}
if( CurrInp2 != lastInput2 )
{ // CHANGE DETECTED BTN2
delay(20);
if( CurrInp2)
{ // RISING EDGE DETECTED
Bright++; // ADD HR
if( Bright > 15 )
Bright = 0;
DrawSymbol( 0, (Bright % 10) + 16, 1);// ACT LIGHT INTENS
DrawSymbol( 1, (Bright / 10) + 16, 1);// ACT LIGHT INTENS
// SET LIGHT INTENS MIN:0, MAX:15
for( byte address = 0; address> offset;
Mtrx.setRow( adr, i, dataRow );
}
}
/*F********************************************************************
* FONT TURNING
**********************************************************************/
byte
ByteRevers( byte in )
{
byte out;
out = 0;
if( in & 0x01 )
out |= 0x80;
if( in & 0x02 )
out |= 0x40;
if( in & 0x04 )
out |= 0x20;
if( in & 0x08 )
out |= 0x10;
if( in & 0x10 )
out |= 0x08;
if( in & 0x20 )
out |= 0x04;
if( in & 0x40 )
out |= 0x02;
if( in & 0x80 )
out |= 0x01;
return( out );
}
/*F********************************************************************
* SET RTC
**********************************************************************/
void
SetRtc( byte Sec, byte Min, byte Hr, byte Dow, byte Dom, byte Mon, byte Yr)
{
Wire.beginTransmission( DS3231_I2C_ADDRESS );
Wire.write( 0 ); // SET 0 TO FIRST REGISTER
Wire.write( decToBcd( Sec ) ); // SET Sec
Wire.write( decToBcd( Min ) ); // SET Mins
Wire.write( decToBcd( Hr ) ); // SET Hrs
Wire.write( decToBcd( Dow ) ); // SET DAY OF WEEK (1=SU, 2=MO, 3=TU)
Wire.write( decToBcd( Dom ) ); // SET day of Mon
Wire.write( decToBcd( Mon ) ); // SET Mon
Wire.write( decToBcd( Yr ) ); // SET Yr
Wire.endTransmission();
}
/*F********************************************************************
* READ RTC
**********************************************************************/
void
GetRtc()
{
Wire.beginTransmission( DS3231_I2C_ADDRESS );
Wire.write( 0 ); // WRITE "0"
Wire.endTransmission();
Wire.requestFrom( DS3231_I2C_ADDRESS, 7 ); // REQUEST - 7 BYTES FROM RTC
Sec = bcdToDec( Wire.read() & 0x7f );
Min = bcdToDec( Wire.read() );
Hr = bcdToDec( Wire.read() & 0x3f );
Dow = bcdToDec( Wire.read() );
Dom = bcdToDec( Wire.read() );
Mon = bcdToDec( Wire.read() );
Yr = bcdToDec(W ire.read() );
}
/*F********************************************************************
* CONVERSION Dec TO BCD
**********************************************************************/
byte
decToBcd( byte val )
{
return( (val / 10 * 16) + (val % 10) );
}
/*F********************************************************************
* CONVERSION BCD TO Dec
**********************************************************************/
byte
bcdToDec( byte val )
{
return( (val / 16 * 10) + (val % 16) );
}
/*F********************************************************************
* SERIAL COMMUNICATION WITH PC, SET TIME VIA PC
**********************************************************************/
void // FIRST LETTER - TYPE OF DATA, SEC LETTER - DATA
SerialComm() // (SPACE = 0, != 1, ETC, SEE ASCII TABLE)
{
if( Serial.available() > 0 )
{
byte receivedCommand;
receivedCommand = Serial.read(); // READ FIRST LETTER
if( receivedCommand < 90 )
{ // RECEIVED DATA IS LESS THAN 90 (LETTER Z)
delay( 10 ); // WAIT FOR sEC LETTER
byte receivedData;
receivedData = Serial.read();
receivedData -= 32; //shift - 32 -> 32 = space
switch( receivedCommand )
{
case 65: // Yr 65 = A
Yr = receivedData;
Mtrx.setLed( 3, 7, 0, true ); // SHOW SETTING DOT
break;
case 66: // Mon 66 = B
Mon = receivedData;
Mtrx.setLed( 3, 7, 1, true ); // SHOW SETTING DOT
break;
case 67: // Dom 67 = C
Dom = receivedData;
Mtrx.setLed( 3, 7, 2, true ); // SHOW SETTING DOT
break;
case 68: // Hr 68 = D
Hr = receivedData;
Mtrx.setLed( 3, 7, 3, true );/ / SHOW SETTING DOT
break;
case 69: // Min 69 = E
Min = receivedData;
Mtrx.setLed( 3, 7, 4, true ); // SHOW SETTING DOT
break;
case 70: // Sec 70 = F
Sec = receivedData;
Mtrx.setLed( 3, 7, 5, true ); // SHOW SETTING DOT
break;
case 71: // DAYOFwEEK 71 = G
Dow = receivedData;
Mtrx.setLed( 3, 7, 6, true ); // SHOW SETTING DOT
break;
}
SetRtc( Sec, Min, Hr, Dow, Dom, Mon, Yr );
} // spl�chnout buffer do hajzlu
Serial.flush();
}
}