Orologio NTP a matrici di LED e scansione delle reti WiFi

Ciao a tutti.
Sto modificando un orologio NTP a matrici di LED. Connettendolo semplicemente con
WiFi.begin ("ReteMiaTP", "Pippo");
o
WiFi.begin ("Retemia A5", "Pippo");
funziona, ma in nessun modo riesco a far funzionare la scansione automatica delle reti. Se uso i const char * e strcmp ottengo errore, perché va a confrontare un oggetto String (che evidentemente viene da WiFi.SSID) con un const char *.
Potete aiutarmi?
Grazie
Gianluca

#include <ESP8266WiFi.h> // URL aggiuntivo per il gestore schede: http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <SPI.h> // Mi sembra che funzioni anche senza...
#include <Adafruit_GFX.h> // Usato da Max72xxPanel
#include <Max72xxPanel.h> // Installare da zip: https://github.com/markruys/arduino-Max72xxPanel
#include <time.h>

// const char *ssid[] = {"ReteMiaTP",        "Retemia A5"};
// const char  *pwd[] = {"Pippo", "Pippo"};

const char *ssid = "ReteMiaTP";
const char  *pwd = "Pippo";
const char *ssid1 = "Retemia A5";
const char  *pwd1 = "Pippo";

// String ssid = "ReteMiaTP";
// String  pwd = "Pippo";
// String ssid1 = "Retemia A5";
// String  pwd1 = "Pippo";

unsigned long t_scan=0; // Per il conteggio del tempo tra una scansione e l'altra della rete (che impiega 2s) durante il loop
int periodo_scan=5000; // Periodo di scansione se c'è già stata una prima conessione
byte prima_conn_ok=0;
byte scan_fatta=0; // Va a 1 dopo aver fatto la scansione ai primi secondi del minuto, per non ripeterla ogni 2s per 10s.

#define TZ "CET-1CEST,M3.5.0/2,M10.5.0/3"

/*
Sull'ora legale: https://forum.arduino.cc/index.php?topic=643074.0
Per l'Italia/Roma:
CET-1CEST,M3.5.0/2,M10.5.0/3

CET = lo Standard Time quando non è presente l'ora legale (Central Europan Time)
-1 = indica 1 ora a Est di Greenwich (quindi CET = GMT+1 = UTC+1)
CEST = lo Standard Time quando è presente l'ora legale (Central Europan Summer Time) con spostamento di 1 ora (default)

M3.5.0 = quando inizia l'ora legale, ossia a Marzo (3) nell'ultima (5) Domenica (0)
/2 = l'ora locale di quando inizia l'ora legale (le 2 di notte)

M10.5.0 = quando termina l'ora legale, ossia a Ottobre (10) nell'ultima (5) Domenica (0)
/3 = l'ora locale di quando termina l'ora legale (le 3 di notte)

Il (5) è inteso come ultima settimana.
Mese.Settimana.Giorno/Ora
Mese va da 1 a 12
Settimana va 1 a 5 (con 5 si intende sempre l'ultima settimana, indipendentemente da quante ce ne sono in quel mese)
Giorno va da 0 a 6 (0=domenica)
*/

int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays   = 1;
char time_value[20];

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7 (MOSI) (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS) D1mini: GPIO2
// CLK            -> D5 (Clk)  (Same Pin for WEMOS)

byte pinCS=2;
Max72xxPanel matrix=Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

unsigned long t_int; // Temporizzazione per la lettura del potenziometro per la regolazione della luminosità.
byte P=5; byte L=7; // POSIZIONE DELL'ORARIO NEL LOOP
time_t t_prec;

/*
void WiFiScan()
{
 int n=WiFi.scanNetworks();
 for (byte i=0; i<n; ++i)
  {
  for (byte w=0; w<sizeof(ssid); w++) {if (WiFi.SSID(i)==ssid[w]) WiFi.begin(ssid[w],pwd[w]);}
  }
}
*/

void WiFiScan()
{
int n=WiFi.scanNetworks();
for (int i=0; i<n+1; i++)
  {
       if (WiFi.SSID(i)==ssid) WiFi.begin(ssid,pwd);
  else if (WiFi.SSID(i)==ssid1) WiFi.begin(ssid1,pwd1);
  else if (WiFi.SSID(i)=="ReteMiaTP") WiFi.begin("ReteMiaTP","Pippo");
  else if (WiFi.SSID(i)=="Retemia A5") WiFi.begin("Retemia A5","Pippo");
  }
}

