[CLOSED] NodeMCU ESP8266 Errors & Time.h Fail

I'm developing on a NodeMCU board retrieving epoch from a time server (NTP). Everything was working as expected until I added: #include <Time.h> so that I could get the date from Unix time.

The sketch fails to compile with: 'day' was not declared in this scope

I tried adding #include <TimeLib.h> but that causes a whole stack of errors about multiple libraries. This also happens if I add both libraries. As soon as I remove Time.h my project builds/runs fine.

I thought Time.h was a standard Arduino lib. Not sure if I can properly or reliably extract the date myself without using this library.

unsigned long epoch = GetDateTime();
if (epoch)
{
  epoch += 36000; // + 10 hours
  epoch += 3600; // + 1 hour for daylight saving
  Serial.println(epoch);
  Serial.printf("\rDate:\t%d:%d:%d   ", day(epoch), month(epoch), year(epoch));
  Serial.printf("\rTime:\t%d:%d:%d   ", GetHours(epoch), GetMinutes(epoch), GetSeconds(epoch));
}

int GetSeconds(uint32_t unixTime)
{
  return unixTime % 60;
}

int GetMinutes(uint32_t unixTime)
{
  return unixTime / 60 % 60;
}

int GetHours(uint32_t unixTime)
{
  return unixTime / 3600 % 24;
}

Post your entire sketch please. Serial does not have a 'printf' member function so the code you presented cannot possibly compile.

You may want to have a look at that library

ToddL1962:
Serial does not have a 'printf' member function so the code you presented cannot possibly compile.

actually you are not right on that one. printf() is part of the default libraries on a ESP8286 or ESP32 (because there is enough memory to have the full library)

J-M-L:
actually you are not right on that one. printf() is part of the default libraries on a ESP8286 or ESP32 (because there is enough memory to have the full library)

Oops. My bad. Thanks for straightening me out!

ToddL1962:
Post your entire sketch please. Serial does not have a 'printf' member function so the code you presented cannot possibly compile.

I will post my entire sketch - but it certainly compiles, runs and correctly displays the time!

Here is the complete code. I just don't know why the default Arduino time library fails.

// Simple Web client example
#include <Arduino.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiUdp.h>
//#include <Time.h>
//#include <TimeLib.h>

#ifndef STASSID
#define STASSID "***"
#define STAPSK  "***"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;
char c = '.';
bool is_get_time_completed = false;
bool is_get_staff_completed = false;

const char* ntp_server_name = "time.nist.gov"; // pool.ntp.org
const int ntp_packet_size = 48; // NTP time stamp is in the first 48 bytes of the message
unsigned long ntp_interval = 300000; // request NTP time every 5 minutes
unsigned long ntp_previous = 0;
unsigned long ntp_last_response = millis();
unsigned long previous_actual_time = 0;
uint32_t time_unix = 0;
byte ntp_buffer[ntp_packet_size]; // buffer to hold incoming and outgoing packets

WiFiUDP UDP; // create an instance of the WiFiUDP class to send and receive
IPAddress time_server_ip; // time.nist.gov NTP server address

static WiFiClientSecure client;

void setup()
{
  Serial.begin(9600); // 115200
  delay(50);
  Serial.println();
  
  // try to connect to access point & wait for a connection
  StartWiFi();
  
  // Get the IP address of the NTP server
  if(!WiFi.hostByName(ntp_server_name, time_server_ip)) 
  {
    Serial.println("DNS lookup failed. Rebooting.");
    Serial.flush();
    ESP.reset();
  }
  Serial.print("Time Server IP: ");
  Serial.println(time_server_ip);
}

void loop()
{
  // get datetime
  if (is_get_time_completed == false)
  {
    // init
    is_get_time_completed = true;
    unsigned long epoch = GetDateTime();
    if (epoch)
    {      
      Serial.println(epoch);
      Serial.printf("\rUTC Time:\t%d:%d:%d   ", GetHours(epoch), GetMinutes(epoch), GetSeconds(epoch));
      epoch += 36000; // + 10 hours
      epoch += 3600; // + 1 hour for daylight saving
      Serial.printf("\rLocal Time:\t%d:%d:%d   ", GetHours(epoch), GetMinutes(epoch), GetSeconds(epoch));
      // Serial.printf("\rLocal Date:\t%d:%d:%d   ", day(epoch), month(epoch), year(epoch));
    }   
  }
}

void StartWiFi()
{
  Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("WiFi Connected: ");
  Serial.println(WiFi.localIP());
}

void StartUDP()
{
  Serial.println("Starting UDP");
   // start listening for UDP messages on port 123
  if (UDP.begin(123))
  {
    Serial.print("Local port: ");
    Serial.println(UDP.localPort());
    Serial.println();
  }
}

