Devices & Components
1
Arduino® UNO R4 WiFi
Software & Tools
Arduino IDE
Project description
Code
aur4_clock
A Arduino code
aur4_clock.ino
cpp
Main code
1/* 2 3 AUR4 Clock 4 RTC clock using NTP server to sync time 5 6 Created using the Arduino Uno R4 Wifi example code - RTC_NTPSync, initially created by Sebastian Romero @sebromero 7 8 * Instructions: 9 * 1. Change the WiFi credentials in the arduino_secrets.h file to match your WiFi network. 10 * 2. Set the orientation using the #define ORIENTATION 0 or 1 11*/ 12 13#include "led-matrix.h" 14#include "Arduino_LED_Matrix.h" 15#include "RTC.h" 16#include <WiFiS3.h> 17#include "arduino_secrets.h" 18 19#define TIMEZONE_OFFSET_HOURS 2 20#define ORIENTATION 1 // 0 (up is where the ESP32 is), 1 (up is where the Qwiic is) 21 22unsigned long currentMillis; 23unsigned long previousMillis = 0; 24 25byte currentFrame[NO_OF_ROWS][NO_OF_COLS]; 26byte rotatedFrame[NO_OF_ROWS][NO_OF_COLS]; 27 28position first = {5, 0}; // position of first digit 29position second = {0, 0}; // etc. 30position third = {5, 7}; 31position fourth = {0, 7}; 32 33// please enter your sensitive data in the Secret tab/arduino_secrets.h 34char ssid[] = SECRET_SSID; // your network SSID (name) 35char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) 36 37constexpr unsigned int LOCAL_PORT = 2390; // local port to listen for UDP packets 38constexpr int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message 39 40int wifiStatus = WL_IDLE_STATUS; 41IPAddress timeServer(162, 159, 200, 123); // pool.ntp.org NTP server 42byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 43WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP 44 45ArduinoLEDMatrix matrix; 46 47void setDigit(position digitPosition, const byte digit[][5]){ 48 for(byte r = 0; r < 3; r++){ 49 for(byte c = 0; c < 5; c++){ 50 currentFrame[r+digitPosition.row][c+digitPosition.col] = digit[r][c]; 51 } 52 } 53} 54 55void rotateFrame(){ 56 for(byte r = 0; r < NO_OF_ROWS; r++){ 57 for(byte c = 0; c < NO_OF_COLS; c++){ 58 rotatedFrame[r][c] = currentFrame[NO_OF_ROWS-1-r][NO_OF_COLS-1-c]; 59 } 60 } 61 memcpy(currentFrame, rotatedFrame, sizeof rotatedFrame); 62} 63 64// send an NTP request to the time server at the given address 65unsigned long sendNTPpacket(IPAddress& address) { 66 // set all bytes in the buffer to 0 67 memset(packetBuffer, 0, NTP_PACKET_SIZE); 68 // Initialize values needed to form NTP request 69 // (see URL above for details on the packets) 70 packetBuffer[0] = 0b11100011; // LI, Version, Mode 71 packetBuffer[1] = 0; // Stratum, or type of clock 72 packetBuffer[2] = 6; // Polling Interval 73 packetBuffer[3] = 0xEC; // Peer Clock Precision 74 // 8 bytes of zero for Root Delay & Root Dispersion 75 packetBuffer[12] = 49; 76 packetBuffer[13] = 0x4E; 77 packetBuffer[14] = 49; 78 packetBuffer[15] = 52; 79 80 // all NTP fields have been given values, now 81 // you can send a packet requesting a timestamp: 82 Udp.beginPacket(address, 123); //NTP requests are to port 123 83 Udp.write(packetBuffer, NTP_PACKET_SIZE); 84 Udp.endPacket(); 85} 86 87void printWifiStatus() { 88 // print the SSID of the network you're attached to: 89 Serial.print("SSID: "); 90 Serial.println(WiFi.SSID()); 91 92 // print your board's IP address: 93 IPAddress ip = WiFi.localIP(); 94 Serial.print("IP Address: "); 95 Serial.println(ip); 96 97 // print the received signal strength: 98 long rssi = WiFi.RSSI(); 99 Serial.print("signal strength (RSSI):"); 100 Serial.print(rssi); 101 Serial.println(" dBm"); 102} 103 104void connectToWiFi(){ 105 // check for the WiFi module: 106 if (WiFi.status() == WL_NO_MODULE) { 107 Serial.println("Communication with WiFi module failed!"); 108 // don't continue 109 while (true); 110 } 111 112 String fv = WiFi.firmwareVersion(); 113 if (fv < WIFI_FIRMWARE_LATEST_VERSION) { 114 Serial.println("Please upgrade the firmware"); 115 } 116 117 // attempt to connect to WiFi network: 118 while (wifiStatus != WL_CONNECTED) { 119 Serial.print("Attempting to connect to SSID: "); 120 Serial.println(ssid); 121 // Connect to WPA/WPA2 network. Change this line if using open or WEP network: 122 wifiStatus = WiFi.begin(ssid, pass); 123 } 124 delay(5000); 125 Serial.println("Connected to WiFi"); 126 printWifiStatus(); 127} 128 129/** 130 * Calculates the current unix time, that is the time in seconds since Jan 1 1970. 131 * It will try to get the time from the NTP server up to `maxTries` times, 132 * then convert it to Unix time and return it. 133 * You can optionally specify a time zone offset in hours that can be positive or negative. 134*/ 135unsigned long getUnixTime(int8_t timeZoneOffsetHours = 0, uint8_t maxTries = 5){ 136 // Try up to `maxTries` times to get a timestamp from the NTP server, then give up. 137 for (size_t i = 0; i < maxTries; i++){ 138 sendNTPpacket(timeServer); // send an NTP packet to a time server 139 // wait to see if a reply is available 140 delay(1000); 141 142 if (Udp.parsePacket()) { 143 Serial.println("Packet received."); 144 Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer 145 146 //the timestamp starts at byte 40 of the received packet and is four bytes, 147 //or two words, long. First, extract the two words: 148 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); 149 unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); 150 151 // Combine the four bytes (two words) into a long integer 152 // this is NTP time (seconds since Jan 1 1900): 153 unsigned long secsSince1900 = highWord << 16 | lowWord; 154 155 // Now convert NTP time into everyday time: 156 // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: 157 const unsigned long seventyYears = 2208988800UL; 158 unsigned long secondsSince1970 = secsSince1900 - seventyYears + (timeZoneOffsetHours * 3600); 159 return secondsSince1970; 160 } else { 161 Serial.println("Packet not received. Trying again."); 162 } 163 } 164 return 0; 165} 166 167void updateTime(){ 168 yield(); 169 Serial.println("\nStarting connection to NTP server..."); 170 auto unixTime = getUnixTime(TIMEZONE_OFFSET_HOURS, 25); 171 Serial.print("Unix time = "); 172 Serial.println(unixTime); 173 if(unixTime == 0){ 174 unixTime = getUnixTime(2,25); 175 } 176 RTCTime timeToSet = RTCTime(unixTime); 177 RTC.setTime(timeToSet); 178 Serial.println("Time updated."); 179} 180 181void setup() { 182 Serial.begin(9600); 183 connectToWiFi(); 184 Udp.begin(LOCAL_PORT); 185 186 RTC.begin(); 187 updateTime(); 188 matrix.begin(); 189} 190 191void loop() { 192 currentMillis = millis(); 193 if(currentMillis - previousMillis > 43200000){ // 1000 * 60 * 60 * 12 194 updateTime(); 195 previousMillis = currentMillis; 196 } 197 198 RTCTime currentTime; 199 RTC.getTime(currentTime); 200 201 String hour = (String) currentTime.getHour(); 202 if (hour.length() == 1){ 203 hour = "0" + hour; 204 } 205 206 String minutes = (String) currentTime.getMinutes(); 207 if (minutes.length() == 1){ 208 minutes = "0" + minutes; 209 } 210 211 setDigit(first, digits[hour.substring(0,1).toInt()]); 212 setDigit(second, digits[hour.substring(1).toInt()]); 213 setDigit(third, digits[minutes.substring(0,1).toInt()]); 214 setDigit(fourth, digits[minutes.substring(1).toInt()]); 215 if (ORIENTATION == 1){ 216 rotateFrame(); 217 } 218 matrix.renderBitmap(currentFrame, NO_OF_ROWS, NO_OF_COLS); 219 220 delay(1000); 221}
led-matrix.h
cpp
Library with BMP digits etc.
1#define NO_OF_ROWS 8 2#define NO_OF_COLS 12 3 4typedef struct position { 5 byte row; 6 byte col; 7} position; 8 9const byte digits[][3][5] = { 10 {//0 11 {1, 1, 1, 1, 1}, 12 {1, 0, 0, 0, 1}, 13 {1, 1, 1, 1, 1} 14 }, 15 {//1 16 {0, 0, 0, 0, 1}, 17 {1, 1, 1, 1, 1}, 18 {0, 1, 0, 0, 1} 19 20 }, 21 {//2 22 {1, 1, 1, 0, 1}, 23 {1, 0, 1, 0, 1}, 24 {1, 0, 1, 1, 1} 25 }, 26 {//3 27 {1, 1, 1, 1, 1}, 28 {1, 0, 1, 0, 1}, 29 {1, 0, 1, 0, 1} 30 }, 31 {//4 32 {1, 1, 1, 1, 1}, 33 {0, 0, 1, 0, 0}, 34 {1, 1, 1, 0, 0} 35 }, 36 {//5 37 {1, 0, 1, 1, 1}, 38 {1, 0, 1, 0, 1}, 39 {1, 1, 1, 0, 1} 40 }, 41 {//6 42 {1, 0, 1, 1, 1}, 43 {1, 0, 1, 0, 1}, 44 {1, 1, 1, 1, 1} 45 }, 46 {//7 47 {1, 1, 0, 0, 0}, 48 {1, 0, 1, 0, 0}, 49 {1, 0, 0, 1, 1} 50 }, 51 {//8 52 {1, 1, 1, 1, 1}, 53 {1, 0, 1, 0, 1}, 54 {1, 1, 1, 1, 1} 55 }, 56 {//9 57 {1, 1, 1, 1, 1}, 58 {1, 0, 1, 0, 1}, 59 {1, 1, 1, 0, 1} 60 } 61};
Comments
Only logged in users can leave comments