void setup()
{
// WiFi.begin("Retemia A5","Pippo");
//  Serial.begin(9600);
// CHANGE THE POOL WITH YOUR CITY. SEARCH AT https://www.ntppool.org/zone/@ 
configTime(0*3600, 0, "it.pool.ntp.org", "time.nist.gov"); 
// setenv("TZ", "GMT-1BST",1);
// set up TimeZone in local environment
setenv("TZ", TZ, 3);
tzset();

matrix.setIntensity(0); // Use a value between 0 and 15 for brightness
matrix.setRotation(0, 1);    // Il 1° display è ruotato
matrix.setRotation(1, 1);    // Il 2° display è ruotato
matrix.setRotation(2, 1);    // Il 3° display è ruotato
matrix.setRotation(3, 1);    // Il 4° display è ruotato
matrix.setRotation(4, 1);    // Il 5° display è ruotato
matrix.setRotation(5, 1);    // Il 6° display è ruotato
matrix.setRotation(6, 1);    // Il 7° display è ruotato
matrix.setRotation(7, 1);    //  L'8° display è ruotato
matrix.fillScreen(LOW);
matrix.write();

byte P=16; byte L=7; // Variabili locali per la posizione della scritta Wi-Fi
while (WiFi.status()!=WL_CONNECTED)
  {
  delay(1000);
  matrix.drawChar(P,    0, 'W', HIGH,LOW,1); // H
  matrix.drawChar(P+L,  0, 'i', HIGH,LOW,1); // HH  
  matrix.drawChar(P+L*2,0, '-', HIGH,LOW,1); // HH:
  matrix.drawChar(P+L*3,0, 'F', HIGH,LOW,1); // HH:M
  matrix.drawChar(P+L*4,0, 'i', HIGH,LOW,1); // HH:MM
  matrix.write(); // Send bitmap to display
  WiFiScan();
  delay(1000);
  matrix.fillScreen(LOW);
  matrix.write();
  }
}

void loop()
{
if(millis()-t_int>200) {t_int=millis(); matrix.setIntensity(map(analogRead(0),0,1024,0,12));} // Ogni 200ms legge il potenziometro. 
matrix.fillScreen(LOW);
time_t now = time(nullptr);
if (now!=t_prec)
  {
  t_prec=now;
  String time = String(ctime(&now));
  time.trim();
  time.substring(11,19).toCharArray(time_value, 10);
  // Visualizza lo '0' iniziale prima delle ore 9.00:
  matrix.drawChar(P,0,    time_value[0], HIGH,LOW,1); // H
  // Cancella lo '0' iniziale prima delle ore 9.00:
  // if(time_value[0]!='0') {matrix.drawChar(P,0,time_value[0],HIGH,LOW,1);} // H
  matrix.drawChar(P+L,  0,time_value[1], HIGH,LOW,1); // _H  
  matrix.drawChar(P+L*2,0,time_value[2], HIGH,LOW,1); // __:
  matrix.drawChar(P+L*3,0,time_value[3], HIGH,LOW,1); // ___M
  matrix.drawChar(P+L*4,0,time_value[4], HIGH,LOW,1); // ____M
  matrix.drawChar(P+L*5,0,time_value[5], HIGH,LOW,1); // _____:
  matrix.drawChar(P+L*6,0,time_value[6], HIGH,LOW,1); // ______S
  matrix.drawChar(P+L*7,0,time_value[7], HIGH,LOW,1); // _______S
  if (WiFi.status()==WL_CONNECTED) prima_conn_ok=1;
  else // Non connesso
    {
    matrix.drawChar(P+L*8-1,0,'°', HIGH,LOW,1);
    if (prima_conn_ok)
      {
      if ((now%100)/10==0 && scan_fatta==0) {scan_fatta=1; WiFiScan();} // Se i secondi iniziano per 0, fa la scansione
      else scan_fatta=0;
      }
    else if (millis()-t_scan>periodo_scan)
      {
      t_scan=millis();
      WiFiScan();
      }
    }
  matrix.write(); // Send bitmap to display
  }
}

Non puoi usare l'uguale uguale per confrontare le stringhe classiche del C devi usare la funzione apposita
strncmp

Sì, hai ragione. Per cortesia, rileggi il messaggio che ho corretto.

Se il tuo scopo è quello di evitare la classe String, dato che la libreria ne fa uso temo che non possa fare molto, non mi viene in mente nulla per confrontare "al volo" una String con una char* ossia senza convertire anche la seconda in String oppure ciclare tutti i singoli caratteri e confrontarli.

Nel codice da cui sono partito:

(nella cui pagina scrivono TESTED... :frowning: ) usano variabili char* e poi scrivono:
if (WiFi.SSID(i)== ssid)
Scrivono TESTED, ma non si sa come potrebbe funzionare...
Qual è il modo giusto, anche a costo di usare String?

docdoc:
... non mi viene in mente nulla per confrontare "al volo" una String con una char* ossia senza convertire anche la seconda in String oppure ciclare tutti i singoli caratteri e confrontarli.

