Having ESP32 synchronized time for blinking LED using NTP sever - esp32

I would like to blink the ESP32 onboard LED (pin 2) every 5 seconds. I have set up a program that sets the time fro NTP sever. After loading the same code onto 3 different ESP32s, the LEDs blink every 5 seconds but are not at the same time. Is this a hardware issue or is my code incorrect? (also, is there a easier way to do this?). Thank you in advance!
#include <WiFi.h>
#include <TimeLib.h>
// Wifi Credentials
const char* ssid = "OhanaAhimsa";
const char* password = "Fam2021Wow!";
//NTP Sever initalization
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
// start now time variable in seconds
//int time_now = now();
//int second ();
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(115200);
// initialize digital pin LED_BUILTIN as an output.
pinMode(2, OUTPUT);
// 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");
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
//disconnect WiFi as it's no longer needed
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);
}
void loop() {
// if (now() > time_now) {
// Reset the time_now to now
// time_now = now();
// print out seconds:
// Serial.println(time_now);
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
// Sets the LED on or off depending on time_now being pair or odd
digitalWrite(2, second() % 5);
}
void printLocalTime(){
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
Serial.print("Day of week: ");
Serial.println(&timeinfo, "%A");
Serial.print("Month: ");
Serial.println(&timeinfo, "%B");
Serial.print("Day of Month: ");
Serial.println(&timeinfo, "%d");
Serial.print("Year: ");
Serial.println(&timeinfo, "%Y");
Serial.print("Hour: ");
Serial.println(&timeinfo, "%H");
Serial.print("Hour (12 hour format): ");
Serial.println(&timeinfo, "%I");
Serial.print("Minute: ");
Serial.println(&timeinfo, "%M");
Serial.print("Second: ");
Serial.println(&timeinfo, "%S");
Serial.println("Time variables");
char timeHour[3];
strftime(timeHour,3, "%H", &timeinfo);
Serial.println(timeHour);
char timeWeekDay[10];
strftime(timeWeekDay,10, "%A", &timeinfo);
Serial.println(timeWeekDay);
Serial.println();
}

you don't wait until time is retrieved from the NTP server and you don't set the time into the TimeLib.
add
time_t now = time(nullptr);
while (now < SECS_YR_2000) { // wait until time is retrieved
delay(100);
now = time(nullptr);
}
setTime(now); // sets the time in TimeLib
With setSyncProvider and setSyncInterval you can setup for TimeLib to sync with ESP32 RTC (which is set from NTP) periodically. See the examples of the TimeLib.

Related

Does NTPClient updates the ESP32 board date and time?

I need to update my current ESP32 date and time in order to correctly report sensor events to server. I need a non blocking implementation....
So far I've used the NTPClient library as follows:
File Ntp.h
class Ntp
{
private:
bool ntpRunning = false;
public:
void setup();
void loop();
void print();
String getDateTime();
};
File Ntp.cpp
#include <NTPClient.h>
#include <Arduino.h>
#include <WiFi.h> // for WiFi shield
#include <WiFiUdp.h>
#include <Logger.h>
#include "Ntp.h"
WiFiUDP ntpUDP;
// By default 'pool.ntp.org' is used with 60 seconds update interval and
// no offset
// NTPClient timeClient(ntpUDP);
// You can specify the time server pool and the offset, (in seconds)
// additionally you can specify the update interval (in milliseconds).
// NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
NTPClient timeClient(ntpUDP);
String Ntp::getDateTime()
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[64];
char buf[64];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf, sizeof tmbuf, "%Y-%m-%d %H:%M:%S", nowtm);
snprintf(buf, sizeof buf, "%s.%06ld", tmbuf, tv.tv_usec);
return (String) buf;
}
void Ntp::print()
{
Serial.print(getDateTime());
Serial.print(" - ");
Serial.println(message);
}
void Ntp::setup()
{
// empty
}
void Ntp::loop()
{
if (!this->ntpRunning && WiFi.status() == WL_CONNECTED)
{
timeClient.begin();
this->ntpRunning = true;
this->print("NTP begin...");
}
if (timeClient.update())
{
this->print("NTP update");
this->print(timeClient.getFormattedTime());
this->print("This is the new date and time")
}
}
My output:
1970-01-01 00:00:14.857479 - NTP begin
1970-01-01 00:00:15.161455 - NTP update
1970-01-01 00:00:15.168832 - 21:59:29
1970-01-01 00:00:15.169365 - This is the new date and time
So, getFormattedDateTime() show current date and time, but it's value is not being set on the device - as can be seen in the log date/time trailler.
I can't find on NtpClient's github page any documentation describing how it works internally, so...
Does ntpClient.update() set's the board clock? If yes, what am I missing on my code?
If not, how can I accomplish this - read NTP server and update the device clock?

Arduino web socket autoreconnect