inline int GetSeconds(uint32_t unixTime)
{
  return unixTime % 60;
}

inline int GetMinutes(uint32_t unixTime)
{
  return unixTime / 60 % 60;
}

inline int GetHours(uint32_t unixTime)
{
  return unixTime / 3600 % 24;
}

unsigned long GetDateTime(void)
{
  uint32_t t;
  Serial.println(F("Connecting to time server to issue request..."));
  WiFiUDP udpClient;
  if (udpClient.begin(123))
  {
    Serial.println(F("OK udpClient.begin(123)"));
    memset(ntp_buffer, 0, ntp_packet_size);  // set all bytes in the buffer to 0
    // Initialize values needed to form NTP request
    ntp_buffer[0] = 0b11100011;   // LI, Version, Mode
    // send a packet requesting a timestamp
    udpClient.beginPacket(time_server_ip, 123); // NTP requests are to port 123
    udpClient.write(ntp_buffer, ntp_packet_size);
    udpClient.endPacket();
    delay(1000);
    
    Serial.print(F("\r\nAwaiting response..."));
    memset(ntp_buffer, 0, ntp_packet_size); // sizeof(ntp_buffer)
    int packet_size = udpClient.parsePacket();
    if (packet_size)
    {
      udpClient.read(ntp_buffer, ntp_packet_size);
      t = (((unsigned long)ntp_buffer[40] << 24) |
           ((unsigned long)ntp_buffer[41] << 16) |
           ((unsigned long)ntp_buffer[42] <<  8) |
            (unsigned long)ntp_buffer[43]) - 2208988800UL;
      Serial.print(F("OK GetDateTime()\r\n"));
      Serial.println(t);
    }
  }
  if(!t)
    Serial.println(F("GetDateTime() error"));
  return t;
}

Here is the complete code. I just don't know why the default Arduino time library fails.

Your code compiles successfully for me with the exp8266 core v2.2.4 and Time v1.5 installed through the library manger of the ide.

Try to uninstall and reinstall the library.

I did have this library commented out, as I did not have it

//#include <ArduinoJson.h>

I tried re-installing Time by Michael Margolis, but no difference. Current version installed is 1.5.0. Even if I comment out the Time library my project won't compile now.

Below is the compile error message. Strange - without the Time library it compiled yesterday. Now it's failing. So frustrating trying to get this basic sketch working :frowning:

COMPILE ERROR:
Arduino: 1.8.10 (Windows 10), TD: 1.48, Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new can abort), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

C:\Users\ross\AppData\Local\Arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506/bin/xtensa-lx106-elf-ar: unable to rename 'libraries\ESP8266WiFi\ESP8266WiFi.a'; reason: File exists

Multiple libraries were found for "ArduinoJson.h"
Used: C:\Users\ross\Documents\Arduino\libraries\ArduinoJson
Multiple libraries were found for "ESP8266WiFi.h"
Used: C:\Users\ross\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.2\libraries\ESP8266WiFi
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

UPDATE - Strange that this works, but I don't know why.

In the Arduino IDE I opened the example Blink sketch for ESP8266 and changed LED_BUILTIN to D7.
The sketch compiled and uploaded to the NodeMCU board, and when I connect an LED between D7 & GND it blinks as expected.

I then re-opened my initial NTP sketch (with TimeLib.h included) and now it compiles and uploads without issue, with the following output:

Awaiting response...OK GetDateTime()
1576045027
1576045027

UTC Time: 6:17:7
Local Time: 17:17:7
Local Date: 11:12:2019

The only way I can compile and run a project is to first upload an example blink sketch!

Multiple libraries were found for "ESP8266WiFi.h"
 Used: C:\Users\ross\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.2\libraries\ESP8266WiFi
exit status 1

You are obviously using core 2.6.2 (i didn't know that was already available)

The sketch compiled and uploaded to the NodeMCU board, and when I connect an LED between D7 & GND it blinks as expected.

I hope you added a small resistor in between as well to limit the current, also keep in mind that it is better to make LED's active LOW, (though for the pin you used it doesn't matter) to prevent accidentally changing the boot-mode. The actual builtin led on GPIO2 is active LOW.

I'm not that smart with electronics but I do know how to use a resistor with an LED.

I'm having so much trouble with my NodeMCU I'm not sure it's going to be feasible. Sometimes the sketch compiles and sometimes it doesn't - even with no changes to the code.

For example, now I'm getting another error message and again it won't compile:
Fatal error: can't create libraries\ESP8266WiFi\BearSSLHelpers.cpp.o: Permission denied

10 minutes later I tried again and now this error is gone!

I'm not that smart with electronics but I do know how to use a resistor with an LED.

One never knows, very smart people can make obvious mistakes.

I'm having so much trouble with my NodeMCU I'm not sure it's going to be feasible

I suspect you have more than 1 core installed somehow. (or another weird happening) anyway i suggest you go to Tools -> Board -> Board Manager and find the ESP (probably all the way at the bottom) and uninstall whatever version you have installed (hit remove), check again to see if there is nothing installed if there is remove that, until there is no ESP core installed. Then go to Used: C:\Users\ross\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\(if that still exists, and remove whatever you find there. Close the IDE & re-open it (actually just in case, reboot the computer, so we know for sure any Java- process has been completed) and now through the boards manager install the ESP core, and i suggest first to try v2.4.2 (2.5.2 should also be stable and even 2.6.1 should be, but i've bee having issues with those)

Multiple libraries were found for "ArduinoJson.h"
 Used: C:\Users\ross\Documents\Arduino\libraries\ArduinoJson
Multiple libraries were found for "ESP8266WiFi.h"

the ESP8266WiFi.h is a builtin library, there should only be 1. The ArduinoJson.h is not builtin i think, but it would be better to make sure no multiple versions exist side by side. Best is to remove both and re-install to your sketch\libraries folder.

Oh 1 more thing, with IDE built 1.8.x i noticed that the progress bar fills up all the way to the end, way before the compilation is complete. The compilation process is not complete until the compiler answers back at you either with error messages & terminated or completed. It may take quite a while depending on your hw-configuration, but refrain from hitting the compile or upload button while it's compiling.

Thanks Deva_Rishi for your response - it's much appreciated. I think I only had one version of ESP8266 installed (see pic below).

BOARD ESP8266

I uninstalled ESP8266 board and re-installed using version 2.4.2. Now I'm looking into the duplicate libraries issue. Is there a "default" location where all libraries should be installed?. I seem to have libraries in two locations:

LIBRARIES

Searching C: drive for ESP8266WiFi.h only finds one file in this folder: c:\users...\Arduino15\packages...

Searching C: drive for ArduinoJson.h only finds one file in this folder: c:\users\ross\Documents\Arduino\libraries\ArduinoJson...

AFTER INSTALLING ESP8266 2.4.2

Things have settled down a lot! My NTP test project now compiles with zero errors.

However, my other project doesn't compile now - it throws an error on: client.setInsecure();

'class axTLS::WiFiClientSecure' has no member named 'setInsecure'

If I remove "client.setInsecure();" it fails to connect to my IIS web service which uses SSL.

I guess the "setInsecure" method was added in a later version. Perhaps I should now try 2.5.2?

AFTER INSTALLING ESP8266 2.5.2:

After I uninstalled 2.4.2 and then installed 2.5.2 everything went pear shaped again. Even my basic test NTP project fails to compile.

UPDATE

I tried changing the board to NodeMCU 0.9 (ESP-12 Module) which compiled and uploaded but the code failed when attempting to get NTP.

I then changed the board back to NodeMCU 1.0 (ESP-12E Module) and now my test NTP project and https project both compiled and ran successfully!

Not sure what I can do for now. I will keep testing and see what results I get.

Now I'm looking into the duplicate libraries issue. Is there a "default" location where all libraries should be installed?. I seem to have libraries in two locations:

there are actually 3 main locations, The second you see is the ESP-core specific location, those libraries are builtin to the core installation. (AVR has a folder for that as well) The first is the Location for libraries that are builtin to the IDE install (but not core specific) and as a subfolder to your main-sketch folder you can install user or custom libraries that you will want to retain if you upgrade the IDE.

I think I only had one version of ESP8266 installed (see pic below).

I was basing that on the error msg, that involved a file in ...\tools\2.5.0.. to which access was denied, maybe that is just being used by 2.6.2 as well.

'class axTLS::WiFiClientSecure' has no member named 'setInsecure'

If I remove "client.setInsecure();" it fails to connect to my IIS web service which uses SSL.

I guess the "setInsecure" method was added in a later version.

i guess, yes in a later version of WifiClientSecure() though the function it actually is a patch for something else, you don't add the fingerprint to the cypher (it can be nearly impossible to get that to work properly) so the https connection is rejected but by setting insecure you can access it as http. You could just stick to core 2.4.2 and update <WiFiClientSecure.h> if all else fails. (or you can try and see if you can get the fingerprint thing to work properly)

Thanks for your input Deva_Rishi.

I continued to have a lot of compile errors despite trying different versions of the library. The duplicate library errors were not correct. For example, my sketch would not compile, so I'd then upload a basic blink sketch, then re-open my sketch and it would compile without error. After making changes and trying to upload again, the errors returned.

I ended up switching to an ESP32 Esspressif board which is working perfectly with no issues and it's pretty much the same code.