In realtà, se guardi la classe String, scopri che tutte le stringhe hanno un metodo nomeStringa.c_str() che ritorna la stringa classica del 'C' quindi ... nulla di extra da fare ... la si usa come una stringa classica :wink:

Guglielmo

Quindi posso confrontare lo String WiFi.SSID, convertito, con un char*...
Provo. :slight_smile:

... si, certo, appendendo la nome della tua stringa il '.c_str()' che ti ritorna la stringa classica con il terminatore 0x00 finale :wink:

Converts the contents of a String as a C-style, null-terminated string. Note that this gives direct access to the internal String buffer and should be used with care. In particular, you should never modify the string through the pointer returned. When you modify the String object, or when it is destroyed, any pointer previously returned by c_str() becomes invalid and should not be used any longer.

Guglielmo

Non da errori, ma ancora non si aggancia a nessuna delle due reti... :frowning:

#include <ESP8266WiFi.h> // URL aggiuntivo per il gestore schede: http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <SPI.h> // Mi sembra che funzioni anche senza...
#include <Adafruit_GFX.h> // Usato da Max72xxPanel
#include <Max72xxPanel.h> // Installare da zip: https://github.com/markruys/arduino-Max72xxPanel
#include <time.h>

// const char *ssid[] = {"ReteMiaTP",        "Retemia A5"};
// const char  *pwd[] = {"Pippo", "Pippo"};

const char *ssid = "ReteMiaTP";
const char  *pwd = "Pippo";
const char *ssid1 = "Retemia A5";
const char  *pwd1 = "Pippo";

// String ssid = "ReteMiaTP";
// String  pwd = "Pippo";
// String ssid1 = "Retemia A5";
// String  pwd1 = "Pippo";

unsigned long t_scan=0; // Per il conteggio del tempo tra una scansione e l'altra della rete (che impiega 2s) durante il loop
int periodo_scan=5000; // Periodo di scansione se c'è già stata una prima conessione
byte prima_conn_ok=0;
byte scan_fatta=0; // Va a 1 dopo aver fatto la scansione ai primi secondi del minuto, per non ripeterla ogni 2s per 10s.

#define TZ "CET-1CEST,M3.5.0/2,M10.5.0/3"

/*
Sull'ora legale: https://forum.arduino.cc/index.php?topic=643074.0
Per l'Italia/Roma:
CET-1CEST,M3.5.0/2,M10.5.0/3

CET = lo Standard Time quando non è presente l'ora legale (Central Europan Time)
-1 = indica 1 ora a Est di Greenwich (quindi CET = GMT+1 = UTC+1)
CEST = lo Standard Time quando è presente l'ora legale (Central Europan Summer Time) con spostamento di 1 ora (default)

M3.5.0 = quando inizia l'ora legale, ossia a Marzo (3) nell'ultima (5) Domenica (0)
/2 = l'ora locale di quando inizia l'ora legale (le 2 di notte)

M10.5.0 = quando termina l'ora legale, ossia a Ottobre (10) nell'ultima (5) Domenica (0)
/3 = l'ora locale di quando termina l'ora legale (le 3 di notte)

Il (5) è inteso come ultima settimana.
Mese.Settimana.Giorno/Ora
Mese va da 1 a 12
Settimana va 1 a 5 (con 5 si intende sempre l'ultima settimana, indipendentemente da quante ce ne sono in quel mese)
Giorno va da 0 a 6 (0=domenica)
*/

int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays   = 1;
char time_value[20];

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7 (MOSI) (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS) D1mini: GPIO2
// CLK            -> D5 (Clk)  (Same Pin for WEMOS)

byte pinCS=2;
Max72xxPanel matrix=Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

unsigned long t_int; // Temporizzazione per la lettura del potenziometro per la regolazione della luminosità.
byte P=5; byte L=7; // POSIZIONE DELL'ORARIO NEL LOOP
time_t t_prec;

/*
void WiFiScan()
{
 int n=WiFi.scanNetworks();
 for (byte i=0; i<n; ++i)
  {
  for (byte w=0; w<sizeof(ssid); w++) {if (WiFi.SSID(i)==ssid[w]) WiFi.begin(ssid[w],pwd[w]);}
  }
}
*/

void WiFiScan()
{
int n=WiFi.scanNetworks();
for (int i=0; i<n+1; i++)
  {     if (!strcmp(WiFi.SSID(i).c_str(),ssid )) {WiFi.begin(ssid, pwd );}
   else if (!strcmp(WiFi.SSID(i).c_str(),ssid1)) {WiFi.begin(ssid1,pwd1);}
  // else if (WiFi.SSID(i)=="ReteMiaTP") WiFi.begin("ReteMiaTP","Pippo");
  // else if (WiFi.SSID(i)=="Retemia A5") WiFi.begin("Retemia A5","Pippo");
  }
}