I am using 2 esp8266, both connected to same network. Esp1 send some data to esp2 using websocket. So basically esp2 connect to esp1 websocket and read data.
My problem is that if esp1 is restarted, after is up again, esp2 does not connect anymore to it and needs restart to connect
This is code I am using on esp2
#include <ESP8266WiFi.h>
#include <WebSocketsClient.h>
#include <ESP8266WebServer.h>
#include <SoftwareSerial.h>
#define USE_SERIAL Serial
#define LEDS 0 //Status led
WebSocketsClient webSocket;
SoftwareSerial COM(5, 4);
long previousMillis = 0;
long interval = 50;
String data;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
yield();
break;
case WStype_CONNECTED: {
webSocket.sendTXT("Connected");
}
yield();
break;
case WStype_TEXT:
if(payload[0] == '#') {
uint32_t dataz = (uint32_t) strtol((const char *) &payload[1], NULL, 10);
if (dataz < 99911) {
data = "0" + String(dataz);
}
else {
data = String(dataz);
}
}
yield();
if (data.length() == 6 ) {
COM.print('<'); // start marker
COM.print(data);
COM.println('>'); // end marker
}
break;
}
}
void setup() {
pinMode(LEDS, OUTPUT);
digitalWrite(LEDS, LOW);
for(uint8_t t = 4; t > 0; t--) {
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFi.begin("xxx", "xxx");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
}
// server address, port and URL
webSocket.begin("192.168.0.30", 81, "/");
// event handler
webSocket.onEvent(webSocketEvent);
// use HTTP Basic Authorization this is optional remove if not needed
//webSocket.setAuthorization("user", "Password");
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
digitalWrite(LEDS, HIGH);
}
void loop() {
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
webSocket.loop();
}
}
I would need some help to make it reconnect when the esp1 is available again after was disconnected
Thank you very much
webSocket.loop(); should be outside of if statement.

NodeMCU Get data from webswerver and update value

