Hi all,
I have built a LED clock with an embedded ATMEGA328 and MAX7219 drivers. I want to display time and date, day number (1-366), week number (01-53), temp and humidity (DHT sensor). Originally, I was using an RTC DS3231 module for timekeeping. Then I discovered the ESP32 and I thought it would be cool to use the I2C interface on my board to get the time off the Internet.
Since I’m a rookie with C, I found the piece of code below and I started fiddling with it to extract the time, date, day number and week number.
void printLocalTime()
{
time_t rawtime;
struct tm timeinfo;
if(!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
return;
}
char timeStringBuff[50];
strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo);
//print like "const char*"
Serial.println(timeStringBuff);
//Optional: Construct String object
String asString(timeStringBuff);
}
The Wi-Fi & NTP part is working and I have been able to display time, date, day number and the DHT readings using Nick Gammon’s “I2Canything” library (ESP32 acting as master, embedded ATMEGA 328 as slave).
As long as I use a call to printLocalTime() in my loop, followed by a direct assignment to variables from the so called “specifiers” like timeinfo.tm_sec, it seems to be working (see master code below). I can use the bytes on the slave side to display the variables with ledcontrol.
Trouble is, I cannot fathom how to extract the week number using the printLocalTime function. If I try using the standard strftime() function with the sole “%W” specifier, date and time won’t work.
Do you guys have any idea?
Here is my sandbox code, still sloppy for the time being.
Master code on the ESP32
#include <WiFi.h>
#include "time.h"
#include <I2C_Anything.h>
#include "DHT.h"
const byte SLAVE_ADDRESS = 8;
#define DHTPIN 14
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
const char* ssid = "mySSID";
const char* password = "myKey";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
byte connectionStatus;
byte second;
byte lastSecond;
byte minute;
byte hour;
byte day;
long year;
long yday;
byte month;
byte weekday;
byte isDST;
byte* current;
float hum;
float temp;
struct tm timeinfo;
void printLocalTime()
{
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
//Serial.println(&timeinfo, "%H:%M:%S %d-%m-%y %W %w");
}
void setup()
{
Serial.begin(115200);
dht.begin();
Wire.begin();
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" CONNECTED");
connectionStatus=1;
Wire.beginTransmission(SLAVE_ADDRESS);
I2C_writeAnything (connectionStatus);
Wire.endTransmission();
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
if (WiFi.status() == WL_DISCONNECTED) {
connectionStatus=0;
Wire.beginTransmission(SLAVE_ADDRESS);
I2C_writeAnything (connectionStatus);
Wire.endTransmission();
}
hum = dht.readHumidity();
temp = dht.readTemperature();
delay(300);
Wire.beginTransmission(SLAVE_ADDRESS);
I2C_writeAnything (hum);
I2C_writeAnything (temp);
Wire.endTransmission();
}
void loop()
{
printLocalTime();
second = timeinfo.tm_sec;
minute = timeinfo.tm_min;
hour = timeinfo.tm_hour;
day = timeinfo.tm_mday;
month = timeinfo.tm_mon + 1;
year = timeinfo.tm_year + 1900;
weekday = timeinfo.tm_wday;
yday = timeinfo.tm_yday;
if (lastSecond!=second) {
Wire.beginTransmission(SLAVE_ADDRESS);
I2C_writeAnything (hour);
I2C_writeAnything (minute);
I2C_writeAnything (second);
I2C_writeAnything (day);
I2C_writeAnything (month);
I2C_writeAnything (year);
I2C_writeAnything (weekday);
I2C_writeAnything (yday);
I2C_writeAnything (hum);
I2C_writeAnything (temp);
Wire.endTransmission();
lastSecond=second;
Serial.println(hum);
Serial.println(temp);
}
if (second==30) {
hum = dht.readHumidity();
temp = dht.readTemperature();
Serial.println(hum);
Serial.println(temp);
if (isnan(hum) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
}
}
Slave code on the ATMEGA328
#include <I2C_Anything.h>
#include <LedControl.h>
const byte MY_ADDRESS = 8;
boolean haveData = false;
boolean haveDataWiFi = false;
boolean haveDataDHT = false;
byte connectionStatus;
float h;
float t;
int temp;
int humi;
byte testByte;
byte second;
byte minute;
byte hour;
byte day;
byte month;
long year;
long yday;
byte weekday;
byte lastSecond;
int secOnes=0;
int secTens=0;
int minOnes=0;
int minTens=0;
int hourOnes=0;
int hourTens=0;
int dayOnes=0;
int dayTens=0;
int monthOnes=0;
int monthTens=0;
int yearOnes=0;
int yearTens=0;
int ydayOnes=0;
int ydayTens=0;
int ydayHundreds=0;
int tempDecimal=0;
int tempOnes=0;
int tempTens=0;
int humiHundreds=0;
int humiTens=0;
int humiOnes=0;
int wiFiLed=11;
LedControl lc1=LedControl(6,5,7,1);
LedControl lc2=LedControl(3,2,4,1);
LedControl lc3=LedControl(9,8,10,1);
void setup() {
Serial.println("Start");
Wire.begin(MY_ADDRESS;
Wire.onReceive(receiveEvent);
Serial.begin(115200);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(wiFiLed,OUTPUT);
lc1.shutdown(0,false);
lc2.shutdown(0,false);
lc3.shutdown(0,false);
delay(50);
lc1.setIntensity(0,8);
lc2.setIntensity(0,8);
lc3.setIntensity(0,8);
delay(50);
lc1.clearDisplay(0);
lc2.clearDisplay(0);
lc3.clearDisplay(0);
delay(50);
}
void loop()
{
if (haveDataWiFi)
{
if (connectionStatus == 1) {
digitalWrite (wiFiLed, HIGH);
}
else {
digitalWrite (wiFiLed, LOW);
}
haveDataWiFi=false;
}
if (haveData)
{
if (second != lastSecond) {
secOnes=second%10;
secTens=(second/10)%6;
minOnes=minute%10;
minTens=(minute/10)%6;
hourOnes=hour%10;
hourTens=(hour/10)%10;
lc1.setDigit(0,7,hourTens,false);
lc1.setDigit(0,6,hourOnes,false);
lc1.setChar(0,5,'-',false);
lc1.setDigit(0,4,minTens,false);
lc1.setDigit(0,3,minOnes,false);
lc1.setChar(0,2,'-',false);
lc1.setDigit(0,1,secTens,false);
lc1.setDigit(0,0,secOnes,false);
lastSecond=second;
}
dayOnes=day%10;
dayTens=(day/10)%10;
monthOnes=month%10;
monthTens=(month/10)%10;
yearOnes=(year-2000)%10;
yearTens=(year%2000)/10;
lc2.setDigit(0,1,yearTens,false);
lc2.setDigit(0,0,yearOnes,false);
lc2.setChar(0,2,'-',false);
lc2.setDigit(0,4,monthTens,false);
lc2.setDigit(0,3,monthOnes,false);
lc2.setChar(0,5,'-',false);
lc2.setDigit(0,7,dayTens,false);
lc2.setDigit(0,6,dayOnes,false);
ydayOnes=yday%10;
ydayTens=(yday/10)%10;
ydayHundreds=(yday/100)%4;
lc3.setDigit(0,0,ydayHundreds,false);
lc3.setDigit(0,1,ydayTens,false);
lc3.setDigit(0,2,ydayOnes,false);
haveData = false;
}
if (haveDataDHT) {
humi = h;
temp = (int) t;
haveDataDHT=false;
}
humiOnes=humi%10;
humiTens=(humi/10)%10;
tempOnes=temp%10;
tempTens=(temp/10)%10;
lc3.setDigit(0,4,humiTens,false);
lc3.setDigit(0,5,humiOnes,false);
lc3.setDigit(0,6,tempTens,false);
lc3.setDigit(0,7,tempOnes,false);
}
void receiveEvent (int howMany)
{
if (howMany >= (sizeof second) + (sizeof minute) + (sizeof hour) + (sizeof day) + (sizeof month) + (sizeof year) + (sizeof weekday) + (sizeof yday))
{
I2C_readAnything (hour);
I2C_readAnything (minute);
I2C_readAnything (second);
I2C_readAnything (day);
I2C_readAnything (month);
I2C_readAnything (year);
I2C_readAnything (weekday);
I2C_readAnything (yday);
haveData = true;
}
if (howMany == (sizeof connectionStatus))
{
I2C_readAnything (connectionStatus);
haveDataWiFi = true;
}
if (howMany >= (sizeof h) + (sizeof t))
{
I2C_readAnything (h);
I2C_readAnything (t);
haveDataDHT = true;
}
}
Cheers,
Fred