void setup()
{
// WiFi.begin("Retemia A5","Pippo");
//  Serial.begin(9600);
// CHANGE THE POOL WITH YOUR CITY. SEARCH AT https://www.ntppool.org/zone/@ 
configTime(0*3600, 0, "it.pool.ntp.org", "time.nist.gov"); 
// setenv("TZ", "GMT-1BST",1);
// set up TimeZone in local environment
setenv("TZ", TZ, 3);
tzset();

matrix.setIntensity(0); // Use a value between 0 and 15 for brightness
matrix.setRotation(0, 1);    // Il 1° display è ruotato
matrix.setRotation(1, 1);    // Il 2° display è ruotato
matrix.setRotation(2, 1);    // Il 3° display è ruotato
matrix.setRotation(3, 1);    // Il 4° display è ruotato
matrix.setRotation(4, 1);    // Il 5° display è ruotato
matrix.setRotation(5, 1);    // Il 6° display è ruotato
matrix.setRotation(6, 1);    // Il 7° display è ruotato
matrix.setRotation(7, 1);    //  L'8° display è ruotato
matrix.fillScreen(LOW);
matrix.write();

byte P=16; byte L=7; // Variabili locali per la posizione della scritta Wi-Fi
while (WiFi.status()!=WL_CONNECTED)
  {
  delay(1000);
  matrix.drawChar(P,    0, 'W', HIGH,LOW,1); // H
  matrix.drawChar(P+L,  0, 'i', HIGH,LOW,1); // HH  
  matrix.drawChar(P+L*2,0, '-', HIGH,LOW,1); // HH:
  matrix.drawChar(P+L*3,0, 'F', HIGH,LOW,1); // HH:M
  matrix.drawChar(P+L*4,0, 'i', HIGH,LOW,1); // HH:MM
  matrix.write(); // Send bitmap to display
  WiFiScan();
  delay(1000);
  matrix.fillScreen(LOW);
  matrix.write();
  }
}

void loop()
{
if(millis()-t_int>200) {t_int=millis(); matrix.setIntensity(map(analogRead(0),0,1024,0,12));} // Ogni 200ms legge il potenziometro. 
matrix.fillScreen(LOW);
time_t now = time(nullptr);
if (now!=t_prec)
  {
  t_prec=now;
  String time = String(ctime(&now));
  time.trim();
  time.substring(11,19).toCharArray(time_value, 10);
  // Visualizza lo '0' iniziale prima delle ore 9.00:
  matrix.drawChar(P,0,    time_value[0], HIGH,LOW,1); // H
  // Cancella lo '0' iniziale prima delle ore 9.00:
  // if(time_value[0]!='0') {matrix.drawChar(P,0,time_value[0],HIGH,LOW,1);} // H
  matrix.drawChar(P+L,  0,time_value[1], HIGH,LOW,1); // _H  
  matrix.drawChar(P+L*2,0,time_value[2], HIGH,LOW,1); // __:
  matrix.drawChar(P+L*3,0,time_value[3], HIGH,LOW,1); // ___M
  matrix.drawChar(P+L*4,0,time_value[4], HIGH,LOW,1); // ____M
  matrix.drawChar(P+L*5,0,time_value[5], HIGH,LOW,1); // _____:
  matrix.drawChar(P+L*6,0,time_value[6], HIGH,LOW,1); // ______S
  matrix.drawChar(P+L*7,0,time_value[7], HIGH,LOW,1); // _______S
  if (WiFi.status()==WL_CONNECTED) prima_conn_ok=1;
  else // Non connesso
    {
    matrix.drawChar(P+L*8-1,0,'°', HIGH,LOW,1);
    if (prima_conn_ok)
      {
      if ((now%100)/10==0 && scan_fatta==0) {scan_fatta=1; WiFiScan();} // Se i secondi iniziano per 0, fa la scansione
      else scan_fatta=0;
      }
    else if (millis()-t_scan>periodo_scan)
      {
      t_scan=millis();
      WiFiScan();
      }
    }
  matrix.write(); // Send bitmap to display
  }
}

Messaggi di debug nel for in modo da capire cosa restituisce la funzione WiFi.SSID(i) e anche il risultato della strcmp in modo che puoi iniziare a capire se entra o meno in un ramo if e se no avere idea del possibile problema

Io forse ricordo male, perché non uso oggetti String da un sacco di tempo

Ma la classe String sovraccarica l'operatore di confronto (==)
E pertanto è possibile confrontare String con stringhe di C usando ==, dato che avviene il casting implicito a String

Ma devono essere char *, non const char *

Datman: puoi provare?

E' vero, non da errore. Però ancora non si connette...

char *ssid = "ReteMiaTP";
char  *pwd = "Pippo";
char *ssid1 = "Retemia A5";
char  *pwd1 = "Pippo";