I am using Nodenmcu with arduino IDE . I have used DHT11 IC to read temperature and humidity. Now i would like to add parameter in web page called set_temp . When Set_temp value being set to value the value should get updated when change icon has been pressed. Here is my code. My code is working till to enter the text from web but it wont update set_temp value
#include <ESP8266WiFi.h>
#include "DHT.h"
static float Set_Temp;
DHT dht;
int value = LOW;
const char* ssid = "esp8266";
const char* password = "Test123456";
int ledPin = 13; // GPIO13
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
dht.setup(D3); /* D1 is used for data communication */
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// New code has been added
delay(dht.getMinimumSamplingPeriod()); /* Delay of amount equal to sampling period */
float humidity = dht.getHumidity(); /* Get humidity value */
float temperature = dht.getTemperature(); /* Get temperature value */
// Serial.print(dht.getStatusString()); /* Print status of communication */
if(temperature>=Set_Temp)
{
digitalWrite(ledPin, HIGH);
value = HIGH;
}else
{
digitalWrite(ledPin, LOW);
value = LOW;
}
// Read the first line of the request
String request = client.readStringUntil('\r');
Serial.println(request);
client.flush();
// Match the request
/* if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(ledPin, LOW);
value = LOW;
}*/
// Set ledPin according to the request
//digitalWrite(ledPin, value);
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("Relay_Turn_On_Status: ");
if(value == HIGH) {
client.print("On");
} else {
client.print("Off");
}
// client.println("<br><br>");
// client.println("<button>Turn On </button>");
// client.println("<button>Turn Off </button><br />");
// client.println("</html>");
client.print("</html>");
client.print("<head>");
client.print("<title>My Page</title>");
client.print("</head>");
client.print("<body>");
client.print("<br><br>");
client.print("Set_Temp: ");
client.println("<input type=text name=textbox size=5 value=Enter_Temp_Here");
client.println("<br><input type=submit value=Change ><br>");
client.println("</div>");
client.println("</body>");
client.println("</html>");
Set_Temp:"<br><input type=submit value=Change ><br>";
//Set_Temp:"<input type=text name=textbox size=5 value=Enter_Temp_Here>";
Serial.println(Set_Temp);
client.println("<br><br>");
client.println("DHT11_HumidityReading: ");
client.println(humidity,1);
client.println("<br><br>");
client.println("DHT11_Temprature Reading: ");
client.println(temperature,1);
client.println("<br><br>");
client.println("Set_Temp: ");
client.println(Set_Temp);
client.println("<br><br>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}
My main doubt in this part of code where once i read it wont update.
Set_Temp:"<br><input type=submit value=Change ><br>";
//Set_Temp:"<input type=text name=textbox size=5 value=Enter_Temp_Here>";
Serial.println(Set_Temp);
If i use like this. it will display -1
Set_Temp=readString.indexOf(2);
I followed the method of get & post from HTTP https://www.w3schools.com/htmL/[Serial Out Here][web page]
How can i change my Set_Temp value from text box.
Take a look to this article, I follow it to turn on and turn off a light in NodeMCU with Arduino IDE. The client in the web is written on PHP.
https://blog.nyl.io/esp8266-led-arduino/
<?php
$light = $_GET['light'];
if($light == "on") {
$file = fopen("light.json", "w") or die("can't open file");
fwrite($file, '{"light": "on"}');
fclose($file);
}
else if ($light == "off") {
$file = fopen("light.json", "w") or die("can't open file");
fwrite($file, '{"light": "off"}');
fclose($file);
}
?>
I hope this help you.
Regards

nodeMCU connect refused with XMAPP localhost

My project is about using nodeMCU measure value from sensor DHT11 and sent value to database Mysql. I use xampp for server. I cannot sent value to database.
nodeMCU can read value and sent value.But HTTP GET is fail.And return connect refused. I think maybe have problems with port for listening.
this is my code
#include <Arduino.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include "DHT.h"
#define DHTPIN 2 // what digital pin the DHT22 is conected to
#define DHTTYPE DHT11 // there are multiple kinds of DHT sensors
DHT dht(DHTPIN, DHTTYPE);
ESP8266WiFiMulti WiFiMulti;
const char* ssid = "something";
const char* password = "something";
int EP =5;
void setup() {
Serial.begin(115200);
pinMode(EP, INPUT);
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFiMulti.addAP(ssid, password); // ssid , password
randomSeed(50);
}
int timeSinceLastRead = 0;
void loop() {
if ((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient http;
float temp = dht.readTemperature();
float humi = dht.readHumidity();
long meas =TP_init();
Serial.println(WiFi.localIP());
//int temp = random(25,35);
String url = "localhost:8012/add2.php?temp="+String(temp)+"&humi="+String(humi)+"&meas=0";
Serial.println(url);
http.begin(url); //HTTP
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(3000);
}
long TP_init(){
delay(10);
long meas=pulseIn (EP, HIGH); //wait for the pin to get HIGH and returns measurement
return meas;
}
I changed Apache port from 80 to 8012
I use PHPMyadmin for store database . File php's name add2.php for insert value from sensor DHT11
enter image description here
This is result from serial port.
String url = "localhost should be replaced with String url = "<IP-address-of-your-webserver> as the webserver clearly isn't running on the ESP8266.

Measuring Time of Flight with Arduino Uno

I am trying to implement a master/slave setup to determine the time of flight between two Arduino Uno boards and ultimately use that as a measure of distance between the two. Using the standard 16MHz crystal and the APC220 from DFRobot communicating between the two is easy but getting a time of flight reading is where I get stuck.
I use the following code on the master side to send the first signal and receive the echo from the slave:
// set pins:
const int switchPin = 3; // pin number of the switch
// variables:
int switchState = 0; // variable for reading switch status
int iDisplay = 1;
unsigned long start, finished, elapsed;
// initialize
void setup()
{
// initialize switch pin as input:
pinMode(switchPin, INPUT);
// initialize serial wireless communication:
Serial.begin(9600);
// read initial state of switch
switchState = digitalRead(switchPin);
}
void displayResult()
{
float h,m,s,ms;
unsigned long over;
elapsed=finished-start;
h=int(elapsed/3600000);
over=elapsed%3600000;
m=int(over/60000);
over=over%60000;
s=int(over/1000);
ms=over%1000;
Serial.print("Raw elapsed time: ");
Serial.println(elapsed);
Serial.print("Elapsed time: ");
Serial.print(h,0);
Serial.print("h ");
Serial.print(m,0);
Serial.print("m ");
Serial.print(s,0);
Serial.print("s ");
Serial.print(ms,0);
Serial.println("ms");
Serial.println();
}
// program loop
void loop()
{
if (Serial.available()>0 && iDisplay == 1)
{
finished=millis();
displayResult();
iDisplay = 0;//Only once
}
// read switch state and print line if state has changed
switch (digitalRead(switchPin)) { // read pin status
case HIGH:
if (switchState == LOW)
{ // check if message has to be sent
start=millis();
delay(200); // for debounce
iDisplay = 1;//Only once
Serial.println(100); // send message about switch
switchState = HIGH; // message has been sent
}
break;
case LOW:
if (switchState == HIGH)
{ // check if message has to be sent
start=millis();
delay(200); // for debounce
iDisplay = 1;//Only once
Serial.println(100); // send message about switch
switchState = LOW; // message has been sent
}
break;
}
}
And the following code for the slave:
// variables:
int intTime = 0;
// initialize
void setup()
{
// initialize serial wireless communication:
Serial.begin(9600);
}
// program loop
void loop()
{
if (Serial.available()>0)
{
intTime = Serial.parseInt();
if (intTime > 1)
{
Serial.println(intTime);
}
intTime = 0;
}
}
Yet this only returns the 200 Milliseconds from the debounce delay, can this be done with the Arduino? Am I getting the math or the code wrong?

Resources