[Risolto]Cronotermostato con esp8266-01s comandato da BOT TELEGRAM

Nessun disturbo, tranquillo,è un piacere

Però guardò e riguardo e non capisco

Te pensa che il messaggio di errore "mancata connessione in trasmissione" non lo ho mai ricevuto

Non mi ha mai perso un colpo...

Ci penso stanotte

abbamo provato anche noi, con il programma di @amedeo ide 1.8.10 non va, mancata connessione in trasmissione, confermiamo

BTW anche a me fa la storia di trovare più di una libreria che invece so essere singola

naturalmente abbiamo importato e messo nel path le tre librerie di @Standard

Devo purtroppo confermare

anche a me, con la 1.8.10 su ubuntu 18.04 x64 fa "mancata connessione in trasmissione"

sullo stesso sistema operativo IDE1.8.5, lo stesso programma con le stesse 3 librerie "private" funziona regolarmente

provo a vederci dentro.......

C'è qualcosa di sbagliato nell'IDE 1.8.10

non è solo che trova doppie librerie ma anche che NON usa le librerie corrette mi spiego: ho cambiato la scritta d'errrore nella mia newtelegrambot da "mancata connessione in trasmissione" a "Mancata Connessione in Trasmissione" invece nella installazione 1.8.5 ho scritto "Trasmissione mancata, nessuna connessione"

inoltre ho cambiato la scritta di versione da "#define VERSIONE "ZZ-esempio Zibellino Zootecnico" // Versione commentata da postare come esempio" a "#define VERSIONE "ZZ-esempio Zibellino ZOOtecnico" // Versione commentata da postare come esempio"

guardate cosa mi esce nel monitor seriale, dopo aver compilato e trasferito

Connessione al wifi: xxxxxxxxxxxxxxx ...... Maggiordomo Automatico Mt Metula Versione: ZZ-esempio Zibellino ZOOtecnico Connesso: IP: 192.168.1.69 Mancata connessione in trasmissione

Mescolando scritte prese chissa' da dove, e che non ci sono nei sorgenti, boh, ci penso ancora, ma per me squadra che vince non si cambia, tengo la 1.8.5.......

come volevasi dimostrare, tornato sulla 1.8.5 funziona tutto e la scritte sono congrue coi sorgenti da dove dovrebbero provenire

quindi per il momento mi fermo, non ho soluzione se non dire: compila su 1.8.5, li va

Trovata documentazione su gitub
da un paio d’anni sono cambiati dei default di esp88266 wificlientsecure

la libreria che usava lo OP è aggiornata
io sto passando solo adesso a 1.8.10 e quindi ho scopeto con dispiacere la cosa
ecco come e che librerie includere nel preambolo

// Nelson StandardOil
// per non dimenticare i gravi disastri petroliferi
// progetto "Metula"
// Petroliera - Stretto di Magellano - 9 agosto 1974 - 51.000 tonnellate
// un telegrambot per accendere spegnere una caldaia
// VZZ Versione senza password, e molto commentata, da dare come esempio




#define PROGETTO "Mt Metula"
#define VERSIONE "ZZ-esempio Zibellino ZOOtecnico" // Versione commentata da postare come esempio

// variabili globali e librerie

// generiche
#include <nelson.h>

//----------
#define USING_AXTLS
#include <ESP8266WiFi.h>
#include "WiFiClientSecureAxTLS.h"
using namespace axTLS;
//-------

#include "new-wifi-connect.h"

da qui è tutto uguale

provato adesso e va
mi spiace, ma non avevo idea che avrebbero aggiornato le librerie senza garantire la compatibilità

e comunque anche dopo aver fisicamente cancellato le altre installazioni di arduino, comunque segala di aver trovato doppie librerie, anche della mia nelson.h che esiste in una sola copia nel file-system (per sicurezza ho anche rimosso il link simbolico che avevo creato per includere direttamente i CPP)
non c’è nulla da fare, alcune librerie le trova doppie…

Quandi dici che le trova doppie hanno lo stesso percorso o percorsi diversi?