void WiFiScan()
{
int n=WiFi.scanNetworks();
for (int i=0; i<n; ++i) // WiFi.SSID(i) è un oggetto String, che deve essere convertito per poter essere confrontato con un char*.
  {
        if (WiFi.SSID(i)==ssid )) {WiFi.begin(ssid, pwd );}
   else if (WiFi.SSID(i)==ssid1)) {WiFi.begin(ssid1,pwd1);}
  // else if (WiFi.SSID(i)=="ReteMiaTP") WiFi.begin("ReteMiaTP","Pippo");
  // else if (WiFi.SSID(i)=="Retemia A5") WiFi.begin("Retemia A5","Pippo");
  }
}

Così, non sempre si connette:

while (WiFi.status()!=WL_CONNECTED)
  {
  delay(1000);
  matrix.drawChar(P,    0, 'W', HIGH,LOW,1); // H
  matrix.drawChar(P+L,  0, 'i', HIGH,LOW,1); // HH  
  matrix.drawChar(P+L*2,0, '-', HIGH,LOW,1); // HH:
  matrix.drawChar(P+L*3,0, 'F', HIGH,LOW,1); // HH:M
  matrix.drawChar(P+L*4,0, 'i', HIGH,LOW,1); // HH:MM
  matrix.write(); // Send bitmap to display
  // WiFiScan();
  const char* Paperino = "Retemia A5";
  const char* Pluto = "Pippo";
  WiFi.begin(Paperino, Pluto);
  //WiFi.begin("Retemia A5","Pippo");
  delay(3000);
  matrix.fillScreen(LOW);
  matrix.write();
  }

Così si connette sempre in 2 secondi:

#include <ESP8266WiFi.h> // URL aggiuntivo per il gestore schede: http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <SPI.h> // Mi sembra che funzioni anche senza...
#include <Adafruit_GFX.h> // Usato da Max72xxPanel
#include <Max72xxPanel.h> // Installare da zip: https://github.com/markruys/arduino-Max72xxPanel
#include <time.h>

#define TZ "CET-1CEST,M3.5.0/2,M10.5.0/3"
/*
Sull'ora legale: https://forum.arduino.cc/index.php?topic=643074.0
Per l'Italia/Roma:
CET-1CEST,M3.5.0/2,M10.5.0/3

CET = lo Standard Time quando non è presente l'ora legale (Central Europan Time)
-1 = indica 1 ora a Est di Greenwich (quindi CET = GMT+1 = UTC+1)
CEST = lo Standard Time quando è presente l'ora legale (Central Europan Summer Time) con spostamento di 1 ora (default)

M3.5.0 = quando inizia l'ora legale, ossia a Marzo (3) nell'ultima (5) Domenica (0)
/2 = l'ora locale di quando inizia l'ora legale (le 2 di notte)

M10.5.0 = quando termina l'ora legale, ossia a Ottobre (10) nell'ultima (5) Domenica (0)
/3 = l'ora locale di quando termina l'ora legale (le 3 di notte)

Il (5) è inteso come ultima settimana.
Mese.Settimana.Giorno/Ora
Mese va da 1 a 12
Settimana va 1 a 5 (con 5 si intende sempre l'ultima settimana, indipendentemente da quante ce ne sono in quel mese)
Giorno va da 0 a 6 (0=domenica)
*/

int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays   = 1;
char time_value[20];

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7 (MOSI) (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS) D1mini: GPIO2
// CLK            -> D5 (Clk)  (Same Pin for WEMOS)

byte pinCS=2;
Max72xxPanel matrix=Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

unsigned long t_int; // Temporizzazione per la lettura del potenziometro per la regolazione della luminosità.
byte P=5; byte L=7; // POSIZIONE DELL'ORARIO NEL LOOP
time_t t_prec;

void setup()
{
  // INSERT YOUR SSID AND PASSWORD HERE
  // WiFi.begin("ReteMiaTP","Pippo");
  WiFi.begin("Retemia A5","Pippo");
//  Serial.begin(9600);
  // CHANGE THE POOL WITH YOUR CITY. SEARCH AT https://www.ntppool.org/zone/@ 
  configTime(0*3600, 0, "it.pool.ntp.org", "time.nist.gov"); 
  // setenv("TZ", "GMT-1BST",1);
  // set up TimeZone in local environment
  setenv("TZ", TZ, 3);
  tzset();
  
  matrix.setIntensity(0); // Use a value between 0 and 15 for brightness
  matrix.setRotation(0, 1);    // Il 1° display è ruotato
  matrix.setRotation(1, 1);    // Il 2° display è ruotato
  matrix.setRotation(2, 1);    // Il 3° display è ruotato
  matrix.setRotation(3, 1);    // Il 4° display è ruotato
  matrix.setRotation(4, 1);    // Il 5° display è ruotato
  matrix.setRotation(5, 1);    // Il 6° display è ruotato
  matrix.setRotation(6, 1);    // Il 7° display è ruotato
  matrix.setRotation(7, 1);    //  L'8° display è ruotato
  matrix.fillScreen(LOW);
  matrix.write();
  
  byte P=16; byte L=7; // Variabili locali per la posizione della scritta Wi-Fi
  while (WiFi.status()!=WL_CONNECTED) {
    matrix.drawChar(P,0, 'W', HIGH,LOW,1); // H
    matrix.drawChar(P+L,0, 'i', HIGH,LOW,1); // HH  
    matrix.drawChar(P+L*2,0,'-', HIGH,LOW,1); // HH:
    matrix.drawChar(P+L*3,0,'F', HIGH,LOW,1); // HH:M
    matrix.drawChar(P+L*4,0,'i', HIGH,LOW,1); // HH:MM
    matrix.write(); // Send bitmap to display
    delay(500);
    matrix.fillScreen(LOW);
    matrix.write();
    delay(500);
  }
}

