Webbino - Server web "dinamico" per Arduino

nero773:
Piuttosto vorrei capire perchè il monitor seriale non mi mostra le informazioni che mi servono ...

... nel codice ci sono i Serial.print() per cui, se il monitor seriale è aperto e la velocità è giusta, dovresti vedere quello che viene inviato ... ::slight_smile:

Guglielmo

gpb01:
... nel codice ci sono i Serial.print() ...

Ora lo vedo, ho messo il baudrate a 9600.

>nero773: Quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" (piccoli schermi) ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho troncato io i "quote" dei tuoi post qui sopra :wink:

Buonasera,
> Guglielmo ho pubblicato il quote così com'era perchè non mi sembrava così lungo, in ogni caso ne terrò conto per la prossima volta.

Riguardo allo sketch LedControl invece, lo sto guardando da ieri ed ho preparato una semplice pagina html con un tasto. Mi sfugge però dove si trova la pagina che attualmente viene caricata dal web server. Ho provato a modificare quella inclusa nella libreria (cartella webroot) pensando che volta per volta carichi quella, compilare e ricaricare lo sketch ma ricarica sempre quella dell'esempio.
Ho visto che Lo sketch carica il file html.h, ma come converto la mia pagina html?

EDIT: ho visto che nella cartella tool c'è lo script python che dovrebbe convertire l'html in C. E' possibile che non funzioni? E' più probabile che sbaglio qualcosa, ma cosa?

1. metti la tua pagina html in una cartella (lui le chiama sempre webroot, ma non è importante).

2. nella cartella tools della libreria, trovi un programma python di nome html2h.py
L'attuale versione gira con python 2.x, dalla prossima sarà obbligatorio avere python 3.x

3. nei commenti del sorgente del programma python c'è la sintassi da usare per trasformare la/le proprie pagine che stanno nella cartella di cui al puno 1. nel file html.h. In pratica basta lanciare (da riga comando):

html2h.py webroot > html.h

... ovvero il programma, la cartella della/e pagine e reindirizzare l'uscita sul file html.h che così viene creato.

Nei messaggi che da il suddetto programma c'è anche il pezzo di codice che occorre mettre nel sorgente .ino (che, per la pagina di esempio, trovi già in LedControl) ... gaurdati bene il tutto :slight_smile:

Guglielmo

Ciao Guglielmo, di seguito l'output, mi dice che non c'è phython, ma l'ho installato (3.8 ). Ora provo con la versione 2.

C:\Users\Fabio\Documents\Arduino2\arduino-1.8.13\portable\sketchbook\LedControl>html2h.py webroot > html.h
Python non trovato; Esegui senza argomenti per installare da Microsoft Store o disabilitare il collegamento da impostazioni > Gestisci app Alias di esecuzione.

Dal pannello di python 3.8 mi da errore di sintassi.

Come detto l'attuale versione gira con python 2 (io la uso con il 2.7.16), mentre la nuova la uso con python 3 (versione 3.8.3) e ... non ci sono errori. :slight_smile:

Guglielmo

Infatti ora con la versione 2.7.18 funziona perfettamente. :slight_smile:
Un altro passo è fatto. Sempre gentile Guglielmo. Grazie

@nero773: Dato che stai facendo i primi passi con Webbino, sei la persona ideale per "collaudare" il tutorial/documentazione che ho appena scritto.

È ancora molto grezzo, ma dovrebbe essere comunque utile. Lo trovi qui.

Nota che è basato sulla prossima versione, che rilascerò a brevissimo (quante volte l'ho già detto? :D), quindi troverai sicuramente delle differenze ma dovrebbe comunque essere indicativo.

Ovviamente ogni commento è ben accetto :).

@Sukkopera sono felice di aiutarti, lo leggerò domani.

>SukkoPera Ho letto il tutorial, devo dire che è molto dettagliato. Penso che sia molto utile, soprattutto per un principiante (come me), consultarlo nel momento in cui si incontrano problemi o mentre si testano gli esempi per capire il funzionamento della libreria.
Sinceramente alcune cose non mi sono ancora chiare, ma per un qualsiasi informatico/programmatore saranno sicuramente dalle banalità è normale, capire come funziona la programmazione non è una passeggiata.
Se posso chiedo dei chiarimenti, nel momento in cui si ha una scheda senza SD (p.e. ESP32), e si vuole caricare il programma nell'ESP32 stesso, il codice seguente va omesso ?