A noi dice solo
“Più di una libreria trovata per <nome.h> uso …”
Che naturalmente corrisponde all’unico path esistente
Ma non mostra le inesistenti altre

OK. confermo che ora funziona, trasmette e riceve. Ora la devo adattare al mio programma e sperare che l'ESP8266 non si blocchi più provo a reinstallare l'IDE 1.8.10, avevo notato i messaggi delle doppie librerie ma li ho ignorati. GRAZIE @Standardoil per il supporto. a breve vi saprò dire se la soluzione è definitiva.

A me dice (è un esempio)

Più di una libreria trovata per "ArduinoJson.h"
Usata: D:\Programmi\arduino-1.8.10\portable\sketchbook\libraries\ArduinoJson
Non usata: D:\Programmi\arduino-1.8.10\portable\sketchbook\libraries\arduino_647813
Uso la libreria ArduinoJson alla versione 6.13.0 nella cartella: D:\Programmi\arduino-1.8.10\portable\sketchbook\libraries\ArduinoJson

La libreria non usata in realtà risulta essere una cartella con la vecchia versione probabilmente non cancellata dopo un aggiornamento.

amedeodivito: a breve vi saprò dire se la soluzione è definitiva.

Bene sono contento non mi sbilancio più con questa nuova versione ma a me maggiordomo sta funzionando ininterrottamente da 91 giorni, 9 ore e 19 minuti (più o meno da quando ho spostato tutto dalla mensola del garage dove lo avevo messo durante il trasloco alla sua nicchia del muro

se non lo spengo io e/o non manca corrente non ho mai avuto delusioni, ma adesso sapendo che le librerie sono cambiate non garantisco nulla tieni conto comunque che maggiordomo, la mia versione, gestisce (gestirebbe, non le ho più) 2 stufe a pellet, interrogandole a intervalli regolari per saperne la potenza (e da qui il consumo), cronotermostato programmabile (nel senso programmabile da telegram, intendo) estate/inverno ora solare/legale accetta comandi del tipo "gas 12.2 20.15 79500" e mi conteggia 12,2 euro di gpl 20.15 litri di gas, mi risponde col consumo medio del periodo e totale, e questo per me, per ziabbona tiene conti separati, stesso per il pestiferonipote (che non ha auto, ma vabbe) e nipotessa grande in realtà conti separati per ogni utente ma riconosce differenti account per lo stesso utente se scrivo "spendo 5 bar" mi aggiorna il conto delle spese, tenendo conto delle spese di gas e benzina (già, separato, per chi ha l'auto a gpl) permette di aggiungere/togliere utenti autorizzati da telegram, il solo utente hardcoded sono io gestisce un numero non precisato di liste di azioni ove ogni utente può aggiungre/togliere/consultare la lista una cosa del tipo: "aggiungi trasloco tavolo verde" e mi aggiunge alla lista "trasloco" il tavolo verde così che al bisogno basta fare "lista trasloco" per farsi trasmettere la lista delle cose da prelevare oppure al supermercato "lista spesa" per avere le cose da comperare i comandi sono soft-coded in un file e ne corrisponde la descrizione sicchè basta dare "lista comandi" per avere i comandi con la loro descrizione e un altro po' di cose che ora non ricordo l'inverno scorso non ha mostrato alcun malfunzionamento, 160 e passa giorni on line quindi direi che eliminare gli oggetti String sia stato un buon affare........

zoomx: A me dice (è un esempio)

a me no, in realtà non dice nulla, se la compilazione va a buon fine non ho errori di libreria

se invece non va a buon fine (ho dovuto togliere un ; per far abortire la compilazione dice:

Più di una libreria trovata per "nelson.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/Nelson
Più di una libreria trovata per "ESP8266WiFi.h"
Usata: /home/max/1.8.10Standard/portable/packages/esp8266/hardware/esp8266/2.6.3/libraries/ESP8266WiFi
Più di una libreria trovata per "OneWire.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/OneWire
Più di una libreria trovata per "DallasTemperature.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/DallasTemperature
exit status 1
expected initializer before 'unsigned'

come vedi non mi da indicazioni su quale sarebbe l'altra libreria ( che io sono sicuro non esista, ho una sola copia della nelson non solo sul file-system di root ma nemmeno nei volumi vari, che comunque ho preventivamente smontato) non parliamo poi di OneWire o Dallas etc etc che sono installate dal gestore di libreria......

PS per "gli uomini della Fondazione" stesso messaggio anche per voi?

File/Impostazioni mettere la spunta in Mostra un output dettagliato durante la compilazione

Più di una libreria trovata per "nelson.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/Nelson
Più di una libreria trovata per "ESP8266WiFi.h"
Usata: /home/nelson/1.8.10Standard/portable/packages/esp8266/hardware/esp8266/2.6.3/libraries/ESP8266WiFi
Più di una libreria trovata per "OneWire.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/OneWire
Più di una libreria trovata per "DallasTemperature.h"
Usata: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/DallasTemperature
Uso la libreria Nelson nella cartella: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/Nelson (legacy)
Uso la libreria ESP8266WiFi alla versione 1.0 nella cartella: /home/nelson/1.8.10Standard/portable/packages/esp8266/hardware/esp8266/2.6.3/libraries/ESP8266WiFi 
Uso la libreria OneWire alla versione 2.3.5 nella cartella: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/OneWire 
Uso la libreria DallasTemperature alla versione 3.8.0 nella cartella: /home/nelson/1.8.10Standard/portable/sketchbook/libraries/DallasTemperature 
/home/nelson/1.8.10Standard/portable/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/xtensa-lx106-elf-size -A /tmp/arduino_build_670198/metula-00.ino.elf
Lo sketch usa 341116 byte (32%) dello spazio disponibile per i programmi. Il massimo è 1044464 byte.
Le variabili globali usano 29092 byte (35%) di memoria dinamica, lasciando altri 52828 byte liberi per le variabili locali. Il massimo è 81920 byte.

continua a non mostrare dove sarebbero le altre trovate

Standardoil: PS per "gli uomini della Fondazione" stesso messaggio anche per voi?

Stesso tipo di errore stiamo pensando che forse non sia un vero problema, ma un semplice contrattempo

Codice e librerie post#10 metto tutto nella stessa cartella
Correzioni post#20

cambio
#include <nelson.h> in #include “nelson.h”

Compilo, nessun errore e scopro già che il core ESP8266 effettivamente non ti dice dove sono le librerie duplicate mentre quello AVR si.

Più di una libreria trovata per "ESP8266WiFi.h"
Usata: D:\Programmi\arduino-1.8.10\portable\packages\esp8266\hardware\esp8266\2.6.3\libraries\ESP8266WiFi
Più di una libreria trovata per "OneWire.h"
Usata: D:\Programmi\arduino-1.8.10\portable\sketchbook\libraries\OneWire
Più di una libreria trovata per "DallasTemperature.h"
Usata: D:\Programmi\arduino-1.8.10\portable\sketchbook\libraries\DallasTemperature

Ed effettivamente i messaggi di librerie duplicate sembrano fasulli.
Uso la portable dove cerco DallasTemperature.h e ne trovo solo uno
OneWire.h effettivamente ce ne sono due l’altro è presente nel core digistump che però non dovrebbe essere visto dal core ESP8266.
Un solo ESP8266WiFi.h

A questo punto dovrebbe trattarsi di un problema di interazione dell’IDE con il core.

per lo OP dai che sono curioso, ha passato la notte?

Siiii, funziona tuttora;
l’ho adattato al mio programma eliminando tutte le Serial.print e lasciando solo quella per inviare il comando al’STM32. (forse se utilizzavo solo un nodemcu mi sarebbe bastato, ma così si presta a future espansioni).
nel loop ho eliminato il tuo sistema di temporizzare i botread() e l’ho forzato a 1 sec. perchè era piuttosto lento.
Ho aggiunto l’HW WDT (una mia fissa).

invio lo sketch modificato.
Grazie ancora.

#include "nelson.h"
#define USING_AXTLS
#include <ESP8266WiFi.h>
#include <WiFiClientSecureAxTLS.h>
using namespace axTLS;

#define LED 2
#define PROGETTO "CRONOTERMO"
#define VERSIONE "V.1.0 Alfa"

char ssid[] = "#########";
char password[] = "##########";
char token[] = "####################################";
#include "newtelegrambot.h"

uint32_t utente  = 0;         // la tua ID di aministratore del BOT
unsigned long int ultimaazione;       // tempo di quando è stata eseguita l'ultima azione
unsigned long int passo = 1;          // tempo da attendere tra una interrogazione Telegram e la successiva

void setup() {
  delay(1000);
  Serial.begin(115200);
  pinMode(LED, OUTPUT);
  ESP.wdtDisable();                                              // disabilita SW WDT
  collegaalwifi(ssid, password);
  delay(0);                                                      // alimenta HW WDT
  botopen(utente); // botopen(utente) inizia un messaggio Telegram verso utente
  telegrambot.print(PROGETTO);
  telegrambot.print(F(" avviato.%0AVersione: ")); // %0A è il ritorno a capo, usare un println() chiuderebbe il messaggio
  telegrambot.print(VERSIONE);
  botclose(); // chiude il messaggio e ne provoca l'inoltro
  delay(0);                                                                                     // alimenta HW WDT
  botread(); // una (serie di) botread() a vuoto svuotano l'eventuale coda di messaggi in ingresso che non sono ancora stati ricevuti, emessi prima dell'accensione
  while (appoggio > ultimo) { // appoggio e ultimo sono il numero id ultimo messaggio ricevuto e trattato e messaggio ricevuto
    ultimo = appoggio;
    delay(20);
    botread();
  }
}

void loop()
{
  lampeggia(1);                                                  // il led esp8266 lampeggia n volte
  chkSerial(utente);                                             // verifica disponibilita nuovo messaggio seriale da stm32f103c8t6

  // se siamo connessi e arriva un nuovo messaggio...
  if (WiFi.status() == WL_CONNECTED)
  {
    aggiorna();// aggiorna per leggere se ho un messaggio da telegram
  }
  else
  {

    collegaalwifi(ssid, password);
  }
  delay(500);
  yield();
  ESP.wdtFeed();                                                 // alimenta il watchdog
}

// ****************************************************************************************
// chkSerial() - VERIFICA/RICEVE I DATI RICHIESTI TRAMITE BOT TELEGRAM
// ****************************************************************************************
void chkSerial(uint32_t utente) {
  // se non disponibili o primo carattere diverso da "#" il flusso non e' valido
  if (Serial.available() == 0 || (Serial.available() != 0 && Serial.read() != '#')) {
    clearSerialBuffer();
    return;
  }
  char c;
  char buf[LENTEXT];
  int idx = 0;
  while (Serial.available() > 0) {
    c = Serial.read();
    if (c != '#') {                                          // esclude # iniziale  e # CRLF finale
      buf[idx] = c;
      idx++;
    }
  }
  botsend(utente, buf);                                      // e invia notifica al mittente
  clearSerialBuffer();                                       // svuota il buffer della seriale
}

// ****************************************************************************************
// clearSerialBuffer() - svuota IL BUFFER DELLA SERIALE
// ****************************************************************************************
void clearSerialBuffer() {
  char c;
  while (Serial.available() > 0) {
    c = Serial.read();
    delayMicroseconds(10000);
  }
}

// ****************************************************************************************
// lampeggia() - IL LED ESP8266 LAMPEGGIA n VOLTE
// ****************************************************************************************
void lampeggia(byte lampi) {
  for (int ciclo = 1; ciclo <= lampi; ciclo++) {
    digitalWrite(LED, LOW);
    delayMicroseconds(50000);
    digitalWrite(LED, HIGH);
    delayMicroseconds(50000);
  }
}

// ****************************************************************************************
// help() - INVIA AL MITTENTE LA LISTA DEI COMANDI
// ****************************************************************************************
void help(uint32_t utente) {
  botopen(utente);
  telegrambot.print("-- ELENCO COMANDI VALIDI --%0A");
  telegrambot.print("/info          Stato impianto%0A");
  telegrambot.print("/accendi  Accende caldaia%0A");
  telegrambot.print("/spegni     Spegne caldaia%0A");
  telegrambot.print("/tem          [99.9] Set Comfort%0A");
  telegrambot.print("/ledon       Accende display%0A");
  telegrambot.print("/ledoff      Spegne display%0A");
  telegrambot.print("/ora           [aaaa-mm-gg hh:mm:ss]");
  botclose();
}

// ****************************************************************************************
// aggiorna() - CONTROLLA SE ARRIVA  UN NUOVO MESSAGGIO E LO ELABORA
// ****************************************************************************************
void aggiorna(void)
{
  // lampeggia(1);
  botread(); // lancio la ricezione
  if (appoggio > ultimo)
  {
    // aggiorno l'ultimo messaggio ricevuto
    ultimo = appoggio;
    if (mittente == utente)
    {
      if (strlen(testo))
      {
        tratta(testo);
      }
    }
    else
    {
      botsend(mittente, "Utente non autorizzato");
    }
  }
}

// ****************************************************************************************
// tratta() - CONTROLLA SE E' UN COMANDO VALIDO
// ****************************************************************************************
void tratta(char * testo)
{
  char comando[5];
  char dati[25];
  int len = strlen(testo);
  if (len >= 4) {
    for (int i = 0; i < 4; i++) {
      comando[i] = testo[i];
    }
  }
  if (len > 4) {
    for (int i = 4; i < len; i++) {
      dati[i - 4] = testo[i];
    }
  }

  if (uguale(comando, "/inf")) {
    Serial.println(testo);     // stato dell'impianto
    return;
  }
  if (uguale(comando, "/acc")) {
    Serial.println(testo);     // accende la caldaia
    return;
  }
  if (uguale(comando, "/spe")) {
    Serial.println(testo);     // spegne la caldaia
    return;
  }
  if (uguale(comando, "/tem")) {
    Serial.println(testo);     // vista/imposta la temperatura comfort
    return;
  }
  if (uguale(comando, "/led")) {
    Serial.println(testo);     // accende/spegne il display lcd5110
    return;
  }
  if (uguale(comando, "/ora")) {
    Serial.println(testo);     // vista/imposta l'orologio del sistema
    return;
  }
  help(utente);
}

// ****************************************************************************************
// collegaalwifi() - ESEGUE IL COLLEGAMENTO ALLA RETE WIFI
// ****************************************************************************************
bool collegaalwifi(char ssid[], char password[])
{
  delay(1000);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);  // alimenta HW WDT
  }
  return (WiFi.status() == WL_CONNECTED);
}

ottimo, grazie a te il meccanismo del passo a lunghezza variabile è un po' una forzatura, lo ammetto, ma mi serviva per ridurre i consumi di banda quando........... (supercazzola precompilata) sono contento che vada, speri ti trovi bene, eventualmente si accettano sempre suggerimenti per migliorare

Buongiorno a tutti;
Dunque anche ieri notte ho ceduto alla stanchezza alle ore 3 per adattare la libreria di Nelson@Standardoil al mio programma.
Quello che desideravo era: eliminare ciò che non mi serviva ed avere la disponibilità del “first_name” prelevandolo dal flusso json, da qui il problema (secondo me) che trovandolo 2 volte mi valorizzava l’array username doppio ( nel mio caso: “AmedeoAmedeo”).
Ho speso molte energie per cercare di risolverlo e alla fine ho accettato il compromesso di creare un’array di appoggio (username_doppio) per poi valorizzare correttamente username, vedi escamotage alla fine della funzione botread().
Adesso funziona ma si accettano consigli e suggerimenti in merito.
allego lo sketch.

void botclose(int a = 0);   // protoripo della botclose, che ha argomento di default
unsigned long int ultimo;   // il numero dell'ultimo messaggio ricevuto
unsigned long int appoggio; // una variabile di appoggio
unsigned long int mittente; // il numero del mittente ultimo messaggio
unsigned long int io;       // tutti gli account di Telegram sono interi a 32 bit senza segno
unsigned long int ultimodestinatario; // ultimo destinatario
#define LENTEXT 100
char testo[LENTEXT];            // il testo appena ricevuto, massimo LENTEXT caratteri
char username[LENTEXT];         // nome utente (first_name in json)
char username_doppio[LENTEXT];  // nome utente duplicato (first_name in json)
byte lenuser = 0;               // la lunghezza del testo trovato
byte lentext = 0;               // la lunghezza del testo trovato



IPAddress telegram(149, 154, 167, 198); // ho fatto un NSlookup
#define PORTA 443
#define HOST "api.telegram.org"
// indirizzo del server e sua porta
// istanza del client
WiFiClientSecure telegrambot;



int elabora(char c)
{
  //Serial.print(c);
  // elabora char by char l'intero messaggio ricevuto da telegram
  // riconosce le coppie di parentesi graffe
  // riconosce alcuni campi
  // restituisce zero per fermare, che poi significa chiusa ultima graffa del messaggio

  static int livello = 0; // il livello di rientro delle parentesi graffe
  static int oggetto = 0; // in quale nome di oggetto siamo
#define NUMSTRINGHE  5  // e' una define solo per comodita'�di trovarla
  static char * oggetti[NUMSTRINGHE] = {"niente", "\"update_id\":", "chat\":\"id\":", "\"first_name\":\"", "\"text\":\"" };
  // vettore di puntatori a carattere
  // siccome un puntatore a carattere e' una stringa di 'C'
  // e' come fare un array di stringhe ('C' non esiste un tipo specifico stringa, quindi non sarebbe possibile un array di stringhe semplice semlice)
  // siccome restituisce l'indice devo tenere ciccato il primo elemento, altrimenti me lo riconosce e fa oggetto=0
  // che si confonde con fuori dall'oggetto
  static byte actual[NUMSTRINGHE];
  // un vettore di posizioni correnti nelle stringhe puntate dal primo vettore

  if (c == '{')
  {
    oggetto = 0;
    // conto i livelli
    livello++;
    return livello;
  }

  if (c == '}')
  {
    oggetto = 0;
    livello--;
    // oggetto=0;
    return livello;
    // se siamo a livello 0 il messaggio e' finito
  }

  // ne graffa aperta ne graffa chiusa, nel pieno del messaggio
  // devo riconoscere se stiamo leggendo il nome di un oggetto conosciuto
  if (oggetto)
  {
    // abbiamo trovato un nome di oggetto (: compreso)
    // adesso fino alla virgola o virgoletta
    // se si tratta di una virgola o virgoletta
    if (c == ',' || c == '\"')
    {
      oggetto = 0;
      // fuori dall'oggetto
      return 1;
    }
  }

  // ok non e' una virgola, ne una virgoletta
  // siamo quindi in un oggetto che voglio riconoscere

  // campi numerici, purtroppo devo saperlo io (hard coded)
  if (oggetto == 1)
  {
    // updateid = ultimo messaggio
    appoggio = appoggio * 10 + c - '0';
    // converto in intero
    return 1;
  }

  if (oggetto == 2)
  {
    // mittente
    mittente = mittente * 10 + c - '0';
    // traduco in intero (gli utenti sono sempre unsigned long
    return 1;
  }

  // campi alfabetici, username
  if (oggetto == 3)
  {
    // username
    if (lenuser < LENTEXT)
    {
      username_doppio[lenuser] = c;
      lenuser++;
      username_doppio[lenuser] = 0; // terminatore
    }
    else
    {
      oggetto = 0;
      // evito di uscire dalla stringa
    }
    return 1;
  }

  // campi alfabetici, che per ora e' solo text, corpo del messaggio
  if (oggetto == 4)
  {
    // siamo nel testo
    if (lentext < LENTEXT)
    {
      testo[lentext] = c;
      lentext++;
      testo[lentext] = 0; // terminatore
    }
    else
    {
      oggetto = 0;
      // evito di uscire dalla stringa
    }

    return 1;
  }

  // non abbiamo ancora trovato il nome di un oggetto
  // vado avanti a cercarlo
  for (byte i = 0; i < NUMSTRINGHE; i++)
  {
    //per ogni oggetto, vedo se coincide il carattere
    if (c != oggetti[i][actual[i]])
    {
      // non coincide
      actual[i] = 0;
    }

    else
    {
      // coincide
      actual[i]++;

      //avanti
      if (oggetti[i][actual[i]] == 0)
      {
        // oggetto finito stringa trovata
        actual[i] = 0; //torno indietro
        oggetto = i;
      }
    }
  }
  return 1; // OK in lettura
}



bool botopen(unsigned long int destinatario)
{
  ultimodestinatario = destinatario;

  // inizia una trasmissione al bot
  // non chiude la connessione, lascia aggiungere
  // per Telegram il messaggio viene chiuso da un fine riga (a capo)

  if (telegrambot.connect(telegram, PORTA))
  {
    telegrambot.print(F("GET /bot"));
    telegrambot.print(token);
    telegrambot.print(F("/sendMessage?chat_id="));
    telegrambot.print(destinatario);
    telegrambot.print(F("&text="));
    return true;
    // si commenta da solo
  }

  else
  {
    Serial.println(F("Mancata connessione in trasmissione"));
    return false;
  }
}

void botclose(int parsemode)
{
  // chiude la connessione
  // parse=0 per no parse
  // parse 1 per parse= Markdown
  if (parsemode == 1)
  {
    telegrambot.print(F("&parse_mode=Markdown"));
  }

  // il parametro opzionale parsemode permette di chiudere il messaggio
  // dicendo a Telegram di seguire una differente convenzione grafica
  telegrambot.println(); // il println chiude il messaggio
  delay(350); // sembra che serva un delay minimale, anche se non ne ho trovato traccia nella documentazione
}

void botsend(unsigned long int destinatario, char messaggio[])
{
  // trasmette al bot il messaggio
  // chiudendo il bot  e non lasciando aggiungere
  if (botopen(destinatario))
  {
    telegrambot.print(messaggio);
    botclose();
    // si commenta da solo
  }

  else
  {
    Serial.println(F("Errore apertura bot"));
  }
}


void botread(void)
{
  // connessione con telegram
  if (telegrambot.connect(telegram, PORTA))
  {
    telegrambot.print(F("GET /bot"));
    telegrambot.print(token);
    telegrambot.print(F("/getUpdates?offset="));
    telegrambot.print(ultimo + 1); // Telegram considera letto e quindi scarta ogni messaggio di numero < offset
    // in questa maniera avanzo di uno nella coda dei messaggi
    telegrambot.println(F("&limit=1")); // uno alla volta uno alla volta per carita.... (da: il barbiere di Siviglia)
    // resetto la variabile di appoggio che mi serve per conteggiare il valore di ultimo update ricevuto
    appoggio = 0;
    // resetto la variabile di ultimo mittente
    mittente = 0;
    // svuoto il campo username
    username[0] = 0; // basta il primo carattere, le stringhe sono terminate da 0
    username_doppio[0] = 0; // basta il primo carattere, le stringhe sono terminate da 0
    // il contatore di lunghezza di username
    lenuser = 0;
    // svuoto il campo testo
    testo[0] = 0; // basta il primo carattere, le stringhe sono terminate da 0
    // il contatore di lunghezza del testo
    lentext = 0;

    unsigned long int ora = millis();

    while (millis() - ora < 1500) // un timeout
    {
      if (telegrambot.available())
      {
        // passo alla funzione di trattamento il carattere ricevuto
        char c = telegrambot.read();

        if (!elabora(c))
        {
          break;
        }
      }
      // tentativo di dividere l'array username valorizzato doppio
      for(char x = 0; x <= (lenuser/2); x++){
        username[x] = username_doppio[x];
      }
      username[(lenuser/2)] = 0;
    }
  }
}