void loop()
{
  if(millis()-t_int>200) {t_int=millis(); matrix.setIntensity(map(analogRead(0),0,1024,0,12));} // Ogni 200ms legge il potenziometro. 
  matrix.fillScreen(LOW);
  time_t now = time(nullptr);
  if (now!=t_prec)
    {
    t_prec=now;
    String time = String(ctime(&now));
    time.trim();
    time.substring(11,19).toCharArray(time_value, 10);
    // Visualizza lo '0' iniziale prima delle ore 9.00:
    matrix.drawChar(P,0,    time_value[0], HIGH,LOW,1); // H
    // Cancella lo '0' iniziale prima delle ore 9.00:
    // if(time_value[0]!='0') {matrix.drawChar(P,0,time_value[0],HIGH,LOW,1);} // H
    matrix.drawChar(P+L,  0,time_value[1], HIGH,LOW,1); // _H  
    matrix.drawChar(P+L*2,0,time_value[2], HIGH,LOW,1); // __:
    matrix.drawChar(P+L*3,0,time_value[3], HIGH,LOW,1); // ___M
    matrix.drawChar(P+L*4,0,time_value[4], HIGH,LOW,1); // ____M
    matrix.drawChar(P+L*5,0,time_value[5], HIGH,LOW,1); // _____:
    matrix.drawChar(P+L*6,0,time_value[6], HIGH,LOW,1); // ______S
    matrix.drawChar(P+L*7,0,time_value[7], HIGH,LOW,1); // _______S
    if (WiFi.status()!=WL_CONNECTED) matrix.drawChar(P+L*8-1,0,'°', HIGH,LOW,1);
    matrix.write(); // Send bitmap to display
    }
  
}

Bene, un altro motivo per non usare il modificatore const
Ragione ho a odiarlo....

Il fatto che si connetta oppure no...

Non lo so spiegare, mi spiace

Comunque, usa con parsimonia i test come quello che ti ho indicato io

Sembra (grazie al lavoro di cotestant) che l'implementazione e l'uso di String negli esp siano fatti bene
Però che "anche" il casting implicito di variabili sia 'failure safe' non ci giurerei

Adesso si connette bene :slight_smile:
Grazie a tutti!

Non riuscivo a capire perché l'ultima versione del programma ma dava sempre l'orario indietro di un'ora, mentre una versione precedente funzionava sempre!...
Alla fine ho scoperto in Setting timezone with setenv doesn't work properly any more with V 2.7.1 · Issue #7353 · esp8266/Arduino · GitHub che facendo solo così funziona:

#define TZ "CET-1CEST,M3.5.0/2,M10.5.0/3"

configTime(TZ, "it.pool.ntp.org", "time.nist.gov");

Ma non ho capito perché in quella versione dava problemi, visto che i parametri erano gli stessi. In un sito si parla di incompatibilità fra due versioni del core ESP-12 ma, a quanto pare, c'è anche una criticità, perché basta qualcosa di insignificante per non far funzionare il sistema con setenv... :frowning:

Funziona!
Un breve video:

Adesso ho velocizzato la commutazione e impiega veramente pochi secondi. Farò un altro video.

