Go Down

Topic: ESP8266 + NTP (Read 11361 times) previous topic - next topic

Louison

Hi everybody,

My wordclock is over so I'm trying to get the time from a NTP server thanks to ESP8266 used as a shield for my arduino uno.

What I'd like to do :

1. Connect the ESP8266 to my wifi
2. Do a NTP request to a server in France
3. Rewrite the time and date get to a classical format of time.
4. Write this information automatically in my RTC module DS1307 once a day

I found thid code but it failed to transfer to my arduino...

I think I can reuse it in my future code.

https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/NTPClient/NTPClient.ino

I red a lot on the ESP8266.

I already tried successfully to connect to my wifi thanks to AT commands

To do the NTP request, do I have to upgrade the ESP firmware ?

Does someone know how to use this module as a wifi shield ?

Thanks for your help !

Louison

6v6gt

The code for the NTP clock you found needs the Arduino core libraries to be installed on your ESP8266. Then you can use it [the ESP8266] with the Arduino IDE just like your existing Arduino Uno etc.
Here is a good guide based on an Adafruit Huzzah, but you should be able to adapt it to another ESP8266.
Once you have done all that, you can load and run the NTP clock software.

When you have all that working, you can then look at the function setSyncProvider from the Arduino Time Library to sync clock sources.

Louison

Right but what I'd like to do is to use the esp as à shield for m'y arduino uno.

Is there a solution ? I currently don't have the usb adapter for the esp.

scrumfled

There are lots of different ESP8266 implementations, which one do you have? (a link would be a good start).

Louison

It's the ESP-01 version

I found this page wich is very similar to what I want to do.

http://thearduinoguy.org/using-an-esp8266-as-a-time-source/

6v6gt

A shame he didn't finish coding it but it does look like you can access an NTP server with simple AT commands.
He said this: "Message me if you need any help with any of the above." so you could try.

I built an ESP8266 clock recently, but I  used Arduino Core code for the ESP8266 and the Arduino IDE. I used an Arduino Nano (configured as an I2C slave) to handle the multiplexing of the display etc. because of the lack of ESP pins and had to use a level shifter between the ESP and the Nano because the ESP pins are not 5volt tolerant. It also handles DST changes.

Louison

Hi 6v6gt

I tried to compile his code and it's using like 11% regular memory and 75% of dynamic memory on my arduino uno.

My wordclock code is using 40% RM & 21% DM.

The conversion of NTP to regular time is not done neither to write it in the DS1307.

I don't think it will work easily. So I think I will try to program the ESP directly.

What accessory do I need to buy to connect it to my computer ?

6v6gt


J-M-L

I hacked something last night quickly with AT commands

I'm traveling at the moment - will share later when I get a chance and have remote access to my Mac
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

scrumfled

ESP's are pretty light on pins. What else have you got connected, so far its an RTC on I2C, is there also a display?

Re: two sketches seeming hungry before they're merged, dont panic, often you'll find you're reusing libraries etc and the compiled version is smaller than you expect (or at least, it has been for me a few times).


Louison

Thanks jml and scrutin for your replies.

Soit il just bought the usb adapter and some stuff just in case I will not have enough memory or did not find à solution I ll program the Esp directly


http://m.ebay.fr/itm?itemId=282049653681
I have the RTC ds 1307 conected and led strip too.

In fact the display is done by the leds. Like each led = one letter it will write the time.

J-M-L

#11
Oct 28, 2016, 06:21 pm Last Edit: Oct 28, 2016, 06:47 pm by J-M-L
here you go. don't be afraid if it looks long - it's just the comments.

that full sketch once compiled uses up ~6500 bytes and global variables use 759 bytes. memory footprint could be reduced by F()-ing the char strings I'have hardcoded. I've been lazy :)

it's coded just as an example, so a lot of things are just hardcoded and there is no error handling

to ensure your ESP is connected to your wifi change the SSID and PWD in the following line

  espATCommand("AT+CWJAP=\"YOURSSID\",\"YOURPWD\"", "OK", LONG_PAUSE); // connect to wifi

to get an NTP time, adjusted to French time (cf the UTC_DELTA stuff in the code for your time zone ) you just need to do
Code: [Select]
   epochUnix = epochUnixNTP();
    ntpHours = (epochUnix  % NUMBEROFSECONDSPERDAY) / NUMBEROFSECONDSPERHOUR;
    ntpMinutes = (epochUnix % NUMBEROFSECONDSPERHOUR) / NUMBEROFSECONDSPERMINUTE;
    ntpSeconds = epochUnix % NUMBEROFSECONDSPERMINUTE;


attaching the file because it's more than 9000 chars. this is how it works

in the setup() I connect my ESP to my wifi network. here are the AT commands

AT+RESTORE      wait for "ready"   --> reset the ESP
AT             wait for "OK"      --> just to see if all is fine  (useless)
AT+CWMODE=1      wait for "OK"      --> Set the wireless mode
AT+CWQAP         wait for "OK"      --> disconnect, just to make sure (useless)
AT+CWJAP="YOURSSID","YOURPWD"   wait for "OK"      --> connect to wifi
AT+CIPMUX=0         wait for "OK"      --> set the single connection mode


at that point you are connected to the Wifi (or you should).

Then when you want to querry the NTP time, I issue the following AT commands:

AT+CIPSTART="UDP","fr.pool.ntp.org",123      wait for "OK"   --> start UDP session with NTP server
AT+CIPSEND=48                        wait for "OK"   -->  will send 48 bytes


here you need to send the 48 bytes of a NTP request, but only the first 4 matters for us
so I write 0xEC0600E3 to the ESP and then another random 44 bytes, whatever is in memory

ESPSEPRIAL.write((char*) &ntpFirstFourBytes, NTP_PACKET_SIZE);


At that point the CIPSEND command got its 48 bytes, and the NTP server got its stuff and will answer with the NTP buffer. but you can't just read the 48 bytes and hope to get the NTP buffer. before you read the buffer you need to get rid of what the ESP tells you. Mine answers

Recv 48 bytes\r\n\r\nSEND OK\r\n\r\n+IPD,48:

so I wait until I see the : character and then the serial link gives me the 48 bytes, out of which I'm only interested in bytes 40,41,42,43 and 44.  I read all the bytes and do

AT+CIPCLOSE                  wait for "OK"   -->  close the session


that's for the AT commands.

I would suggest you run them first all manually in a direct manual AT session with your ESP to see if you get similar answers from your version of the firmware. My code does not do error checking but the critical one is the : mentioned above as this is how I detect the start of the 48 bytes of the NTP buffer. if you are off when you read the buffer, then nothing will work. so try commands by hands, see what it spits out and if it looks like mine and adjust code accordingly.

I let you see the code for the maths to transform the 32 bits I capture into a time in seconds.

let me know if that works and have fun!
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Louison

Oh my go jml I was not expecting so much ! I ll  check it as soon as I can !

Thanks a lot to all of you ! I ll keep you up dates as soon as possible !

Louison

Hi JML,

I red your code and I figured out something about the rtc lib and the fact u are using an rtc ds3231

I'm using an RTC DS1307 that I configure that way.

Code: [Select]

#include "Wire.h"
#define DS1307_ADDRESS 0x68
byte zero = 0x00; //workaround for issue #527

int minute == 0
int hour == 0
int second == 0

void setup(){
  Wire.begin();
  Serial.begin(9600);
  setDateTime(); //MUST CONFIGURE IN FUNCTION
}

void loop(){
  printDate();
  delay(1000);
}

void setDateTime(){ // I defined x y z a b c d by writting myself so the idea here is to reuse the ones given from the NTP function

  byte second =      x; //0-59
  byte minute =      y; //0-59
  byte hour =        z; //0-23
  byte weekDay =     a; //1-7
  byte monthDay =    b; //1-31
  byte month =       c; //1-12
  byte year  =       d; //0-99

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);

  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));

  Wire.write(zero); //start

  Wire.endTransmission();

}

byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
  return ( (val/16*10) + (val%16) );
}

void printDate(){

  // Reset the register pointer
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111); //24 hour time


  //print the date Eg   23:59:59

  Serial.print(hour);
  Serial.print(":");
  Serial.print(minute);
  Serial.print(":");
  Serial.println(second);

}


So basically I don't need to add a zero before the hour when hour = 0 to 9
I need to reuse hour / minute / second in the ntp code to set the rtc and reuse it in my wordclock code (eg when minute == 0 light led XYZ)

is that possible this way ?

Thanks

Louison

J-M-L

#14
Oct 29, 2016, 07:05 pm Last Edit: Oct 29, 2016, 07:34 pm by J-M-L
The library I use work for the 1307, just neeed to instantiate that object instead of a 3231

The extra zero i add is just to make it nice when printing minutes (I prefer to see 10:09 rather than 10:9) but it's nothing important.

As mentioned above besides the utility functions to send the AT commands, what you need to do is only this:

Code: [Select]

   epochUnix = epochUnixNTP();
    ntpHours = (epochUnix  % NUMBEROFSECONDSPERDAY) / NUMBEROFSECONDSPERHOUR;
    ntpMinutes = (epochUnix % NUMBEROFSECONDSPERHOUR) / NUMBEROFSECONDSPERMINUTE;
    ntpSeconds = epochUnix % NUMBEROFSECONDSPERMINUTE;


Then you have in ntpHours, ntpMinutes and ntpSeconds the values you want to use for z,y and x in your setDateTime function.
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up