Serial.print (F("Initializing SD card..."));
if (!sdStorage.begin (SD_SS)) {
	Serial.println (F(" failed"));
	while (42)
		;
}
webserver.addStorage (sdStorage);
Serial.println (F(" done"));

La funzione Page Function limita ad 1 i pulsanti/tasti che possono essere messi in una pagina? Se si dovesse avere la necessità di mettere più pulsanti?

Spero di esserti stato utile. Buona serata

Grazie per avergli dato un'occhiata. Se pensi che ci sia qualcosa che posso rendere più chiaro, dimmi pure.

Se sei su una scheda senza SD, perché prendi del codice dall'esempio SDOnly? :slight_smile: Parti da SimpleServer.

Quanto alla Page Function, non limita niente, sei libero di fare tutto quello che vuoi nella funzione, e dunque gesitre tutti i pulsanti che vuoi.

Se pensi che ci sia qualcosa che posso rendere più chiaro, dimmi pure.

Forse è proprio la parte della page function che non riesco ad afferrare. Quello che ho capito, da profano quale sono, è che la richiesta di apertura di quella pagina causa l'accensione del LED:

http://10.0.0.1/index.html?state=on

Invece (presumo che) il seguente codice si occupa di inviare al browser tutti gli stati delle variabili associate ad animazioni sulla pagina interessata, solo quando questa viene richiesta.

HttpStatusCode ledToggle (HTTPRequestParser& request) {
	char *param;

	param = request.get_parameter (F("state"));
	if (strlen (param) > 0) {
		if (strcmp_P (param, PSTR ("on")) == 0) {
			ledState = true;
			digitalWrite (ledPin, LED_ACTIVE_LEVEL);
		} else {
			ledState = false;
			digitalWrite (ledPin, !LED_ACTIVE_LEVEL);
		}
	}

	return HTTP_OK;
}

Conseguentemente, cosa scatena la lettura dello stato di eventuali pulsanti barre o selettori?

nero773:
Conseguentemente, cosa scatena la lettura dello stato di eventuali pulsanti barre o selettori?

Nulla, tu devi preparare la tua pagina inserendo praticamente un "form" che, quando premi il tasto "send" viene inviato.
Nel "form" HTML puoi avere campi di testo, bottoni, ecc. ecc. tu riempi il tutto e poi invvi con un bottone "send" (o simile).

Però questo NON è webbino, queste sono le basi di come funziona HTML ed il metodo GET ... magari è meglio che approfondisci questi argomenti ... :wink:

Guglielmo

Esatto, e la funzione ledToggle(), essendo la Page Function associata a index.html, viene chiamata quando il browser richiede tale pagina e si occupa di processare quel che l'utente ha inserito nel form e accende/spegne il led di conseguenza.

>SukkoPera ho visto nel tuo esempio LedControl della vecchia versione della libreria Webbino che la pagina html ha un unico form. La pagina che ho creato io per il mio utilizzo ha diversi form, ognuno assegnato ad un tasto e altri form nei quali cambia il colore di fondo in funzione di una variabile su ESP32. In sostanza ho dei pulsanti che comandano dei led, quando il led è acceso mi colora di giallo lo sfondo della cella dove è presente il tasto che altrimenti sarebbe grigia. Per il funzionamento di Webbino, è meglio avere un form che contiene tutti i pulsanti/animazioni o va bene come l'ho creato io?
E' un pò la stessa cosa che mi ha spiegato Guglielmo nel precedente post. Sembra che Webbino sia strutturato diversamente da come me lo aspettavo e non sia adatto a fare quello che vorrei farci.

>Guglielmo so che devo studiare, faccio il possibile nel (poco) tempo libero che ho. Occorre avere pazienza.

Webbino è strutturato per chiamare una tua funzione. Nella tua funzione, ribadisco, sei libero di fare quel che ti pare e piace, anche gestire i dati provenienti da form diversi, devi solo organizzarti per farlo. Mi vengono in mente due modi:

  1. Ogni form ha come action una pagina diversa, quindi a quel punto nella PF associata a tale pagina avrai sempre e solo da processare i dati di quel singolo form. Brutto perché devi avere un sacco di pagine.

  2. Ogni form ha un campo hidden con lo stesso nome e valore diverso, tipo:

<input type="hidden" id="form_id" value="form1" />

Un altro:

<input type="hidden" id="form_id" value="form2" />

E così via. A questo punto nella PF puoi facilmente capire quale form è stato cliccato:

char *form_id = request.get_parameter (F("form_id"));
if (strcmp_P (form_id, PSTR ("form1")) == 0) {
  // Inviato il form1
} else if (strcmp_P (form_id, PSTR ("form2")) == 0) {
  // Inviato il form2
} // ...

Spero di aver reso l'idea.

... e comunque, basta chiamare i vari campi dei form con identificativi univoci e te ne freghi da quale form arriva, sai comunque l'elemento e il contenuto.

Guglielmo

Buonasera,
mi piacerebbe essere certo della fattibilità di quello che ho in testa di fare, di seguito lo sketch (va adattato all'ESP32) col quale vorrei comandare diversi punti luce in casa (24VDC) tramite pulsanti fisici, questo sketch fa accendi spegni con un click, poi, solo da luce accesa tenendo premuto avvia il fade che si ferma al rilascio del pulsante.

int PINpb1 = 2;
int LED1 = 3;
bool StatoPB1 = LOW;
bool onClick1 = LOW;
bool StatoPB1old = LOW;
volatile int Step1 =0;
int lumin1 = 0;
int increm = 2;
unsigned long Tpress1 = 0;


void setup() {
  Serial.begin(9600);
  pinMode(PINpb1, INPUT);
  pinMode(LED1, OUTPUT);
}

void loop() {
  Serial.print ("Click=  ");
  Serial.print (onClick1);
  Serial.print ("/    Step1=  ");
  Serial.println (Step1);
  StatoPB1 = digitalRead (PINpb1);
  analogWrite(LED1, lumin1);
    
  switch (Step1){
    case 0: Spento1(); break;
    case 1: Acceso1(); break;
  }
  if ((StatoPB1 == HIGH) && (StatoPB1old == LOW)) {
    unsigned long tempoH = millis();
    StatoPB1old = StatoPB1;
    Tpress1 = tempoH;}
   
  else if ((StatoPB1 == LOW) && (StatoPB1old == HIGH)) {
   unsigned long tempoL = millis();
   StatoPB1old = StatoPB1;
   Serial.print ("Tempo on  ");
   Serial.println (tempoL - Tpress1);
   if ((tempoL - Tpress1) <= 2000) {
     onClick1 = HIGH;
     Serial.print ("/    onClick1=  ");
     Serial.println (onClick1);
     Tpress1 = tempoL;}
  }
}

void Spento1() {
  if (onClick1) {
    Step1 = 1;
    lumin1 = 200;
    onClick1 = LOW;
  }
}

void Acceso1() {
  if (onClick1) {
        Step1 = 0;
        lumin1 = 0;
        onClick1 = LOW;
   }   
  else if (StatoPB1 && (millis() - Tpress1 > 2000)) {
    Fade();   
   } 
}       
void Fade() {
  bool fadePause;
  int t1 = 0;
  Serial.println ("/  FADING  ");
  if (StatoPB1) {
    
    if (!fadePause) {
      lumin1 = lumin1 + increm;
      if (lumin1 <= 0 || lumin1 >= 255) {
        increm = -increm;
        fadePause =1;
        t1 = millis(); 
      }
   }
  if (fadePause && (millis()-t1 > 50)) {
    fadePause = 0;
  }
}
}

Tramite Webbino vorrei mettere in parallelo ai pulsanti fisici quelli sul browser solo però con la funzione accendi/spegni (no fade).
Vorrei capire se ho scelto una strada praticabile (da me) o se è meglio usare Blink, probabilmente più alla mia portata (in tempi ragionevoli).
Ho allegato anche la pagina html (modificando l'estensione in txt per poterlo allegare) dove ho inserito alcuni pulsanti e sto tentando di capire come rendere dinamico il colore di fondo della cella attorno al pulsante in funzione delle variabili di stato dei led(GET) .
Se avete anche suggerimenti per semplificare il lavoro sono benaccetti

index.txt (3.18 KB)

A fare, si può fare sicuro, e non è nemmeno particolarmente difficile secondo me. Per cambiare il colore devi usare un Replacement Tag, ovviamente.