![]() | ![]() | ![]() |
I got the Nano working with an ESP8266 on an ESP01 adapter but, didn't
have enough RAM left, so I tried a ESP32 NodeMCU
.
NTP is atomic, but "Atomic Clock" is already taken.
BTW, I measured the 5V current drawn by the first prototype at 153Ma.
I wanted to build a clock that used WiFi to get NTP packets. The problem with doing this is, you have to tell the clock the WiFi SSID and password.
Several thoughts came to mind:
![]() |
![]() |
ESP32NodeMCU 30 Pin pinout | ESP32NodeMCU 38 Pin pinout |
RTC->SCL | -> | ESP2->SCL i.e. Pin D22 (I2C) |
RTC->SDA | -> | ESP2->SDA i.e. Pin D21 |
RTC->Vcc | -> | ESP2->Vcc -> 3.3 V |
MAX7219 (LedMtx) | ||
MTX->DAT | -> | ESP32->MOSI ->13 |
MTX->CLK | -> | ESP32->SPI CLK->14 |
MTX->CS | -> | ESP32->27 |
MTX->Vcc | -> | 5V |
![]() |
DS3231 RTC pinout.
DS3231 has and I2C interface, CLK goes to ESP32->22 DAT goes to ESP32->21 The DS3231 also has an on-board 24C32 Non-Volatile RAM. Cllck for larger PIC. |
![]() |
Led Matrix
MAX7219 Led Matrix conectors. MAX7219 has an SPI interface: DIN -> ESP32->13 CLK -> Esp32->14 CS -> ESP32->27 Cllck for larger PIC. |
![]() |
Time test lash-up.
You can see the ESP32NodeMCU (lower left), temporary display 2004 (upper right), and the DS3231 RTC top center of bread board.
The ESP32NodeMCU is getting the time from our NTP server, storing it into the RDC, retrieving it and finally displaying it on the 2004 LCD.
The Nano at the upper left isn't used, it just happened to be on the test board. The Time Code sketch |
![]() | Closer look at the Time Test display. |
![]() |
The number test, all ascii chars scrolling.
This is a test of the Led Matrix driving code.
I started out with this scrolling "The quick brown fox jumped over the lazy dog" in both upper and lower case.
The program also scrolls all 128 ASCII characters.
The Sketch |
![]() | This is on the lowest intensity setting. Note the colon in the center is also present. |
![]() | Some of the lower case characters. |
![]() | The RTC (DS3231). The larger chip (top) is the DS3231, the smaller chip (lower) is the 24C32 EEPROM. |
Note that the three adapter boards all have their pins 90° and will have to have them replaced with straight pins in order to mount them.
/*H******************************************************************** * Matrix clock with scrolling data. * Mtx-2 = DAT, Mtx-3 = CS, Mtx-4 = CLK **********************************************************************/ #include <LedControl.h> #include "ChrCodes.h" //************************* DEFINES ************************************ #define MTX_DAT 2 #define MTX_CLK 4 #define MTX_CS 3 #define BAUD 9600 typedef unsigned long ulong; //************************* PROTOTYPES ************************************ void msg( char *msgStr ); void scrollFont(); void ldBuff( int chr ); void rotBuff(); void pntBuff( ); //************************* VARIABLES ************************************ const int NbrDevs = 4; // NUMBER OF MAX7219s USED const long ScrlDly = 75; // ADJUST SCROLLING SPEED ulong Buff[14] = {0}; // DAT, CLK CS, NbrDevs LedControl Mtx = LedControl( MTX_DAT, MTX_CLK, MTX_CS, NbrDevs ); const char ScrlTxt[] = { " THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG 1234567890" " the quick brown fox jumped over the lazy dog " }; /*F******************************************************************** * **********************************************************************/ void setup( ) { Serial.begin( BAUD ); for( int x =0; x < NbrDevs; x++ ) { Mtx.shutdown( x, false );// MAX72XX IS IN POWER-SAVING MODE ON STARTUP Mtx.setIntensity( x, 0 ); // SET BRIGHTNESS TO DEFAULT VALUE Mtx.clearDisplay( x ); // AND CLEAR DISPLAY } Serial.println( "startup end" ); } /*F******************************************************************** * **********************************************************************/ void loop( ) { Serial.println("Loop bgn"); msg( ScrlTxt ); Serial.println( "loop past scroll Msg" ); scrollFont(); } /*F******************************************************************** * DISPLAYS ENTIRE ChrCodes ARRAY **********************************************************************/ void scrollFont() { int ndx; for( ndx = 0x20; ndx < 0x80; ndx++ ) { ldBuff( ndx ); delay( 33 ); // WAS 500 } } /*F******************************************************************** * Scroll Message **********************************************************************/ void msg( char *msgStr ) { int cnt = 0, chr =0; for( cnt =0; (chr = ScrlTxt[cnt]) != 0; cnt++ ) ldBuff( chr ); // READ BACK A CHAR } /*F******************************************************************** * Load character into scroll buffer, ALL THE SHUCKING AND JIVING HAPPENS HERE **********************************************************************/ void ldBuff( int chr ) { int ndx; byte cnt1, cnt2, cnt3, kcnt; ulong var1, var2; if( chr >= 0x20 && chr <= 0x7f ) { for( cnt1 =0; cnt1 < 7; cnt1++ ) { // LOOP 7 TIMES FOR 5X7 FONT // NDX INTO CHAR TBL GET ROW DAT var1 = Font5x7[((chr -0x20) *8 ) +cnt1]; var2 = Buff[cnt1 *2]; // LOAD CURR SCROLL BUFFER var2 = var2 | var1; // OR NEW CHARACTER ONTO END OF CURRENT Buff[cnt1 *2] = var2; // STORE IN BUFFER } kcnt = Font5x7[((chr -0x20 ) *8 ) +7]; for( cnt3 =0; cnt3 < kcnt; cnt3++ ) // ACTUAL SCROLL CODE { rotBuff(); pntBuff(); delay( ScrlDly ); } } } /*F******************************************************************** * Rotate buffer **********************************************************************/ void rotBuff( ) { int cnt; ulong var; byte bit; for( cnt =0; cnt < 7; cnt++ ) { // LOOP 7 TIMES FOR A 5X7 FONT var = Buff[cnt *2]; // GET LOW BUFFER ENTRY bit = bitRead( var, 31 ); // CPY HI BIT GETS LOST IN ROTATION var = var << 1; // ROTATE LEFT ONE BIT Buff[cnt *2] = var; // STORE NEW LOW BUFFER var = Buff[cnt *2 +1]; // GET HIGH BUFFER ENTRY var = var << 1; // ROTATE LEFT ONE BIT bitWrite( var, 0, bit ); // STORE SAVED BIT Buff[cnt *2 +1] = var; // STORE NEW HIGH BUFFER } } /*F******************************************************************** * DISPLAY BUFFER ON LED MATRIX **********************************************************************/ void pntBuff( ) { int ndx; byte byt; ulong var; for( ndx =0; ndx < 7; ndx++ ) { // LOOP 7 TIMES FOR A 5X7 FONT var = Buff[ndx *2 +1]; // GET HIGH BUFFER ENTRY byt = var; // MASK OFF FIRST CHARACTER Mtx.setRow( 3, ndx, byt ); // SEND ROW TO RELEVENT MAX7219 CHIP var = Buff[ndx *2]; // GET LOW BUFFER ENTRY byt = ( var >> 24 ); // MASK OFF SECOND CHARACTER Mtx.setRow( 2, ndx, byt ); // SEND ROW TO RELEVENT MAX7219 CHIP byt = ( var >> 16 ); // MASK OFF THIRD CHARACTER Mtx.setRow( 1, ndx, byt ); // SEND ROW TO RELEVENT MAX7219 CHIP byt = ( var >> 8 ); // MASK OFF FORTH CHARACTER Mtx.setRow( 0, ndx, byt ); // SEND ROW TO RELEVENT MAX7219 CHIP } } #ifdef BARF bitWrite( x, n, b ) Parameters x: the numeric variable to write into n: bit of var to write, 0 == LSB (rightmost) bit. b: value to write to var bit (0 or 1). byte X = 0b10000000; // BEFORE bitWrite( X, 0, 1 ); // WRITE '1' TO LSB OF VAR X byte X = 0b10000001; // AFTER bitWrite( X, 0, 1 ); #endif
/*H******************************************************************** * Matrix clock test * Mtx-2 = DAT, Mtx-3 = CS, Mtx-4 = CLK **********************************************************************/ #include <LedControl.h> //************************* DEFINES ************************************ #define MTX_DAT 2 #define MTX_CLK 4 #define MTX_CS 3 #define HR10 3 #define HR1 2 #define MIN10 1 #define MIN1 0 #define BAUD 9600 typedef unsigned long ulong; //************************* PROTOTYPES ************************************ void putChr( byte mtxNbr, byte *dat ); void colon( bool on ); //************************* VARIABLES ************************************ const int NbrDevs = 4; // NUMBER OF MAX7219s USED const long ScrlDly = 75; // ADJUST SCROLLING SPEED byte State =0, Tggl =0; ulong NewNbrs, ColonBlink; // DAT, CLK CS, NbrDevs LedControl Mtx = LedControl( MTX_DAT, MTX_CLK, MTX_CS, NbrDevs ); byte Nbrs[11][8] = { { 0x38,0x44,0x4C,0x54,0x64,0x44,0x38}, // '0' { 0x10,0x30,0x10,0x10,0x10,0x10,0x38}, // '1' { 0x38,0x44,0x04,0x08,0x10,0x20,0x7C}, // '2' { 0x7C,0x08,0x10,0x08,0x04,0x44,0x38}, // '3' { 0x08,0x18,0x28,0x48,0x7C,0x08,0x08}, // '4' { 0x78,0x40,0x78,0x04,0x04,0x44,0x38}, // '5' { 0x18,0x20,0x40,0x78,0x44,0x44,0x38}, // '6' { 0x7C,0x44,0x04,0x08,0x10,0x10,0x10}, // '7' { 0x38,0x44,0x44,0x38,0x44,0x44,0x38}, // '8' { 0x38,0x44,0x44,0x3C,0x04,0x08,0x30} // '9' { 0x00,0x00,0x00,0x3000x00,0x00,0x300 // BLANK }; byte Colon[8] = { 0x00,0xC0,0xC0,0x00,0xC0,0xC0,0x00 }; /*F******************************************************************** * **********************************************************************/ void setup( ) { Serial.begin( BAUD ); for( int x =0; x < NbrDevs; x++ ) { Mtx.shutdown( x, false );// MAX72XX IS IN POWER-SAVING MODE ON STARTUP Mtx.setIntensity( x, 0 ); // SET BRIGHTNESS TO DEFAULT VALUE Mtx.clearDisplay( x ); // AND CLEAR DISPLAY } NewNbrs = millis() + 1000; // SET MATTRIX UPDATE TIME ColonBlink = millis() +500; // SET COLON BLINK TIME } /*F******************************************************************** * **********************************************************************/ void loop( ) { int ndx; delay( 500 ); if( millis() > NewNbrs ) { for( ndx =0; ndx < 4; ndx++ ) Mtx.clearDisplay( ndx ); // AND CLEAR DISPLAY switch( State ) { case 0: putChr( HR10, Nbrs[1] ); // '1' putChr( HR1, Nbrs[2] ); // '2' putChr( MIN10, Nbrs[3] ); // '3' putChr( MIN1, Nbrs[4] ); // '4' State++; break; case 1: putChr( HR10, Nbrs[5] ); // '5' putChr( HR1, Nbrs[6] ); // '6' putChr( MIN10, Nbrs[7] ); // '7' putChr( MIN1, Nbrs[8] ); // '8' State++; break; case 2: putChr( MIN10, Nbrs[9] ); // '9' putChr( MIN1, Nbrs[0] ); // '0' State = 0; break; } NewNbrs = millis() + 1000; // SET DISPLAY UPDATE TIME } if( (ColonBlink < millis()) && (Tggl ^= 1) ) { colon( true ); ColonBlink = millis() + 500; // SET COLON BLINK TIME } delay( 2000 ); } /*F******************************************************************** * USE inbound byte as address, GET 7 bytes from mFont5x7[], ouput each to a row in one of 4 matrices. **********************************************************************/ void putChr( byte mtxNbr, byte dat[] ) { byte ndx, byt; for( ndx =0; ndx < 7; ndx++ ) // SCAN CHR'S 7 ROWS OF 7 BYTES Vs ROW# { byt = dat[ndx]; // GET ASCII NUMERIC VALUE Mtx.setRow( mtxNbr, ndx, byt ); } } /*F******************************************************************** * PUT COLON IN ROW 7 MTX 2 **********************************************************************/ void colon( bool on ) { byte col; if( on ) col = 0X6C; else col =0; Mtx.setColumn( 2, 7, col ); }
![]() |