Devo dire che la commutazione delle reti funziona molto meglio di quella di Windows 10, che durante queste prove rimane sempre disconnesso! >:(

v3.4a:

#include <ESP8266WiFi.h> // URL aggiuntivo per il gestore schede: http://arduino.esp8266.com/stable/package_esp8266com_index.json
#include <SPI.h> // Mi sembra che funzioni anche senza...
#include <Adafruit_GFX.h> // Usato da Max72xxPanel
#include <Max72xxPanel.h> // Installare da zip: https://github.com/markruys/arduino-Max72xxPanel
#include <time.h>

#define TZ "CET-1CEST,M3.5.0/2,M10.5.0/3"

/*
Sull'ora legale: https://forum.arduino.cc/index.php?topic=643074.0
Per l'Italia/Roma:
CET-1CEST,M3.5.0/2,M10.5.0/3

CET = lo Standard Time quando non è presente l'ora legale (Central Europan Time)
-1 = indica 1 ora a Est di Greenwich (quindi CET = GMT+1 = UTC+1)
CEST = lo Standard Time quando è presente l'ora legale (Central Europan Summer Time) con spostamento di 1 ora (default)

M3.5.0 = quando inizia l'ora legale, ossia a Marzo (3) nell'ultima (5) Domenica (0)
/2 = l'ora locale di quando inizia l'ora legale (le 2 di notte)

M10.5.0 = quando termina l'ora legale, ossia a Ottobre (10) nell'ultima (5) Domenica (0)
/3 = l'ora locale di quando termina l'ora legale (le 3 di notte)

Il (5) è inteso come ultima settimana.
Mese.Settimana.Giorno/Ora
Mese va da 1 a 12
Settimana va 1 a 5 (con 5 si intende sempre l'ultima settimana, indipendentemente da quante ce ne sono in quel mese)
Giorno va da 0 a 6 (0=domenica)
*/

/* 1 */ char *ssid1 = "ReteMiaTP";  char  *pwd1 = "Pippo";
/* 2 */ char *ssid2 = "Retemia A5"; char  *pwd2 = "Pippo";
/* 3 */ char *ssid3 = " ";          char  *pwd3 = " ";
/* 4 */ char *ssid4 = " ";          char  *pwd4 = " ";
/* 5 */ char *ssid5 = " ";          char  *pwd5 = " ";
/* 6 */ char *ssid6 = " ";          char  *pwd6 = " ";
/* 7 */ char *ssid7 = " ";          char  *pwd7 = " ";
/* 8 */ char *ssid8 = " ";          char  *pwd8 = " ";
/* 9 */ char *ssid9 = " ";          char  *pwd9 = " ";

char id[30];

unsigned long t_scan=0; // Per il conteggio del tempo tra una scansione e l'altra della rete (che impiega 2s) durante il loop
int periodo_scan=5000; // Periodo di scansione se c'è già stata una prima conessione
byte prima_conn_ok=0;
byte scan_fatta=0; // Va a 1 dopo aver fatto la scansione ai primi secondi del minuto, per non ripeterla ogni 2s per 10s.
time_t adesso=0;


int numberOfHorizontalDisplays = 8;
int numberOfVerticalDisplays   = 1;
char time_value[20];

// LED Matrix Pin -> ESP8266 Pin
// Vcc            -> 3v  (3V on NodeMCU 3V3 on WEMOS)
// Gnd            -> Gnd (G on NodeMCU)
// DIN            -> D7 (MOSI) (Same Pin for WEMOS)
// CS             -> D4  (Same Pin for WEMOS) D1mini: GPIO2
// CLK            -> D5 (Clk)  (Same Pin for WEMOS)

byte pinCS=2;
Max72xxPanel matrix=Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

unsigned long t_int; // Temporizzazione per la lettura del potenziometro per la regolazione della luminosità.
byte P=5; byte L=7; // POSIZIONE DELL'ORARIO NEL LOOP
time_t t_prec;


void WiFiScan()
{
byte n_ssid;
int n=WiFi.scanNetworks();
if(prima_conn_ok) scrive_orario();
memset(id,'\0',sizeof(id));
for (byte i=0; i<n; ++i) // WiFi.SSID(i) è un oggetto String, che deve essere convertito per poter essere conrontato con un char*.
  {     
  strcpy(id, WiFi.SSID(i).c_str());
       if (!strcmp(id,ssid1)) {WiFi.begin(ssid1, pwd1); n_ssid=1; break;}
  else if (!strcmp(id,ssid2)) {WiFi.begin(ssid2,pwd2); n_ssid=2; break;}
  else if (!strcmp(id,ssid3)) {WiFi.begin(ssid3,pwd3); n_ssid=3; break;}
  else if (!strcmp(id,ssid4)) {WiFi.begin(ssid4,pwd4); n_ssid=4; break;}
  else if (!strcmp(id,ssid5)) {WiFi.begin(ssid5,pwd5); n_ssid=5; break;}
  else if (!strcmp(id,ssid6)) {WiFi.begin(ssid6,pwd6); n_ssid=6; break;}
  else if (!strcmp(id,ssid7)) {WiFi.begin(ssid7,pwd7); n_ssid=7; break;}
  else if (!strcmp(id,ssid8)) {WiFi.begin(ssid8,pwd8); n_ssid=8; break;}
  else if (!strcmp(id,ssid9)) {WiFi.begin(ssid9,pwd9); n_ssid=9; break;}
  }
  delay(1000);
  configTime(TZ, "it.pool.ntp.org", "time.nist.gov");
  //configTime(0*3600, 0, "it.pool.ntp.org", "time.nist.gov"); 
  matrix.fillScreen(LOW);
  if (n_ssid<10) {matrix.drawChar(30,0,48+n_ssid,HIGH,LOW,1); matrix.write(); delay(500);}
  // matrix.drawChar(30,0,48+n_ssid,HIGH,LOW,1); matrix.write(); delay(500);
  //setenv("TZ", TZ, 3);
  tzset();
}

void scrive_orario()
{
time_t now = time(nullptr); // Facendo now variabile globale, perdeva il fuso orario.
adesso = time(nullptr);
if (now!=t_prec)
  {
  t_prec=now;
  matrix.fillScreen(LOW);
  String time = String(ctime(&now));
  time.trim();
  time.substring(11,19).toCharArray(time_value, 10);
  // Visualizza lo '0' iniziale prima delle ore 9.00:
  matrix.drawChar(P,0,    time_value[0], HIGH,LOW,1); // H
  // Cancella lo '0' iniziale prima delle ore 9.00:
  // if(time_value[0]!='0') {matrix.drawChar(P,0,time_value[0],HIGH,LOW,1);} // H
  matrix.drawChar(P+L,  0,time_value[1], HIGH,LOW,1); // _H  
  matrix.drawChar(P+L*2,0,time_value[2], HIGH,LOW,1); // __:
  matrix.drawChar(P+L*3,0,time_value[3], HIGH,LOW,1); // ___M
  matrix.drawChar(P+L*4,0,time_value[4], HIGH,LOW,1); // ____M
  matrix.drawChar(P+L*5,0,time_value[5], HIGH,LOW,1); // _____:
  matrix.drawChar(P+L*6,0,time_value[6], HIGH,LOW,1); // ______S
  matrix.drawChar(P+L*7,0,time_value[7], HIGH,LOW,1); // _______S
  matrix.write(); 
  }
}


void setup()
{
//  Serial.begin(9600);
WiFiScan();
matrix.setIntensity(0); // Use a value between 0 and 15 for brightness
matrix.setRotation(0, 1);    // Il 1° display è ruotato
matrix.setRotation(1, 1);    // Il 2° display è ruotato
matrix.setRotation(2, 1);    // Il 3° display è ruotato
matrix.setRotation(3, 1);    // Il 4° display è ruotato
matrix.setRotation(4, 1);    // Il 5° display è ruotato
matrix.setRotation(5, 1);    // Il 6° display è ruotato
matrix.setRotation(6, 1);    // Il 7° display è ruotato
matrix.setRotation(7, 1);    //  L'8° display è ruotato
matrix.fillScreen(LOW);
matrix.write();
byte P=16; byte L=7; // Variabili locali per la posizione della scritta Wi-Fi
while (WiFi.status()!=WL_CONNECTED)
  {
  matrix.drawChar(P,    0, 'W', HIGH,LOW,1); // H
  matrix.drawChar(P+L,  0, 'i', HIGH,LOW,1); // HH  
  matrix.drawChar(P+L*2,0, '-', HIGH,LOW,1); // HH:
  matrix.drawChar(P+L*3,0, 'F', HIGH,LOW,1); // HH:M
  matrix.drawChar(P+L*4,0, 'i', HIGH,LOW,1); // HH:MM
  matrix.write(); // Send bitmap to display
  WiFiScan();
  delay(1500);
  matrix.fillScreen(LOW); // Cancella i display per far lampeggiare la scritta
  matrix.write();
  delay(1500);
  }
}

void loop()
{
if(millis()-t_int>200) {t_int=millis(); matrix.setIntensity(map(analogRead(0),0,1024,0,12));} // Ogni 200ms legge il potenziometro. 
scrive_orario();
if (WiFi.status()!=WL_CONNECTED) // Non connesso
  {
  matrix.drawChar(P+L*8-1,0,'°', HIGH,LOW,1);
  matrix.write(); // Send bitmap to display
  // if (((adesso%100)/10==0 || (adesso%100)/10==3) && scan_fatta==0) {scan_fatta=1; WiFiScan();} // Se i secondi iniziano per 0 o 3, fa la scansione per cercare un'altra rete.
  if (millis()-t_scan>10000 && scan_fatta==0) {t_scan=millis(); scan_fatta=1; WiFiScan();}
  else scan_fatta=0;
  }
else prima_conn_ok=1;
}

gpb01:
In realtà, se guardi la classe String, scopri che tutte le stringhe hanno un metodo nomeStringa.c_str()

Ah si, vero, è che la classe String su Arduino l'ho cancellata dalla mia mente (anche se sarebbe effettivamente molto più comoda da usare...) quindi proprio non avevo pensato al metodo c_str(). :wink: