text:
Generation of TTL Signal
I would like to generate a TTL signal using an Arduino.
As far as I understand, a TTL signal is just a predefined controlled signal that repeats at a certain interval (e.g. 2 μs).
An Arduino circuit arguably has a very fast clock (e.g. 16 MHz), so what I thought is I can basically just draw a square signal for whatever desirable interval (important to be down to the microsecond).
I used the following code, choosing a pin and changing its signal state between 0 and 1 and then using Serial.println to draw the signal out. Everything is inside a while loop that times everything to be generated exactly within 1 second.
#include <arduino-timer.h>

// Variables
unsigned long v = -1;
int freq = 100.0; // Hz
unsigned long d = floor(1.0/freq*1000000.0) ; // us
Timer<1, micros> timer; // create a timer with 1 task and microsecond resolution

void setup() {
  unsigned long repeatEvery = 5000000; // Microseconds
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  timer.every(repeatEvery, func1); // XXXXX microsec
}

void func1() {
  unsigned long uSec = 1000000; // Microseconds (= 1 sec)

  PORTD = B00000000;
  v = digitalRead(3);

  unsigned long counter = 0, i = 0;

  auto currentTime = micros();
  auto prevTime = currentTime;
  d = 0; // no delay to check the speed of the execution

  do {
    PORTD = B00001000;
    v = digitalRead(3);
    // Serial.println(v);
    PORTD = B00001000;
    v = digitalRead(3);
    // Serial.println(v);
    delayMicroseconds(d); // first frame

    PORTD = B00000000;
    v = digitalRead(3);
    // Serial.println(v);
    PORTD = B00000000;
    v = digitalRead(3);
    // Serial.println(v);
    delayMicroseconds(d); // second frame

    currentTime = micros();
    i = (unsigned long)(currentTime - prevTime);
    counter++;
  } while(i < uSec);

  Serial.print(">>>Counter:");
  Serial.println(counter);
  Serial.print(">>>delay (ms):");
  Serial.println(d);
}

void loop() {
  timer.tick();
}

The code above will give output as counter = 47620 // how many times the instructions were repeated
and if the Serial.println lines were uncommented to draw the signal then the execution time slows down to counter = 86

I am not sure if the whole train of thought is wrong and I should do something else or use a different circuit.
Any hint or help would be highly appreciated.
PS: my Arduino by the way is a UNIROI that is supposed to be the same as an Arduino R3.

Describing your code makes it rather difficult to understand. Could you just post the code instead?

TTL signal is just a predefined controlled signal that repeats at a certain interval ... no TTL is a logic level that is 5 V when high and 0 V when low ... it does not necessarily repeat ... it could easily always be high

The 1u/2us are pretty fast - you have 16 or 32 instruction cycles @16MHz.
And now you have digitalRead that usually takes around 70 instruction cycles (several times), after that 32b arithmetics (hundreds instructios).
When you uncomment Serial.printlns that starts being blocking after the internal buffer is filled plus you even use 9600bauds speed (960 characters per second max speed), each println means 3 characters and it's there 4 times -> 960/12 = around 80 loops per second. Do you see the pattern?
The only way to generate jitter free signals are timers (probably fast PWM with prescaler=1 and top value according to your desired period).

I see the problem already yeah and thanks for the answer. The thing is that, I am not too familiar yet with all these electronic circuits (instructions). So I would appreciate a link or more details that could help putting me on the right track.

It'd be "AVR instruction set manual", however for the Timer setting the "Atmega328p datasheet" will be more interesting

I will look that up, thanks for the tip


text:
What is the ideal way to check if time on ESP8266 via NTP is ready?
With ESP8266, I noticed that for the first 1 or 2 loops, localtime returns Unix epoch (1970 date) until it has finished getting the actual time from NTP, after which point I see the real date. Sometimes it can take 10 seconds or so before NTP is available, depending on what time server I use and how frequently I make requests to it (most time servers have request throttling, it seems).
Right now, I'm checking whether the date is valid by testing if the year is 70 but this seems weird and hacky. Is there a better way? For instance, is there a function that returns true if the NTP update has been successful or -1 if not?
All of the examples of localtime that I have found so far don't seem to check if the date is valid, and if I run their code, it almost always prints the 1970 Unix epoch date on the first loop.
#define TIME_SERVER_1 "time.google.com"
#define TIME_SERVER_2 "time.nist.gov"
#define TIME_SERVER_3 "pool.ntp.org"
#define TIMEZONE TZ_Europe_London

void setup() {

// ..

  configTime(TIMEZONE, TIME_SERVER_1, TIME_SERVER_2, TIME_SERVER_3);

// ..

}

void loop() {

// ..

      time_t now;
      time(&now);
      struct tm* timeinfo = localtime(&now);

      // TODO: maybe there's a better way to check unknown time?
      if (timeinfo->tm_year == 70) {
        TRACE_LN(F("ntp not yet available"));
      } else {
        epoch = mktime(timeinfo);
      }

//..

}

Doesn't time() return −1 if it cannot get the time? At least that is what it is supposed to do.

Unfortunately, it doesn't seem to return -1. When the year is 70, the result from time is 18 (I guess that's how many seconds the device has been online). When the year is valid, it returns expected epoch, e.g. 1670274493.

I guess, localtime even starts at 31-Dec-1969 afternoon in a western time zone. Thus comparing the local year with 70 is really a strange approach. Rather test the raw time_t value.

You can define a call back function which is triggered when SNTP updates the system time. There is an example of it on the GitHub esp8266/Arduino project with a short description in the comments. The call back function is registered by the example function call settimeofday_cb(time_is_set) where time_is_set() is a user defined funtion.
I have an application (a timeswitch) which maintains an indicator to show how 'fresh' the current time status is. If it is stale, the time source reverts to an RTC until a new time can be fetched. It uses this callback mechanism for that purpose.

Oh awesome!! Nice find.

Eventually tested this today, settimeofday_cb works great.

If time() doesn't return -1 as expected when it doesn't know, then I
have nothing cleaner (less “hacky”) to suggest. That being said,
converting the scalar time to a broken-down representation is a
relatively expensive operation. I suggest avoiding it and just comparing
the returned time to an arbitrary threshold:
// May we consider this valid as the "current" time?
// If it is too far in the past, it is centainly not valid.
static bool is_time_valid(time_t t) {
    const time_t old_past = 1577836800;  // 2020-01-01T00:00:00Z
    return t >= old_past;
}

Yes! Checking if year is 70 did feel really strange indeed; I wasn't convinced that I could guarantee 1970 being Epoch, and as you rightly say in the comments, Epoch could be 1969 in a western time zone.

The following code snippet is most likely the best way of ensuring valid time from NTP. If the call to timeSetup(...) is made after already connected to the internet, then that connection will be used, otherwise the setup will connect to internet, using passed in credetials, and when finished getting NTP time, will disconnect. The code has been cut/pasted from a much bigger project and has not been tested, so there might be some syntax errors.
The SNTP stuff:
#include "sntp.h"
#include "time.h"
#include <sys/time.h>
#include <WiFi.h>

int WiFiconnectedhere = 0;
int timeIsSet = 0;

// timeavailable() cannot be in a class has to be static
//callback function when time has been set
void timeavailable(struct timeval *t)
{
  struct tm timeinfo;
  Serial.println("NTP notification that time is set");

  if (!getLocalTime(&timeinfo)){
    Serial.println("Using getLocalTime()No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "using getLocalTime() = %A, %B %d %Y   H:%M:%S");

  if (WiFiconnectedhere == 1) {
    WiFi.disconnect(true, true);  //WiFi off, erase AP
    WiFiconnectedhere = 0;
    Serial.println("WiFi has been disconnected");
  }
  timeIsSet = 1;
}

void ESP32Time::timeSetup(
    char *ssid,
    char *password,
    char *ntpServer1,
    char *ntpServer2,
    char *timezone)
{
  timeIsSet = 0;
  //connect to WiFi if not already connected
  if (! WiFi.isConnected()) {  //standard WiFi call to check if connected
    sntp_servermode_dhcp(1);    // (optional)
    Serial.printf("Connecting to %s in time module\r\n", ssid);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.printf(" CONNECTED to internet %s\r\n", ssid);
    WiFiconnectedhere = 1; // so we know to disconnect after done with it
  }
  else {
    Serial.println("WiFi is already connected");
  }

  // get a callback when time has been received locally
  sntp_set_time_sync_notification_cb( timeavailable );

  configTzTime(timezone, ntpServer1, ntpServer2);
  Serial.println("Getting localtime");
  setenv("TZ", timezone, 1);
  tzset();

}

Usage:
ESP32Time esptime;  // Instantiate the class

In arduino setup()
//initialise the time.
esptime.timeSetup(ssid, password, ntpserver1, ntpserver2, timezone);

Retrieve local time:
  struct tm timeinfo;
  time_t now;
  time(&now);
  localtime_r(&now, &timeinfo);
  time_t tt = mktime (&timeinfo);

The timezones in a program usable array (sorry it is so long):
#ifndef TZDB_H
#define TZDB_H

typedef struct {
  char tzlit[35];
  char tzzone[45];
} tTimezones;

#ifndef TZARRAY
#define TZARRAY

tTimezones tz[470] =
{
{"TZ_Africa_Abidjan ","GMT0"},
{"TZ_Africa_Accra   " , "GMT0"},
{"TZ_Africa_Addis_Ababa ","EAT-3"},
{"TZ_Africa_Algiers ","CET-1"},
{"TZ_Africa_Asmara  ","EAT-3"},
{"TZ_Africa_Bamako  ","GMT0"},
{"TZ_Africa_Bangui  ","WAT-1"},
{"TZ_Africa_Banjul  ","GMT0"},
{"TZ_Africa_Bissau  ","GMT0"},
{"TZ_Africa_Blantyre    ","CAT-2"},
{"TZ_Africa_Brazzaville ","WAT-1"},
{"TZ_Africa_Bujumbura   ","CAT-2"},
{"TZ_Africa_Cairo   ","EET-2"},
{"TZ_Africa_Casablanca  ","<+01>-1"},
{"TZ_Africa_Ceuta   ","CET-1CEST,M3.5.0,M10.5.0/3"},
{"TZ_Africa_Conakry ","GMT0"},
{"TZ_Africa_Dakar   ","GMT0"},
{"TZ_Africa_Dar_es_Salaam   ","EAT-3"},
{"TZ_Africa_Djibouti    ","EAT-3"},
{"TZ_Africa_Douala  ","WAT-1"},
{"TZ_Africa_El_Aaiun    ","<+01>-1"},
{"TZ_Africa_Freetown    ","GMT0"},
{"TZ_Africa_Gaborone    ","CAT-2"},
{"TZ_Africa_Harare  ","CAT-2"},
{"TZ_Africa_Johannesburg    ","SAST-2"},
{"TZ_Africa_Juba    ","CAT-2"},
{"TZ_Africa_Kampala ","EAT-3"},
{"TZ_Africa_Khartoum    ","CAT-2"},
{"TZ_Africa_Kigali  ","CAT-2"},
{"TZ_Africa_Kinshasa    ","WAT-1"},
{"TZ_Africa_Lagos   ","WAT-1"},
{"TZ_Africa_Libreville  ","WAT-1"},
{"TZ_Africa_Lome    ","GMT0"},
{"TZ_Africa_Luanda  ","WAT-1"},
{"TZ_Africa_Lubumbashi  ","CAT-2"},
{"TZ_Africa_Lusaka  ","CAT-2"},
{"TZ_Africa_Malabo  ","WAT-1"},
{"TZ_Africa_Maputo  ","CAT-2"},
{"TZ_Africa_Maseru  ","SAST-2"},
{"TZ_Africa_Mbabane ","SAST-2"},
{"TZ_Africa_Mogadishu   ","EAT-3"},
{"TZ_Africa_Monrovia    ","GMT0"},
{"TZ_Africa_Nairobi ","EAT-3"},
{"TZ_Africa_Ndjamena    ","WAT-1"},
{"TZ_Africa_Niamey  ","WAT-1"},
{"TZ_Africa_Nouakchott  ","GMT0"},
{"TZ_Africa_Ouagadougou ","GMT0"},
{"TZ_Africa_PortomNovo  ","WAT-1"},
{"TZ_Africa_Sao_Tome    ","GMT0"},
{"TZ_Africa_Tripoli ","EET-2"},
{"TZ_Africa_Tunis   ","CET-1"},
{"TZ_Africa_Windhoek    ","CAT-2"},
{"TZ_America_Adak   ","HST10HDT,M3.2.0,M11.1.0"},
{"TZ_America_Anchorage  ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Anguilla   ","AST4"},
{"TZ_America_Antigua    ","AST4"},
{"TZ_America_Araguaina  ","<-03>3"},
{"TZ_America_Argentina_Buenos_Aires ","<-03>3"},
{"TZ_America_Argentina_Catamarca    ","<-03>3"},
{"TZ_America_Argentina_Cordoba  ","<-03>3"},
{"TZ_America_Argentina_Jujuy    ","<-03>3"},
{"TZ_America_Argentina_La_Rioja ","<-03>3"},
{"TZ_America_Argentina_Mendoza  ","<-03>3"},
{"TZ_America_Argentina_Rio_Gallegos ","<-03>3"},
{"TZ_America_Argentina_Salta    ","<-03>3"},
{"TZ_America_Argentina_San_Juan ","<-03>3"},
{"TZ_America_Argentina_San_Luis ","<-03>3"},
{"TZ_America_Argentina_Tucuman  ","<-03>3"},
{"TZ_America_Argentina_Ushuaia  ","<-03>3"},
{"TZ_America_Aruba  ","AST4"},
{"TZ_America_Asuncion   ","<-04>4<-03>,M10.1.0/0,M3.4.0/0"},
{"TZ_America_Atikokan   ","EST5"},
{"TZ_America_Bahia  ","<-03>3"},
{"TZ_America_Bahia_Banderas ","CST6"},
{"TZ_America_Barbados   ","AST4"},
{"TZ_America_Belem  ","<-03>3"},
{"TZ_America_Belize ","CST6"},
{"TZ_America_BlancmSablon   ","AST4"},
{"TZ_America_Boa_Vista  ","<-04>4"},
{"TZ_America_Bogota ","<-05>5"},
{"TZ_America_Boise  ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Cambridge_Bay  ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Campo_Grande   ","<-04>4"},
{"TZ_America_Cancun ","EST5"},
{"TZ_America_Caracas    ","<-04>4"},
{"TZ_America_Cayenne    ","<-03>3"},
{"TZ_America_Cayman ","EST5"},
{"TZ_America_Chicago    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Chihuahua  ","CST6"},
{"TZ_America_Costa_Rica ","CST6"},
{"TZ_America_Creston    ","MST7"},
{"TZ_America_Cuiaba ","<-04>4"},
{"TZ_America_Curacao    ","AST4"},
{"TZ_America_Danmarkshavn   ","GMT0"},
{"TZ_America_Dawson ","MST7"},
{"TZ_America_Dawson_Creek   ","MST7"},
{"TZ_America_Denver ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Detroit    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Dominica   ","AST4"},
{"TZ_America_Edmonton   ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Eirunepe   ","<-05>5"},
{"TZ_America_El_Salvador    ","CST6"},
{"TZ_America_Fortaleza  ","<-03>3"},
{"TZ_America_Fort_Nelson    ","MST7"},
{"TZ_America_Glace_Bay  ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Godthab    ","<-02>2"},
{"TZ_America_Goose_Bay  ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Grand_Turk ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Grenada    ","AST4"},
{"TZ_America_Guadeloupe ","AST4"},
{"TZ_America_Guatemala  ","CST6"},
{"TZ_America_Guayaquil  ","<-05>5"},
{"TZ_America_Guyana ","<-04>4"},
{"TZ_America_Halifax    ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Havana ","CST5CDT,M3.2.0/0,M11.1.0/1"},
{"TZ_America_Hermosillo ","MST7"},
{"TZ_America_Indiana_Indianapolis   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Knox   ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Marengo    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Petersburg ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Tell_City  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Vevay  ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Vincennes  ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Indiana_Winamac    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Inuvik ","MST7MDT,M3.2.0,M11.1.0"},
{"TZ_America_Iqaluit    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Jamaica    ","EST5"},
{"TZ_America_Juneau ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Kentucky_Louisville    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Kentucky_Monticello    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Kralendijk ","AST4"},
{"TZ_America_La_Paz ","<-04>4"},
{"TZ_America_Lima   ","<-05>5"},
{"TZ_America_Los_Angeles    ","PST8PDT,M3.2.0,M11.1.0"},
{"TZ_America_Lower_Princes  ","AST4"},
{"TZ_America_Maceio ","<-03>3"},
{"TZ_America_Managua    ","CST6"},
{"TZ_America_Manaus ","<-04>4"},
{"TZ_America_Marigot    ","AST4"},
{"TZ_America_Martinique ","AST4"},
{"TZ_America_Matamoros  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Mazatlan   ","MST7"},
{"TZ_America_Menominee  ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Merida ","CST6"},
{"TZ_America_Metlakatla ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Mexico_City    ","CST6"},
{"TZ_America_Miquelon   ","<-03>3<-02>,M3.2.0,M11.1.0"},
{"TZ_America_Moncton    ","AST4ADT,M3.2.0,M11.1.0"},
{"TZ_America_Monterrey  ","CST6"},
{"TZ_America_Montevideo ","<-03>3"},
{"TZ_America_Montreal   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Montserrat ","AST4"},
{"TZ_America_Nassau ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_New_York   ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Nipigon    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Nome   ","AKST9AKDT,M3.2.0,M11.1.0"},
{"TZ_America_Noronha    ","<-02>2"},
{"TZ_America_North_Dakota_Beulah    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_North_Dakota_Center    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_North_Dakota_New_Salem ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Nuuk   ","<-02>2"},
{"TZ_America_Ojinaga    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Panama ","EST5"},
{"TZ_America_Pangnirtung    ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Paramaribo ","<-03>3"},
{"TZ_America_Phoenix    ","MST7"},
{"TZ_America_PortmaumPrince ","EST5EDT,M3.2.0,M11.1.0"},
{"TZ_America_Port_of_Spain  ","AST4"},
{"TZ_America_Porto_Velho    ","<-04>4"},
{"TZ_America_Puerto_Rico    ","AST4"},
{"TZ_America_Punta_Arenas   ","<-03>3"},
{"TZ_America_Rainy_River    ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Rankin_Inlet   ","CST6CDT,M3.2.0,M11.1.0"},
{"TZ_America_Recife ","<-03>3"},
{"TZ_America_Regina ","CST6"},
{"TZ_America_Resolute   ","CST6CDT,M3.2.0,M11.1.0"},

Continuation of timezones:
        {"TZ_America_Santarem   ","<-03>3"},
        {"TZ_America_Santiago   ","<-04>4<-03>,M9.1.6/24,M4.1.6/24"},
        {"TZ_America_Santo_Domingo  ","AST4"},
        {"TZ_America_Sao_Paulo  ","<-03>3"},
        {"TZ_America_Scoresbysund   ","<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
        {"TZ_America_Sitka  ","AKST9AKDT,M3.2.0,M11.1.0"},
        {"TZ_America_St_Barthelemy  ","AST4"},
        {"TZ_America_St_Johns   ","NST3:30NDT,M3.2.0,M11.1.0"},
        {"TZ_America_St_Kitts   ","AST4"},
        {"TZ_America_St_Lucia   ","AST4"},
        {"TZ_America_St_Thomas  ","AST4"},
        {"TZ_America_St_Vincent ","AST4"},
        {"TZ_America_Swift_Current  ","CST6"},
        {"TZ_America_Tegucigalpa    ","CST6"},
        {"TZ_America_Thule  ","AST4ADT,M3.2.0,M11.1.0"},
        {"TZ_America_Thunder_Bay    ","EST5EDT,M3.2.0,M11.1.0"},
        {"TZ_America_Tijuana    ","PST8PDT,M3.2.0,M11.1.0"},
        {"TZ_America_Toronto    ","EST5EDT,M3.2.0,M11.1.0"},
        {"TZ_America_Tortola    ","AST4"},
        {"TZ_America_Vancouver  ","PST8PDT,M3.2.0,M11.1.0"},
        {"TZ_America_Whitehorse ","MST7"},
        {"TZ_America_Winnipeg   ","CST6CDT,M3.2.0,M11.1.0"},
        {"TZ_America_Yakutat    ","AKST9AKDT,M3.2.0,M11.1.0"},
        {"TZ_America_Yellowknife    ","MST7MDT,M3.2.0,M11.1.0"},
        {"TZ_Antarctica_Casey   ","<+11>-11"},
        {"TZ_Antarctica_Davis   ","<+07>-7"},
        {"TZ_Antarctica_DumontDUrville  ","<+10>-10"},
        {"TZ_Antarctica_Macquarie   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Antarctica_Mawson  ","<+05>-5"},
        {"TZ_Antarctica_McMurdo ","NZST-12NZDT,M9.5.0,M4.1.0/3"},
        {"TZ_Antarctica_Palmer  ","<-03>3"},
        {"TZ_Antarctica_Rothera ","<-03>3"},
        {"TZ_Antarctica_Syowa   ","<+03>-3"},
        {"TZ_Antarctica_Troll   ","<+00>0<+02>-2,M3.5.0/1,M10.5.0/3"},
        {"TZ_Antarctica_Vostok  ","<+06>-6"},
        {"TZ_Arctic_Longyearbyen    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Asia_Aden  ","<+03>-3"},
        {"TZ_Asia_Almaty    ","<+06>-6"},
        {"TZ_Asia_Amman ","<+03>-3"},
        {"TZ_Asia_Anadyr    ","<+12>-12"},
        {"TZ_Asia_Aqtau ","<+05>-5"},
        {"TZ_Asia_Aqtobe    ","<+05>-5"},
        {"TZ_Asia_Ashgabat  ","<+05>-5"},
        {"TZ_Asia_Atyrau    ","<+05>-5"},
        {"TZ_Asia_Baghdad   ","<+03>-3"},
        {"TZ_Asia_Bahrain   ","<+03>-3"},
        {"TZ_Asia_Baku  ","<+04>-4"},
        {"TZ_Asia_Bangkok   ","<+07>-7"},
        {"TZ_Asia_Barnaul   ","<+07>-7"},
        {"TZ_Asia_Beirut    ","EET-2EEST,M3.5.0/0,M10.5.0/0"},
        {"TZ_Asia_Bishkek   ","<+06>-6"},
        {"TZ_Asia_Brunei    ","<+08>-8"},
        {"TZ_Asia_Chita ","<+09>-9"},
        {"TZ_Asia_Choibalsan    ","<+08>-8"},
        {"TZ_Asia_Colombo   ","<+0530>-5:30"},
        {"TZ_Asia_Damascus  ","<+03>-3"},
        {"TZ_Asia_Dhaka ","<+06>-6"},
        {"TZ_Asia_Dili  ","<+09>-9"},
        {"TZ_Asia_Dubai ","<+04>-4"},
        {"TZ_Asia_Dushanbe  ","<+05>-5"},
        {"TZ_Asia_Famagusta ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Asia_Gaza  ","EET-2EEST,M3.4.4/50,M10.4.4/50"},
        {"TZ_Asia_Hebron    ","EET-2EEST,M3.4.4/50,M10.4.4/50"},
        {"TZ_Asia_Ho_Chi_Minh   ","<+07>-7"},
        {"TZ_Asia_Hong_Kong ","HKT-8"},
        {"TZ_Asia_Hovd  ","<+07>-7"},
        {"TZ_Asia_Irkutsk   ","<+08>-8"},
        {"TZ_Asia_Jakarta   ","WIB-7"},
        {"TZ_Asia_Jayapura  ","WIT-9"},
        {"TZ_Asia_Jerusalem ","IST-2IDT,M3.4.4/26,M10.5.0"},
        {"TZ_Asia_Kabul ","<+0430>-4:30"},
        {"TZ_Asia_Kamchatka ","<+12>-12"},
        {"TZ_Asia_Karachi   ","PKT-5"},
        {"TZ_Asia_Kathmandu ","<+0545>-5:45"},
        {"TZ_Asia_Khandyga  ","<+09>-9"},
        {"TZ_Asia_Kolkata   ","IST-5:30"},
        {"TZ_Asia_Krasnoyarsk   ","<+07>-7"},
        {"TZ_Asia_Kuala_Lumpur  ","<+08>-8"},
        {"TZ_Asia_Kuching   ","<+08>-8"},
        {"TZ_Asia_Kuwait    ","<+03>-3"},
        {"TZ_Asia_Macau ","CST-8"},
        {"TZ_Asia_Magadan   ","<+11>-11"},
        {"TZ_Asia_Makassar  ","WITA-8"},
        {"TZ_Asia_Manila    ","PST-8"},
        {"TZ_Asia_Muscat    ","<+04>-4"},
        {"TZ_Asia_Nicosia   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Asia_Novokuznetsk  ","<+07>-7"},
        {"TZ_Asia_Novosibirsk   ","<+07>-7"},
        {"TZ_Asia_Omsk  ","<+06>-6"},
        {"TZ_Asia_Oral  ","<+05>-5"},
        {"TZ_Asia_Phnom_Penh    ","<+07>-7"},
        {"TZ_Asia_Pontianak ","WIB-7"},
        {"TZ_Asia_Pyongyang ","KST-9"},
        {"TZ_Asia_Qatar ","<+03>-3"},
        {"TZ_Asia_Qyzylorda ","<+05>-5"},
        {"TZ_Asia_Riyadh    ","<+03>-3"},
        {"TZ_Asia_Sakhalin  ","<+11>-11"},
        {"TZ_Asia_Samarkand ","<+05>-5"},
        {"TZ_Asia_Seoul ","KST-9"},
        {"TZ_Asia_Shanghai  ","CST-8"},
        {"TZ_Asia_Singapore ","<+08>-8"},
        {"TZ_Asia_Srednekolymsk ","<+11>-11"},
        {"TZ_Asia_Taipei    ","CST-8"},
        {"TZ_Asia_Tashkent  ","<+05>-5"},
        {"TZ_Asia_Tbilisi   ","<+04>-4"},
        {"TZ_Asia_Tehran    ","<+0330>-3:30"},
        {"TZ_Asia_Thimphu   ","<+06>-6"},
        {"TZ_Asia_Tokyo ","JST-9"},
        {"TZ_Asia_Tomsk ","<+07>-7"},
        {"TZ_Asia_Ulaanbaatar   ","<+08>-8"},
        {"TZ_Asia_Urumqi    ","<+06>-6"},
        {"TZ_Asia_UstmNera  ","<+10>-10"},
        {"TZ_Asia_Vientiane ","<+07>-7"},
        {"TZ_Asia_Vladivostok   ","<+10>-10"},
        {"TZ_Asia_Yakutsk   ","<+09>-9"},
        {"TZ_Asia_Yangon    ","<+0630>-6:30"},
        {"TZ_Asia_Yekaterinburg ","<+05>-5"},
        {"TZ_Asia_Yerevan   ","<+04>-4"},
        {"TZ_Atlantic_Azores    ","<-01>1<+00>,M3.5.0/0,M10.5.0/1"},
        {"TZ_Atlantic_Bermuda   ","AST4ADT,M3.2.0,M11.1.0"},
        {"TZ_Atlantic_Canary    ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Cape_Verde    ","<-01>1"},
        {"TZ_Atlantic_Faroe ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Madeira   ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Atlantic_Reykjavik ","GMT0"},
        {"TZ_Atlantic_South_Georgia ","<-02>2"},
        {"TZ_Atlantic_Stanley   ","<-03>3"},
        {"TZ_Atlantic_St_Helena ","GMT0"},
        {"TZ_Australia_Adelaide ","ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Brisbane ","AEST-10"},
        {"TZ_Australia_Broken_Hill  ","ACST-9:30ACDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Currie   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Darwin   ","ACST-9:30"},
        {"TZ_Australia_Eucla    ","<+0845>-8:45"},
        {"TZ_Australia_Hobart   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Lindeman ","AEST-10"},
        {"TZ_Australia_Lord_Howe    ","<+1030>-10:30<+11>-11,M10.1.0,M4.1.0"},
        {"TZ_Australia_Melbourne    ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Australia_Perth    ","AWST-8"},
        {"TZ_Australia_Sydney   ","AEST-10AEDT,M10.1.0,M4.1.0/3"},
        {"TZ_Europe_Amsterdam   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Andorra ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Astrakhan   ","<+04>-4"},
        {"TZ_Europe_Athens  ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Belgrade    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Berlin  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Bratislava  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Brussels    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Bucharest   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Budapest    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Busingen    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Chisinau    ","EET-2EEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Copenhagen  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Dublin  ","IST-1GMT0,M10.5.0,M3.5.0/1"},
        {"TZ_Europe_Gibraltar   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Guernsey    ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Helsinki    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Isle_of_Man ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Istanbul    ","<+03>-3"},
        {"TZ_Europe_Jersey  ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Kaliningrad ","EET-2"},
        {"TZ_Europe_Kiev    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Kirov   ","<+03>-3"},
        {"TZ_Europe_Lisbon  ","WET0WEST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Ljubljana   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_London  ","GMT0BST,M3.5.0/1,M10.5.0"},
        {"TZ_Europe_Luxembourg  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Madrid  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Malta   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Mariehamn   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Minsk   ","<+03>-3"},
        {"TZ_Europe_Monaco  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Moscow  ","MSK-3"},
        {"TZ_Europe_Oslo    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Paris   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Podgorica   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Prague  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Riga    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Rome    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Samara  ","<+04>-4"},
        {"TZ_Europe_San_Marino  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Sarajevo    ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Saratov ","<+04>-4"},
        {"TZ_Europe_Simferopol  ","MSK-3"},
        {"TZ_Europe_Skopje  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Sofia   ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Stockholm   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Tallinn ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Tirane  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Ulyanovsk   ","<+04>-4"},
        {"TZ_Europe_Uzhgorod    ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Vaduz   ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vatican ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vienna  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Vilnius ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Volgograd   ","<+03>-3"},
        {"TZ_Europe_Warsaw  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Zagreb  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Europe_Zaporozhye  ","EET-2EEST,M3.5.0/3,M10.5.0/4"},
        {"TZ_Europe_Zurich  ","CET-1CEST,M3.5.0,M10.5.0/3"},
        {"TZ_Indian_Antananarivo    ","EAT-3"},
        {"TZ_Indian_Chagos  ","<+06>-6"},
        {"TZ_Indian_Christmas   ","<+07>-7"},
        {"TZ_Indian_Cocos   ","<+0630>-6:30"},
        {"TZ_Indian_Comoro  ","EAT-3"},
        {"TZ_Indian_Kerguelen   ","<+05>-5"},
        {"TZ_Indian_Mahe    ","<+04>-4"},
        {"TZ_Indian_Maldives    ","<+05>-5"},
        {"TZ_Indian_Mauritius   ","<+04>-4"},
        {"TZ_Indian_Mayotte ","EAT-3"},
        {"TZ_Indian_Reunion ","<+04>-4"},
        {"TZ_Pacific_Apia   ","<+13>-13"},
        {"TZ_Pacific_Auckland   ","NZST-12NZDT,M9.5.0,M4.1.0/3"},
        {"TZ_Pacific_Bougainville   ","<+11>-11"},
        {"TZ_Pacific_Chatham    ","<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45"},
        {"TZ_Pacific_Chuuk  ","<+10>-10"},
        {"TZ_Pacific_Easter ","<-06>6<-05>,M9.1.6/22,M4.1.6/22"},
        {"TZ_Pacific_Efate  ","<+11>-11"},
        {"TZ_Pacific_Enderbury  ","<+13>-13"},
        {"TZ_Pacific_Fakaofo    ","<+13>-13"},
        {"TZ_Pacific_Fiji   ","<+12>-12"},
        {"TZ_Pacific_Funafuti   ","<+12>-12"},
        {"TZ_Pacific_Galapagos  ","<-06>6"},
        {"TZ_Pacific_Gambier    ","<-09>9"},
        {"TZ_Pacific_Guadalcanal    ","<+11>-11"},
        {"TZ_Pacific_Guam   ","ChST-10"},
        {"TZ_Pacific_Honolulu   ","HST10"},
        {"TZ_Pacific_Kiritimati ","<+14>-14"},
        {"TZ_Pacific_Kosrae ","<+11>-11"},
        {"TZ_Pacific_Kwajalein  ","<+12>-12"},
        {"TZ_Pacific_Majuro ","<+12>-12"},
        {"TZ_Pacific_Marquesas  ","<-0930>9:30"},
        {"TZ_Pacific_Midway ","SST11"},
        {"TZ_Pacific_Nauru  ","<+12>-12"},
        {"TZ_Pacific_Niue   ","<-11>11"},
        {"TZ_Pacific_Norfolk    ","<+11>-11<+12>,M10.1.0,M4.1.0/3"},
        {"TZ_Pacific_Noumea ","<+11>-11"},
        {"TZ_Pacific_Pago_Pago  ","SST11"},
        {"TZ_Pacific_Palau  ","<+09>-9"},
        {"TZ_Pacific_Pitcairn   ","<-08>8"},
        {"TZ_Pacific_Pohnpei    ","<+11>-11"},
        {"TZ_Pacific_Port_Moresby   ","<+10>-10"},
        {"TZ_Pacific_Rarotonga  ","<-10>10"},
        {"TZ_Pacific_Saipan ","ChST-10"},
        {"TZ_Pacific_Tahiti ","<-10>10"},
        {"TZ_Pacific_Tarawa ","<+12>-12"},
        {"TZ_Pacific_Tongatapu  ","<+13>-13"},
        {"TZ_Pacific_Wake   ","<+12>-12"},
        {"TZ_Pacific_Wallis ","<+12>-12"},
        {"TZ_Etc_GMT    ","GMT0"},
        {"TZ_Etc_GMTm0  ","GMT0"},
        {"TZ_Etc_GMTm1  ","<+01>-1"},
        {"TZ_Etc_GMTm2  ","<+02>-2"},
        {"TZ_Etc_GMTm3  ","<+03>-3"},
        {"TZ_Etc_GMTm4  ","<+04>-4"},
        {"TZ_Etc_GMTm5  ","<+05>-5"},
        {"TZ_Etc_GMTm6  ","<+06>-6"},
        {"TZ_Etc_GMTm7  ","<+07>-7"},
        {"TZ_Etc_GMTm8  ","<+08>-8"},
        {"TZ_Etc_GMTm9  ","<+09>-9"},
        {"TZ_Etc_GMTm10 ","<+10>-10"},
        {"TZ_Etc_GMTm11 ","<+11>-11"},
        {"TZ_Etc_GMTm12 ","<+12>-12"},
        {"TZ_Etc_GMTm13 ","<+13>-13"},
        {"TZ_Etc_GMTm14 ","<+14>-14"},
        {"TZ_Etc_GMT0   ","GMT0"},
        {"TZ_Etc_GMTp0  ","GMT0"},
        {"TZ_Etc_GMTp1  ","<-01>1"},
        {"TZ_Etc_GMTp2  ","<-02>2"},
        {"TZ_Etc_GMTp3  ","<-03>3"},
        {"TZ_Etc_GMTp4  ","<-04>4"},
        {"TZ_Etc_GMTp5  ","<-05>5"},
        {"TZ_Etc_GMTp6  ","<-06>6"},
        {"TZ_Etc_GMTp7  ","<-07>7"},
        {"TZ_Etc_GMTp8  ","<-08>8"},
        {"TZ_Etc_GMTp9  ","<-09>9"},
        {"TZ_Etc_GMTp10 ","<-10>10"},
        {"TZ_Etc_GMTp11 ","<-11>11"},
        {"TZ_Etc_GMTp12 ","<-12>12"},
        {"TZ_Etc_UCT    ","UTC0"},
        {"TZ_Etc_UTC    ","UTC0"},
        {"TZ_Etc_Greenwich  ","GMT0"},
        {"TZ_Etc_Universal  ","UTC0"},
        {"TZ_Etc_Zulu   ","UTC0"},
        {"EOF", "eof"}
        };

        char *getTimeZoneLit(int tzindex) {
          return(tz[tzindex].tzlit);
        }
        char *getTimeZone(int tzindex) {
          return(tz[tzindex].tzzone);
        }

        #endif // TZDB_H
        #endif

Why the markdown. This database is the authoritative database. Please note that the array starts in the previous post. I don't know how to add it as a downloadable file and had to split it to fit the post size limitations.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
How do I wake the ESP8266 from deep sleep on a specific date and time?
I'd like to put my ESP8266 into deep sleep and then wake it up at at specific date and time, [roughly] to the second.
Edit: Unfortunately, ESP8266 deep sleep doesn't support values greater than about 3.5 hours. I tried sleeping for an hour at a time until the desired time is reached, but found that it's not very accurate; often dozens seconds of drift on each wake, adding up to many minutes of drift after several hours.
Edit: I want to wake every 24 hours at a specific time. A few seconds per week drift is more than acceptable, as I'll be re-syncing the clock every 24 hours or so.
Edit: I'm using WAKE_RF_DISABLED to disable WiFi to save power on wake, so when it wakes up, there is usually no internet connection to check the time (I want to connect to WiFi only once every 24h).

Over what period of time do you expect one-second accuracy? This is important.

Every 24 hours at a specific time, but I'd like a solution that I can use flexibly, so perhaps wake every few days.

You need 1ppm or better if you want 1 second accuracy over a period on 1 week. That's not going to be easy or cheap. For a cheap RTC the accuracy will be limited by the crystal itself, not by the chip that counts the clock cycles.

Are you sure? "The [DS3231 at ±3.5ppm] maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C" (Source: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf)

Two minutes per year is 120 seconds over 52 weeks...worse than 2 seconds per week drift. I'm pretty sure.

Well, according to Maxim, that is still "extremely accurate" and I'm inclined to agree. I'm not designing a GPS satellite.

As you wish, but you changed the requirements. You said "wake every few days" and "on a specific...date" then you later said that you will be "re-syncing the clock every 24 hours or so". Whatever works for you. Peace.

Yes, I realised that I was being too demanding; I appreciate that to the second over a year would be impossible with the DS3231, and I definitely don't need that level of accuracy. I'm more than happy with 2 seconds of drift per week. Peace.

Since the ESP8266 doesn't have a real onboard RTC (i.e. it's not capable of keeping very accurate time while in deep sleep) and is limited to a short time period, one solution is to use an external RTC (real time clock) but there is a way of doing it without.
Below are 3 approaches, the first two involve a DS3231 RTC (quite easy to get as a module). For low power, I prefer DS3231 over DS1307, since DS3231 modules seem to work fine at 2.6V (whereas DS1307 modules seem to require at least 3.3V... or more like 4.5V according to the datasheet). The 3rd approach is useful if you don't want to add an external RTC.

"The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC)".
The DS3231 "maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C"

Solution 1: Periodically wake the MCU and check the external RTC
Probably, the most energy efficient solution (compared to using the alarm solution below) would be to wake the ESP8266 from deep sleep periodically to check the time on the external RTC and depending on desired accuracy, deep sleep for shorter periods as you approach the target wake time (e.g. wake and check the RTC every minute once you're about 10 mins away from the target time).
To save power, before sleeping the ESP8266, you can simply use a transistor connected to GPIO to turn off the Vcc power supply on the DS3231 module (it'll use the onboard 2032 battery while no power is supplied). Don't forget to turn off the I2C pull-ups too, as they can provide parasite power to the RTC. You can also just disconnect GND.
If restarted with WiFi off (ESP.deepSleep(1e6, WAKE_RF_DISABLED)), the ESP8266 only needs to wake for about 200 ms consuming 20 mA to check the DS3231 if it's time to wake up fully. This is probably the most energy efficient you can get with wanting to keep accurate time.
Solution 2: Set an alarm on the external RTC to wake the MCU
Using the DS3231, the SQW pin can be connected to the ESP8266 RST pin via a monostable circuit. The monostable circuit is important because the RST pin can't stay low, as it won't boot. The monostable circuit creates a pulse on the RST pin when the DS3231 SQW pin goes low.
A note on power consumption: The ESP8266 should consume only 20 µA in deep sleep, but DS3231 modules actually tend to use about 1 mA when powered on (which is required to trigger the alarm), probably because of the EEPROM on the module. That power consumption is significant if you're designing a low power system. This is why this 2nd solution is less energy efficient compared to the 1st solution.
The following code will set an alarm to a specific time, and when the RST pin is pulled low (based on the SQW output of the DS3231), the ESP8266 then wakes up. Make sure you uncomment SLEEP_DT and set a date and time to wake at a specific date and time (of course, you can set this programmatically to any date and time), otherwise it'll wake up every n seconds (value of SLEEP_SECONDS) but that might also be useful (ESP8266 deep sleep time isn't very accurate).
#include <ESP8266WiFi.h>

// TODO: NTPClient is redundant; replace with native
// ESP8266 NTP functions (configTime and localtime)
#include <NTPClient.h>
#include <WiFiUdp.h>

#include <RTClib.h>

#define WIFI_SSID "Your WiFi SSID"
#define WIFI_PASS "Your WiFi password"

// uncomment to wake up at specific date and time
//#define SLEEP_DT
#define SLEEP_DT_YEAR 2022
#define SLEEP_DT_MONTH 12
#define SLEEP_DT_DAY 02
#define SLEEP_DT_HOUR 15
#define SLEEP_DT_MINUTE 50
#define SLEEP_DT_SECOND 25

#define SLEEP_SECONDS 10 // easier for testing

RTC_DS3231 rtc;
WiFiUDP udp;
NTPClient ntp(udp);

void print_date(const DateTime& dt);

void setup() {
  Serial.begin(9600);
  while (!Serial) { delay(1); }

  Serial.println('\n');
  Serial.println("Hello RTC wake deep sleep");

  Serial.println("Init DS3231");
  if(!rtc.begin()) {
    Serial.println("DS3231 failed");
    while (true) { delay(1); }
  }

  // not needed
  rtc.disable32K();

  // not used
  rtc.disableAlarm(2);

  // apparently can lead to problems if not cleared
  rtc.clearAlarm(1);
  rtc.clearAlarm(2);

  // stop oscillating; allows alarm to work
  rtc.writeSqwPinMode(DS3231_OFF);

  Serial.println("Init WiFi");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  Serial.println("Connecting to " WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.print("Connected, IP: ");
  Serial.println(WiFi.localIP());

  ntp.begin();
  bool ntpOk = ntp.update();

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting time");
    if (ntpOk) {
      Serial.println("Using time from NTP client");
      rtc.adjust(DateTime(ntp.getEpochTime()));
    }
    else {
      // untested code
      Serial.println("NTP unavailable, using time of build");
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }
  }

  Serial.print("Date and time set to: ");
  print_datetime(rtc.now());

#ifdef SLEEP_DT

  DateTime alarm(
    SLEEP_DT_YEAR,
    SLEEP_DT_MONTH,
    SLEEP_DT_DAY,
    SLEEP_DT_HOUR,
    SLEEP_DT_MINUTE,
    SLEEP_DT_SECOND);

  Serial.print("Setting alarm for date: ");
  print_datetime(alarm);

  if (!rtc.setAlarm1(alarm, DS3231_A1_Date)) {
    Serial.println("Failed to set alarm");
  }

#else

  // sleep for set seconds for the purposes of testing
  Serial.print("Setting alarm for seconds: ");
  Serial.print(SLEEP_SECONDS);
  Serial.println(" seconds");
  if (!rtc.setAlarm1(rtc.now() + TimeSpan(SLEEP_SECONDS), DS3231_A1_Second)) {
    Serial.println("Failed to set alarm");
  }

#endif // SLEEP_DT

  Serial.println("Going into deep sleep (wake on RST low)");
  Serial.flush();
  ESP.deepSleep(0);
}

void print_datetime(const DateTime& dt) {
  char df[] = "YYYY-MM-DD hh:mm:ss";
  Serial.println(dt.toString(df));
}

void loop() { }

Here it is in action...

Note: The time jumps because I chopped out a few frames to save you from being bored (no smoke and mirrors, I promise).
Solution 3: Use only the internal RTC
Keeping with the low power theme: to use the internal RTC in deep sleep, you have to keep sleeping for n seconds until desired seconds elapse. You can keep track of how many seconds have elapsed by using the RTC memory. This approach allows you to implement time keeping without having to add an external RTC, and without having to reconnect connect to WiFi every hour. However, I have found the drift to be quite substantial (many seconds per hour), so this is probably useful only when accuracy is not a major concern.

the ESP8266 has an onboard RTC capable of keeping time while in deep sleep

"Despite being named RTC, the RTC is not really a Real Time Clock in the normal sense of the word. While it does keep a counter ticking while the module is sleeping, the accuracy with which it does so is highly dependent on the temperature of the chip.": https://nodemcu.readthedocs.io/en/dev/modules/rtctime/

"number of microseconds to sleep for. Maxmium value is 4294967295us, or ~71 minutes.": https://nodemcu.readthedocs.io/en/dev/modules/rtctime/#rtctimedsleep

@Juraj Updated answer, thanks.

You are fooling yourself if you think your cheap RTC module is accurate to 1 second over a period of more than a few hours. You need to carefully calibrate the RTC and maintain it at a constant temperature if you want better accuracy.

I'm not sure I can agree with you. Maxim is a pretty reputable company. Unless the datasheet is lying... "The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC)" https://datasheets.maximintegrated.com/en/ds/DS3231.pdf

Also... "maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C"

@ElliotAlderson FYI, I have flagged your comment as unfriendly (which is against the code of conduct). I suggest you re-think how you communicate with others. https://arduino.stackexchange.com/conduct#unfriendly-language

I will try to be more diplomatic. Your proposed solution will not be able to provide an accuracy of 1 second over a period of more than a few days, as stated in the Maxim documentation. The words "extremely accurate" mean different things to different people.

Thanks. I'm happy (and most people probably would be happy) with the accuracy improvement that the DS3231 offers over the ESP8266 deep sleep RTC (which seems to drift by several seconds over an hour). If you're sleeping repeatedly to get to 24h, then that drift is quite bad... many minutes. The DS3231 is certainly a significant improvement on that, don't you think?

the RTC is updated from NTP if connection to Internet is available

Yep, if there is an internet connection; not if you're turning WiFi off to save power.

I noticed that with ESP8266, when waking after deep sleep, the NTP time (using configTime and localtime) is reset to default; 1970. With an external RTC, of course this isn't a problem.

@Juraj I was thinking about what you said... did you mean that if configTime is used on ESP8266, then NTPClient is redundant?

of course it is redundant

Thanks for confirming, I wonder why the most popular tutorials for "esp8266 time" point to NTPClient; the top 3 results all do, and only until you get to the 4th is configTime mentioned.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Why is the GSM shield so expensive?
I've been doing some Googling for GSM shields and their prices and frankly I don't understand why they are so expensive on average.
The official one sold by Arduino is 71 euros for me (I live in Europe), and third party ones have similar prices.
A cheap dumb-phone is usually 30 euros and those phones have become really impressive these days, they have even a camera. When they are locked with the carrier the price can go as low as 20 euros. How is it even possible that a single part of what is supposed to make up a phone is more expensive than the phone itself? :(
Thanks in advance!

Economies of scale?

Both my dumb-phone and Arduino's GSM shield are sold on a global scale. And I don't think my dumb-phone sells more than the shield, it's a quite crappy brand.

@AlbertoLaRocca no, the GSM shield is sold on a global scope, the scale (number of units sold) is miniscule compared to phones.

@SmartHead You should also read the help center yourself, because edits are not for flagging something as off-topic.

@Michel Keijzers you approved an utterly improper title edit to this question.  NEVER DO THAT AGAIN.

@Hasan you approved an utterly improper title edit to this question. NEVER DO THAT AGAIN.

If you are ready to wait a month for delivery and also giving up flexibility by restricting yourself to just sending and receiving SMS, then you can go as low as €2 for a DIY kit on AliExpress.
By adding more money, you also get more features. Just sarch for "gsm arduino" or "SIM800", "SIM900".

Sorry but that doesn't answer at all. All right, I can go as low as 2 euros, and why such a crazy difference? Just because I can't make voice calls? My 30 euro dumb-phone actually CAN make voice calls.

Some of these probably can make voice calls on a suitable network, and some probably won't work on the current network in your country at all.  A big part of the cost difference is not having a local distributor standing behind their suitability.

I thougt you was just complaining about the price. Well the reason is simple. Those devices are produced in small batches. Non of those suitable for use with arduino are used in actual phones. Phones have SoCs so the modem is integrated into the CPU. Just take a look at a Qualcomm Snapdragon. Those have built in LTE modems. Also iPhone CPUs have integrated modems. So you would have to pay a lot more if a manufacturer used those for Arduino Shields. Also you would get more than you asked for. Like a CPU, GPU and system memory.

However Flash storage is external. so those would be even more expensive if you want run them with pre configured firmware/software/operating system or such. The development of those will likely also take a bunch of money. Not to mention licensing fees.

@Kwasmich - it may be that some of the modules are simply low-end feature phone SoCs with a serial port brought out.  Or at least, that seems like it could be the most economical way to make a module.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Can't reprogram Arduino on protoboard (perfboard), but could program the same circuit on breadboard
So I have a circuit that works well when it's on a breadboard and without removing any pins I'm able to upload sketches, but for some reason when I transition it to a protoboard I can no longer upload sketches.
My circuit consists of an MPU6050, an Arduino Pro Mini, and a HC-08 BLE module. I've tried protoboarding this circuit twice with Arduino Pro Minis and once with an Arduino Nano, and now I'm not able to upload sketches to any of these three circuits.
I'm using perfboard (not stripboard, so yes I have already connected the jumper wires to the header pins) and know that the circuit partially works since the IMU, Arduino, and BLE LEDs all light and you can connect to the BLE on a mobile terminal app.
The error I get is:
avrdude: stk500_getsync(): not in sync: resp=0x00,

I use SoftwareSerial.h so NO pins are connected to the Arduinos 0 and 1 pins.
I've already tried restarting the IDE
I've tried disconnecting/reconnecting the USB cable
There's only one COM# port so I'm sure I'm using the right one.

I'm so stumped because this error message did not occur when I was playing with the same circuit on a breadboard...
Any ideas on how I can fix this or what I'm doing wrong?

something is probably pulling the power down .... disconnect the arduino from the circuit and try loading

Did you remember to include all the bypass capacitors?

.. I'm using an arduino Pro Mini, and didn't use any bypass capacitors in my breadboarded circuit, can you clarify?

Maybe post a sketch of your circuit?

https://arduino.stackexchange.com/questions/8847/getting-avrdudestk500-recv-programmer-is-not-responding-while-uploading-sk

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Arduino Rotary Encoder Pulses?
I made an program so if I turn on my rotary encoder the position and the rotation comes on a LCD screen. But I need to change it a bit up for my teacher, she wants to see the graph of the pulses on the serial monitor. I searched it up and can't find a solution? Any help?
My program:
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#define outputA 2
#define outputB 4
int counter = 0;
int angle = 0;
int aState;
int aLastState;
int lastAngle = 0;
String rotationDirection;
String savedRotationDirection;

void setup() {
  pinMode (outputA,INPUT);
  pinMode (outputB,INPUT);

  aLastState = digitalRead(outputA);
  lcd.begin();

     }

void loop() {
  aState = digitalRead(outputA);
  if (aState != aLastState){
     if (digitalRead(outputB) != aState) {
       counter ++;
       angle ++;
     }
     else {
       counter--;
       angle --;
     }
     if (counter >=30 ) {
      counter = 0;
     }

     if (angle < lastAngle){
      rotationDirection = "CCW";
     }
     else {
      if (angle > lastAngle){
        rotationDirection = "CW";
      }
      else {
        rotationDirection = savedRotationDirection;
      }
     }
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Position: ");
     lcd.print(int(angle)*(-1));
     lcd.print((char)223);
     lcd.setCursor(0,1);
     lcd.print("Rotation: ");
     lcd.print(rotationDirection);
     savedRotationDirection = rotationDirection;
     lastAngle = angle;
  }
  aLastState = aState;

}

My program:  is hard to read formatted like that

almost every Arduino example uses prints to Serial Monitor

I searched it up ... what did you search for?

Just a few comments on your code: 1. You can remove counter, as you never use it. 2. aState and rotationDirection should be local variables. 3. savedRotationDirection serves no useful purpose: you can just remove every line in which it appears. 4. lastAngle is not useful either: you know the angle increases when you do angle++, and it decreases when you do angle--.

Add Serial.begin(115200); in setup() and use Serial.println() or Serial.print() to print to Serial.
In Arduino IDE open Serial Monitor and set baud rate to 115200.
EDIT: The question turned out to be about Serial Plotter. Maximilian Gerhardt answered in a comment :

If you want multiple data streams (graphs) you need to seperate them
  by a comma: Serial.println( String(digitalRead(outputA)) + "," +
  String(digitalRead(outputB)));

Nothing's happening. My question is how to see the graph of the pulse in the serial monitor?

Serial Plotter in IDE?

Used it but still nothing happens.

Used this:
Serial.println(digitalRead(outputA));
Serial.println(digitalRead(outputB));
Now I only get one of the 2. Is there a way to get both but under eachother?

If you want multiple data streams (graphs) you need to seperate them by a comma: Serial.println( String(digitalRead(outputA)) + "," + String(digitalRead(outputB))); (https://www.norwegiancreations.com/2016/01/tutorial-multiple-values-in-the-arduino-ide-serial-plotter/) @user43154

Yes, that worked thanks. Further information I'll search first by myself. Thanks!


text:
Suddently, "avrdude: Device signature = 0x000000" with ArduinoISP. Is my chip dead?
I have some boards with the atmega32u4 that they were working perfectly before. I'm using an unnoficial UNO board to program them via ICSP. To power the uC I'm using two lithium batteries and a step-down converter to drop it to 5 V.
This started happening when I tried to upload code via ISCP when the target chip was not powered by mistake.
This is my error message:
Arduino: 1.8.5 (Windows 10), Placa:"Arduino Leonardo"

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

     Using Port                    : COM4
     Using Programmer              : stk500v1
     Overriding Baud Rate          : 19200
     AVR Part                      : ATmega32U4
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PA0
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
       lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : STK500
     Description     : Atmel STK500 Version 1.x firmware
     Hardware Version: 2
     Firmware Version: 1.18
     Topcard         : Unknown
     Vtarget         : 0.0 V
     Varef           : 0.0 V
     Oscillator      : Off
     SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

What I've already tried:

Different programmer (another Uno board);
Uploading to a proper Leonardo board via ICSP, it worked;
Uploading to another of my boards via ICSP, it worked;
Running with the portable Arduino version;
Check if the chip is being powered with 5 V;
Changed wires and checked the connections;
The chip does not get hot;

I've been around this two days straight, any help would be much appreciated.

Have a look at this question and answer: Have I bricked my Arduino Uno? Problems with uploading to board

Mostly this error is due to connections/powering issues (as already mentioned in your output ).

Check connections, especially power and ground also check the
resistance between Vcc and GND of your target MCU. (If it's less than
100ohm that means something is off in your circuitry or your MCU is
already fried.)
Check if your MCU is actually getting enough power (voltage and current) also check if it's getting excess voltage.
Make sure there is proper "common grounding" done between devices.
If you are sure that the above points are checked and you still get the error try the override flag -F (avrdude through shell/command-line) and if you are still not able to upload try the manually changing the address (not recommended ) in your arduino's library so that it matches with the signature it's receiving.
Finally try using a direct USB interface with atmega32u4 as atmega32u4 supports it and upload the bootloader again through an old software called Flip after that try again.

After all this if you are not able to upload then probably your MCU is dead and it might be due to an unnoticed wrong power connection or short circuit or unintentional fuse reconfiguration (highly unlikely).


text:
Arduino Uno USB 5 V and external power supply 12 V overheating
I have a issue with my Arduino Uno r3.
I'm not sure why is that happening but I have a 5 V, 18 A power supply to power my LEDs. I connected 5 V from the Arduino to 5 V from the external power supply and I plugged this combined cable to my LEDs. I did the same with GND. On data pin 6 I used a 220 Ω resistor. Also I am using a 12 V power supply to power my Arduino.
At the same time the USB was plugged in.
In and between USB and power some chip is getting hot. I got scared and unplugged the whole Arduino. I am not sure how I should plug this in. It worked fine until I plugged in the external power supply and I was using few LEDs at the time.
This is what it looked like in more understandable way.

Please point out to me what I did wrong.

If you a separate 5V 18A power supply for supplying to the LED, then there is no need for the 12V power supply as you already connect the power supply to the 5V pin of the Arduino board as per your drawing.

Rule #1: A Power Supply the Arduino is NOT!

I suggest you do not use the 12V external power when you are already supplying it with an externally regulated 5V source.
The sole purpose of the 12V input is to provide a 5V regulated supply voltage for the microcontroller. The PCB outputs this on the 5V header. The problem is that you are feeding your external 5V into that pin.
You can either continue powering the Arduino from the 12V supply and disconnect the external 5V from the Arduino (keep the GND from the external 5V conected). Or you can just remove the 12V power source.
It could end up that you have damaged the chip that overheated. If the Arduino still works after doing one of the solutions above, then you may be lucky and not damaged anything.
As a precaution, please measure your external 5V source with a multimeter to make sure it is within specs that Arduino allows.

yes, as the other people say. I'm an electronician , your power supply 5V 18 Amperes , it's to dangerous to connect that to your arduino, the board is not creating to support a great power, if someone of your outputs receives all this unlimited power P = U × I = 5 × 18 = 90 Watts,  your board is just able to smell a awful odour. yes, your board burnst with thi great possible intensity. 1. Connect all the several ground together and for supply the arduino take on the USB header
.
2. connect your power supply directly on the leds board.
warning test that,  but it is possible that your board working not more, see all the led of your board and detect step by step if it works normally...


text:
Why doesn't serial communication work on Arduino Uno r3 and ESP8266 WiFi module?
I have a simple problem here. I use an ESP8266 WiFi module and an Arduino Uno r3.
What I want is to receive a serial message from the ESP8266 on the Arduino Uno.
Note: I set the upload speed of the ESP8266 to 9600.
void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.write("hello friend");
  delay(2000);
}

Arduino Uno:
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); //rx, tx

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}

String message = "";
boolean check = false;

void loop() {
  Serial.println(mySerial.available());
  mySerial.println("hindi nagagana");
  while (mySerial.available() > 0) {
    Serial.println(mySerial.readString());
    check = true;
  }

  if (check == true) {
    Serial.println(message);
  }

  delay(200);
}

Or any idea on how to control the Arduino Uno via the internet, such as a simple LED blink?
I used Firebase for databases an I plan to use ReactJs for webApp/Native App (nodeJs).

you print the empty String message forever once something is received on mySerial

Are you sure you have tx connected to rx and vice versa?  You could use the serial monitor to test each half in isolation.

i think you should change Serial.write() to Serial.print() because Serial.write() is for send data as bytes or series of bytes and Serial.print() send as human-readable text.
Reference:
Serial.write()
https://www.arduino.cc/reference/en/language/functions/communication/serial/write/
Serial.print()
https://www.arduino.cc/reference/en/language/functions/communication/serial/print/
esp 8266 code:
void setup()
{
 Serial.begin(9600);
}
void loop(){
    Serial.print("hello friend");
    delay(2000);

 }

Hi thank you for answering my question it really help but the thing is , its not working T_T is there any library or board installation do i need to install?? Im ran out of google stuff on the internet

write and print are same for string

Can you add your wiring diagram into question?


text:
Using Arduino to read and write data to RS232 device
I have a micro turbojet engine (JetCat P100-RX) which is operated through an Electronic Control Unit (ECU).
The ECU has a lot of information about the engine. I want to access that information and also send commands to the ECU to control the engine.
The ECU connects to a Mini I/O device. This connection is shown in the following image:

The details of both the ECU serial connection and the Mini I/O Board are given in this manual page 4. (What I understand here is that the data stream from the Mini Board follows a RS232 protocol.) It looks as shown:

I would like to collect the information from the Tx, Rx and GND pins using the Arduino Uno.
How can I do this? The Arduino is connected to my PC through the USB port.
EDIT1: What I tried doing:
I connected the Tx, Rx and GND of the Mini Board to pins 10 and 11 of the Arduino and configured 10 and 11 as serial pins and GND to Arduino GND (Rx anf Tx respectively) using SerialSoftware as follows:
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600); // Set to 9600 as the manual says (link above)
}

void loop() {
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
}

My circuit diagram:

But I don't get any output on the Serial Monitor.
While reading online I found out that I need some converter. Following these posts, I have bought a MAX3232. Do I need to use that? How do I use that and what changes do I make in my code?

not a question about arduino specifically ... you would have the same question if you used any other microcontroller ... first thing to do is to determine the signalling voltage levels on the RxD and TxD pins

The manual for the device shows that TX and RX are 3.3V signals.

@jsotola Yes Indeed, the pins are 3.3V. Now where shall I move from here? I am not an electronics guy ;)

@Wendall You are right, the manual does say that. Now how shall I connect?

Since you are not using the JetCat RS232 adapter (which converts the 3.3V signals into RS-232 levels (which would require the MAX 3232) you should be able to connect directly to the UART of your Arduino. Once you have it working with your hardware THEN try to get it going using a software driven serial port. In my experience, software ports work OK, but not well and almost not at all if I am using interrupts for my own purposes. Since it is a 3.3V signal you MAY have to convert them to 5V. Google around a bit, there are lots of ways to do it. There are 3V Arduinos too, then it will work at 3V.

Since the USB interface uses the same Arduino UART, either be careful not to send anything from your PC to the Arduino, or indeed use a software port. As mentioned it can work fine.

That is relatively easy to do.  If you have a Mega or another Arduino that has more than one serial port, great. If not, then softwareserial is what you need. For this to work all grounds must be connected.
Softwareserial can only receive on one channel at a time. On the hardware level you should use a high-impedance receiver to monitor both the RX and TX signals. I use a 74HC14 (74C914 is rated at +- 25 V on its input) or similar device. Place a 50 kΩ resistor from the RX to an input on the IC, do the same with the TX to another input on the IC. The input protection diodes of the 74HC will limit the current, at 50 kΩ 50 V gives 1 mA.
Connect the outputs of the IC to inputs of the Arduino. Each input needs to be configured to receive ASYNC input at the correct baud and other parameters. I have done this many times and it works great. I always did it with UARTs, not software. Note the 74HC device inverts the signal as is normal with RS232. There are various modules available for the Arduino that have a USART, UART or similar serial device on them.

Thanks for your reply. Para1: Softwareserial-check. What do you mean "all" grounds? I see only 1 GnD pin on the Mini Board. Para2: I don't understand what you are talking about, the voltages on the Mini Board are 3.3V, where is 50V coming from? Para3: How to configure to receive ASYNC input at correct baud rate? Can you show some code as example?

What does the Mini board connect to. RS232 is a three wires, one for Tx, one for Rx, and one for Ground. The grounds of each unit need to be connected. That is to simply show the input to the gate is rugged. At 50V you will have 1 mA of current into the HC protection, and not destroy the chip. Sorry on the code, there is a lot of it posted for the Arduino. At best I could only guess as you do not even have the design finished. Be sure you get the number of bits correct, parity correct, number of stop bits correct and of course the baude. Typically is 9600,n,1 (9600 baud, no parity and 1 stop.


text:
Why we are using client.flush() in the program code ,when we connect Esp8266 with internet or web server?
I am using Esp8266 Wifi modular (12-E) for controlling a led through the access of wifi/webserver.
I have written code in Arduino ide taking various references from the google.In the code, I didn't understand the client.flush(), why we are using this method? In google, I have searched about many explanations, I got common to explain which I don't understand till yet.
"Waits for the transmission of outgoing serial data to complete."
I didn't get till yet. can anyone explain to me in simple terms?
/
/ Wait until the client sends some data

  Serial.println("new client");

  while(!client.available()){

    delay(1);

  }

  // Read the first line of the request

  String request = client.readStringUntil('\r');

  Serial.println(request);

  client.flush();

This is most likely related to the old usage of .flush() from pre IDE version 1.0.0.
In those old versions .flush() would erase any pending data in the reception buffer. It was the equivalent of:
while (client.available()) {
    client.read();
}

Now though it's used to ensure that all data has been sent before doing anything else. In this situation it's completely meaningless.

I mean to say suppose if I am client, request for anything from the server and my request read by in the Arduino by this line "
String request = client.readStringUntil('\r');"
Then the serial monitor will print my message.
then client. flush will flush my current request before coming to a new client request. Is it?
please give me a simple example where I can understand easily. if possible try to explain to me from the code which is posted above.

With a version of the IDE released within the past few years client.flush() will do absolutely nothing. In an ancient  version it would discard anything remaining in the buffer.

In those old versions .flush() would erase any pending data in the reception buffer. It was the equivalent of can you explain to me what is meaning of reception buffer? is it a place where incoming data will store?

Yes. It's where your "client" stores the data it receives before you .read() it.

With a version of the IDE released within the past few years client.flush() will do absolutely nothing. In an ancient version, it would discard anything remaining in the buffer. sir I need toa ask you what is buffer?

Yes. It's where your "client" stores the data it receives before you .read() it. Sir,  can you explain to me, in brief, the above code which I have posted earlier?

A client never knows when it's going to receive data. Data just arrives. When it does so an interrupt (typically) is triggered. This interrupt receives the data that has arrived and stores it away in an internal block of memory called a "buffer". Your code then uses .read() to get the data out of that "buffer". Data can arrive and be stored into that buffer at any time, not just when you're using .read() to get it into your program. If more data is sent (and thus stored in the buffer) than you read from it with .read() then there will be data left over. .flush() used to remove ...

... that data from the buffer, but now doesn't. Now if you want to empty out any remaining data you have to do it manually.

Let us continue this discussion in chat.


text:
I am getting an error while trying to set up the U8g2 library
I am just trying to set up the U8g2 library to use an OLED. I read through the documentation and tried copying and pasting the code block example for the constructor, but switched out their information for my OLED's information. After trying to verify, the IDE returned this error:
exit status 1
expected ')' before ',' token
#include <SPI.h>
#include <U8g2lib.h>

//Constructor
U8G2_SSD1306_128X64_NONAME_1_SW_I2C(U8G2_R0,A5,A4);```

I saw a similar post about this problem from four years ago, but the only suggestion on there was to capitalize the "A" in the analog pins. I tried this and nothing changed. Any help would be much appreciated!

are there the correct number of arguments in the constructor?

According to the website, it takes in the rotation, clock, and data. It also has [, reset] listed, but I don't have a pin for that. https://github.com/olikraus/u8g2/wiki/u8g2setupcpp

i think that you are missing the object name U8G2_SSD1306_128X64_NONAME_1_SW_I2C abc123(U8G2_R0,A5,A4);

I figured out what I was doing wrong. I was copying the name from the Constructor Reference and immediately inputting the arguments in parentheses. I needed to put u8g2 after the constructor name and then put the arguments. Thanks!
The corrected code is as follows:
#include <Arduino.h>
#include <SPI.h>
#include <U8g2lib.h>

//Constructor
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0,A5,A4);

It doesn't have to be "u8g2".  You could name your instance Fred or Jim or Bob for all the compiler cares.  But you do have to give it a name.


text:
How are the different sleep modes used for esp8266?
I am currently trying to power my esp8266 with a battery, but I want to decrease the power consumption (current mostly). I understand there are different sleep modes, but I do not understand what can I use for each sleep mode. I want to know what functions are still enabled during each sleep mode.
Example: Can I use ADC pins in modem sleep?
My biggest question:
I am sending beacon frames to my phone, I want to know if I can use one of these sleep modes while sending my beacons at the same time? Do I need my CPU or do I need my Clock to send frames?


text:
ESP32 print weird data on Arduino IDE Serial Monitor
I tried to upload a sketch on esp32 devkit v1 (wroom) picture of my board is below :

but this message is always printed on the serial monitor continuously and quickly :
rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
ets Jun  8 2016 00:22:57
I tried multiple sketches and all of them successfully uploaded but always got same data printing in serial monitor as output
In the beginning, the shield on the board heats up a little, but after I made the following settings, it no longer heats up (i powered my board only by connecting it by simple USB cable from my laptop USB port) :
Board : ESP32 Dev Module
Upload Speed :115200
CPU Frequency : "240MHz(wifi/BT)
Flash Frequency : 80MHz
Flash Mode : QIO
Flash Size : 16MB(128Mb)
Partition Scheme : 16M Flash(3MB APP/9MB FATFS)
Core Debug Level : None
PSRAM : Enabled
Arduino IDE version : 1.8.9
ESP Core version : by Espressif Systems version 1.0.6
Is my board burnt due to the setting for maximum performance, and I shouldn't have made these settings for this board?  To adjust these parameters in a way that does not damage the board, how much should I adjust each parameter?
Any suggestions to fix it?
(Nothing connected to GPIO pins and also nothing connected to wifi & Bluetooth)
UPDATE :
If I set the board settings to default, the program will upload to the esp32 board, but I want to use the maximum performance of my board, so how high can I increase each setting?
(settings like cpu freq. Flash freq. and etc. )
How can i be sure of this?
Is there any sketch & instructions to find out how high can i select them?(it seems the board isn't Original and I'm not sure about it's specifications, how can i get this information by any sketch from it and then how high can i set the setting? )

Have you tried an empty sketch with nothing connected to the ESP32?

Is it possible to upload empty sketch on it? ( nothing connected to the board at all - answer deited by mentioning this)

an empty sketch is a sketch with only the functions setup() and loop() without anything in them

I know, i tried now and successfully uploaded but got same result

It seems this error can have many reasons. How are you powering the ESP? Do you use the latest ESP32 core in the Arduino IDE? What are your board settings when programming?

The question updated by the info you want (thanks for your help)

This looks like a very standard ESP32 Dev board, which usually have only 4MB of Flash and no PSRAM. Change the settings for "Flash Size" to 4MB, change the PSRAM setting to "disabled" and try again. You are also working with an old Arduino IDE version and ESP32 Core version.

What is the rest of setting? Are they right? (Frequencies, partition Scheme, ... ). do those settings work for this board?

setting changes done, still same problem

set 40MHz for the flash

"ESP Core version : by Espressif Systems version 1.0.6"  This seems to be latest the 1.x line, but we're up to 2.0.5 now overall. You may want to try with the current core. The IDE is also a little outdated, but if either make any difference at all, it would probably be the core version. May not matter at all, but it's an easy test and odds are anyone trying to help is on the newer core anyway.

I found the an issue . The question updated by new info. Check it out

if your flash memory chip can handle only 40 MHz then you can't set 80 MHz. if is connected as DIO then you can't set QIO. if the module has a 4 MB flash, you can't set 16 MB in Tools menu

The main question is, the board it's not Original and how can i be sure of these? And then what is the detailed instructions to set these board settings?

Simply use the defaults as they are usually fine. If your board runs with the defaults, you can try to change a setting and see if it has any effect. There usually is not much to gain performance wise. You can find out what most settings do by searching for them or looking them up in the ESP32 data sheet. For example here is a discussion about Flash modes which may be interesting.


text:
Recognizing fake NEO-M8N gps module?
I bout a NEO-M8N gps module but I can't connect to u-blox softwares (both u-center2 & u-center_v22.07)
It seems to be one of the junk modules that China mass-produces
Module's pictures :

I tried TinyGPSPlus, Sparkfun u-blox and some other libraries to connect it to my ESP32 Dev. Board (30 pin board) but i cant programme it,
Also i connected to my laptop USB port directly but i even can't see  it coming up to my device manager list (not even as unknow device)
All i can see is the onboard LED turning On when i connect it
Is there any Arduino sketch to recognise it (recognise it's core) to find it's library? Or is there any free windows software to recognise all gps modules?
And then, how can i programme it to connect esp32 and give me lat, long & alt as float numbers?
Note : i have ESP32 Dev. Kit (30 pin) as my only controller so, any suggestion sketch must be compatible with the board

sounds like the module has failed

There is a very simple Arduino program you can try here: https://randomnerdtutorials.com/guide-to-neo-6m-gps-module-with-arduino/ . You'll have to adapt it for the ESP32 to use one of the ESP32's other serial ports instead of using the SoftwareSerial library. Note that TX and RX are crossed. This may help if there is a problem only with the device's USB interface.

I'm using Neo-M8N-0-10 not Neo-6m

just plug the unit to terminal software, set the baud to 9600 and see what is coming out.
you can even use Arduino IDE, if the unit is not faulty, you should be able to see data coming out.
I use Neo8M & Neo6M, all bought from AliXpress, not a single failed so far.

didn't get anything

and about connecting and getting data from Arduino IDE, it's not make sense because in the IDE you have to select the board and it doesn't support any gps module as far as i know

I am using Arduino IDE to test the serial data from GPS.  just plug in the GPS module, if windows(I assume you are using windows) detects the port, that particular port will appear in the port list on the arduino ide. just select the port and open the serial monitor.  data should be flowing in.  if the port does not appear in your IDE, most likely windows does not recognise the port, ie port is faulty or the gps module is faulty.  hope this helps.


text:
Does the StringObject.reserve() function prevent memory fragmentation/leaks?
I'm currently writing and testing a professional Arduino application, I'm aware of the dangers of using the String class, so I began to implement C-style strings in some places, but it's just way harder using them to receive data from a Software Serial port that's variable in size and needs some manipulation.
I've upgraded from an Arduino Uno to a Leonardo so my current minimum SRAM usage is 1325 bytes (51%)
Here's the relevant part of my code:
String serialContents;
char emailChar[SIZEOF_ARRAY][SIZEOF_CHAR];

void setup(){
  serialContents.reserve(70);
  SerialOne.begin(9600);
}

void loop{

  if (SerialOne.available() > 0) //something is there to be read
  {
    serialContents = SerialOne.readStringUntil('\n'); //make a string of the characters coming on serial
  }

  if (serialContents.length() >= 60)
  {
   serialContents = ""; //ignore serial data
  }
 else{
  serialContents = cutString(serialContents); //some String manipulation, no adding only cutting
  serialContents.replace("@", "%40");
  serialContents.toCharArray(emailChar[count], 31);
  serialContents = ""; //String reset
}

So my question is, does something like this make my code unstable? Does the
reserve() function help at all?
Edit: Here's the cutString() function
String cutString(String request) {

  int points = request.indexOf(':');

  if (request.substring(0, points) == "CHECKOUT")
  {
    modoPedido[count] = 'o'; //char array
  }
  else if (request.substring(0, points) == "CHECKIN")
  {
    modoPedido[count] = 'i';
  }

  request = request.substring(points + 1);

  return request;
}

there is readBytesUntil if you want a convenient function for c-string

Reserving space will help reduce memory fragmentation, but much of what else you are doing is swamping that small improvement you have made.
The biggest area of concern is your cutString function, which you have omitted from your code above.  Passing a String as a parameter, modifying it, and then returning it again, ends up in new String objects being created and destroyed multiple times, which will make a mess of your heap.
Instead you should pass a String object by reference, and modify that object in-place. No need to return anything.
void cutString(String &theString) {
    // Modify theString here.
}

Of course, what you do in cutString could cause more problems - you should include that function in your code above so we can check it out.

Thanks!
I've updated the first post. Damn, I think I'm creating at least three more String objects with the substring() function. I guess I'll use other way to see if the string contains checkin or checkout like indexOf(), and use the reference method instead of returning the String object.


text:
Can I make my own TFT LCD shield?
I have a few TFT LCD displays lying around which I salvaged from old phones. I would really like to use them with my Arduino. I didn't get anything about making a shield on the net but only links to eBay and Amazon. Please help.
It is a 36 pin tft for which adapters can be found.
But I don't know the wiring or the pins concerned.
Here is the supposed pin data sheet for my lcd for ur help

gre_gor , the image I provided shows the commonest of LCDs with 36 pins, for which adapters can be found. The question you refer above has a lcd with a custom adapter, and thus of very limited use in a Arduino.Thanks though.

Well I asked about the wiring and the concerned pins to which I can connect it. I don't know about that. And I couldn't get the wiring diagram of the tft shield that is in the market.

The adapter is irrelevant. The answer is the same.

Thanks , but I will wait for some others to answer. No hard feelings though gre_gor.

Unless you can get the datasheet for the TFT with the details of each pin on the connector you have zero chance.

Majenko, I am adding a pic to my question that shows the pin data sheet for a 3.5 inch tft lcd, and I think mine should be similar. Please help now.

Unless it is the exact same screen by the exact same manufacturer chances are it's different. There is no standard, and many screens the "same size" are completely different.

TFT shields are so cheap why waste your time trying to salvage something you have no data for? If you want to make your own (and I make my own systems with built-in TFT screens) buy a new TFT screen that you can get the datasheet for. I get mine from http://www.buydisplay.com


text:
tinkercad arduino simulator integers being outputted as larger numbers than they are?
I am using an Arduino simulator on www.tinkercad.com (a seemingly nice free product from Autodesk).  Working on conversion of an integer to a 16 bit binary string for output to a DAC, but unfortunately even at the first step I am getting unexpected behavior.
void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  Serial.print("Sanity Check\n");
  uint16_t num = 12000;
  Serial.print("\nNumber: " + String(num) + "\n");
  delay(3000);
}

Surprisingly the above code gave the following output:
Sanity Check

Number: 12222

Is there something I am doing wrong, or something wrong with the simulator?   The error seems to crop up with any value over 10000.  10001, 10002, 10003 all print as 10000.  11000, 11001, 11002, 11003 all print as 11111.  etc, etc.  What could be going on?

My Uno prints “Number: 12000”.

Bug. No other explanation. Real hardware (Arduino Uno) prints 12000.
Even the debugger tells me that the value of that variable is 12000.

Outputs:
Number: 12222
12000
12222 something

Most interestingly if you Serial.println() the number, it is outputted correctly. The bug must be in the constructor of the String object, as demonstrated by the "test" String. This bug also occurs on other data types, e.g. int.
If you only use direct Serial.print[ln] calls you should be able to workaround that bug.

Tinkercad is (was) a very good simulator but it has stopped updates.
Here is the output from the free Arduino simulator from here
This project is used for the below screenshot

Here is an article pointing some more features of the simulator


text:
Arduino UNO SPI Serial Clock (Pin 13 SCK) gives no output, but Blink Example (Pin 13 LED) works
I was attempting to use an SPI library and DAC device (Library AD57X4) for the first time, when I realized that the Arduino UNO Pin 13 was not outputting a clock signal (something I expected it to do).
Using a serial analyzer I can sample at 16MHz, yet nothing comes out of UNO Pin 13 except maybe a very occasional noise blip.  After no luck with the AD57X4 library, I wrote this simple program to try to get SPI clock signal on UNO Pin 13.  Setting UNO Pin 13 to OUTPUT makes no difference.
#include <SPI.h>

void setup() {
  //pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

I do get a signal on UNO Pin 11 (MOSI), frequency 381 kHz.  This signal is due to SPI.transfer(0x00); , as it disappears when the line is removed.  Although likely irrelevant to the question, I noticed some periodic 6us gaps every ~1ms on this UNO Pin 11 (MOSI) signal.

The Blink Example Works:
    // the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

I tried monitoring UNO ICSP header pin 3 (SCK), however there is no signal for either the SPI or Blink programs.

UPDATE:
I switched over to an Arduino NANO that I had around and was able to get this output.  I expected the clock to be high frequency and continuous for SPI.  The MOSI output is the same 381 kHz that I observed earlier.

#include <SPI.h>

void setup() {
  pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

EDIT:
Here is a schematic of my circuit.  I am using an EVAL-AD5754R Evaluation Board from Analog Devices.  Here is a link to the AD5754 chip data sheet.  I'm providing 5V power through the J7 terminal (via the UNO), and supplying the SPI connections through the J8 header. The EVAL-AD5754R board works perfectly via USB and their software, but now I am transitioning to controlling it through Arduino/SPI.  As you can see I'm temporarily using a 12V battery for the analog voltage supply - this is until I build a regulated circuit.  J8 DGND pins are shown unconnected on the schematic below, but I've tried connecting one of them to the UNO's GND to no effect.

This is the configuration of the linkers which act to configure the eval board:

This is an annotated table describing J8 header connections (UNO <-> EVAL-AD5754R):

Can you post your schematic? And the exact part number (and preferably a link to the datasheet) of your DAC device.

@NickGammon I am using EVAL-AD5754R from Analog Devices.  I edited the question to include a schematic of the UNO and the configuration of the DAC board.

set pin 10 as output in test sketch, to prevent uno to fall into slave role with the SPI library

I can't reproduce that. Using your first test code:
#include <SPI.h>

void setup() {
  //pinMode(13, OUTPUT);
  SPI.begin();

}

void loop() {
  SPI.transfer(0x00);
}

I get this on the logic analyzer:

Also on my scope on pin 13:

As expected, a 4 MHz signal with gaps between the bytes.

I expected the clock to be high frequency and continuous for SPI.

No, you get the clock when data is being transmitted and not at other times.

Although likely irrelevant to the question, I noticed some periodic 6us gaps every ~1ms on this UNO Pin 10 (MOSI) signal.

That would be the Timer 0 interrupt kicking in (roughly every 1 ms) and thus interrupting your looping code for a few microseconds.

Possible solution
Try enabling slave select (write LOW to pin 10). I think some versions of the logic analyzer ignore incoming data if the slave isn't selected.
In fact, pin 10 should be an output, otherwise the SPI hardware goes into slave mode. Some versions of the library might not set it to output.

I'm going to try this tomorrow. I was able to draw a schematic of my circuit above.

I was able to get the clock signals now as expected. Library still not working for me (a separate question), but at least I can now see the signals on the SPI!  Thanks


text:
Can you make it so, when your phone connects to the Hc-05 on a Arduino, a variable changes?
So whenever my phone gets close, and it connects to the Hc-05, the Arduino changes a variable? I want to avoid the use of apps, where the user has to do anything after first time connecting. The project is an automatic door opener, wherein the user for whatever reason can't use their hands, like if they have groceries in their hands.
Thank you for your time

Detecting successful connection with HC-05
The HC-05 can be configured to do what you are after.
Search for "POLAR" in the AT set documentation.
AT+POLAR=0,1

should be what you need as per their examples.
Hook up PI09 to your arduino and wait for it to go HIGH.
You may even want to wake up your arduino with an hardware interrupt using that signal.
Depending on your package, this may require soldering to the HC-05 module.
The datasheet features a pinout in that case. Be sure to checkout the manual of your breakout board first.


text:
TFT and SD don't work together
I use a 2.8" TFT Touch Shield v1 and I want to read some data that were stred in sd and plot them with the tft.
When the following code is ordered, to access the data. TFT freezes.... but the code's execution is continued...
    pinMode(SS, OUTPUT);
    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
       Serial.println("Card failed, or not present");
    // don't do anything more:
       while (1) ;
    }

    Tempfile = SD.open("DATALOG.TXT",FILE_READ);
    if (! Tempfile) {
       Serial.println("error opening datalog.txt");
    // Wait forever since we cant write data
       while (1) ;}

I tested the code on the example of the tft graphics test... and the result was a freezed tft...
I tried also to run the example: tftbmp but the tft remains black. Once again the code is executed in the loop as i receive results from the Serial monitor but tft is black...
I use an Arduino Uno R3.
Any tip is welcomed

The solution to getting data from SD to TFT may depend on the type of data stored.  See examples included in software for your TFT.  Also it might be possible to solve this issue with 2 Arduinos using Software Serial, which, I believe, is included in the Arduino IDE.  Assume you have stored analog data from a sensor on an SD.  During the recording, you were able to visualize incoming data on your serial plotter and  your sketch also allowed you to see the live data on your TFT.   You now wish to visualize the  data recorded on your SD on the TFT once more. To accomplish this with Software Serial,  the SD card could be mounted on one Arduino and  the TFT on another.  The Tx and Rx pins of the 2 Arduinos must be connected as described in the Arduino Software Serial guide.  This technique should allow user to "fool" the Arduino with TFT into thinking it is receiving live analog data from a sensor.  Since the user has already written the sketch to visualize data from a sensor on TFT , the modifications should be easy.

old topic, but since I'm having the same issues I'll share what I found.
chipSelect is usually 10 for arduino uno, some exemples have other pin setted.
also I found a guy claiming he fixed his issues setting after
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);

chip select is 10 if Uno is SPI slave. if Uno is master 10 must be OUTPUT. that is way it is usually used as chip select for one of the SPI slaves. the SPI library sets the SS pin as OUTPUT and HIGH in begin()