Buonasera. Sto utilizzando arduino YUN. Con il codice postato sotto ho problemi con l'esecuzione del comando "Cancello/ApriEBlocca" in quanto nel browser non mi viene restituita la risposta "Apertura cancello eseguita.". Credo sia dovuto al delay di 23000ms che devo per forza di cose tenere. Se allungo il timeout del client non funziona comunque. anzi addirittura non mi funziona più nemmeno il comando "Cancello/Apri" che ora funziona.
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
// array per la gestione dello stato dei pin
const int GateReleControlPin = 8;
const String gateDevice = "Cancello";
// Instanzia oggetto server
YunServer server;
YunClient client;
void setup()
{
// Pin uscite rele'
pinMode(GateReleControlPin,OUTPUT);
digitalWrite(GateReleControlPin,HIGH);
Bridge.begin();
server.listenOnLocalhost();
server.begin();
}
void loop()
{
// Lo scketch si mette in attesa di messaggi entranti attivando un client verso Yunserver
client = server.accept();
// Nuovo messaggio in arrivo?
if (client)
{
// Richiamo funzione process() per gestire il messaggio
process(client);
// Alla fine chiude il client
client.stop();
}
delay(50); // Un attimo di pausa
}
void process(YunClient client)
{
String command = client.readString();
command.replace("\r\n", "");
Console.println(command);
if(command == "Cancello/ApriEBlocca")
{
execCommand(gateDevice,"ApriEBlocca","");
client.print("Apertura e blocco cancello eseguita.");
}
if(command == "Cancello/Apri")
{
execCommand(gateDevice,"Apri","");
client.print("Apertura cancello eseguita.");
}
}
void execCommand(String device,String param1,String param2)
{
//controllo il device da gestire
if (device == gateDevice)
{
//controllo che comando eseguire
if (param1 == "Apri")
{
digitalWrite(GateReleControlPin,LOW);
delay(100);
digitalWrite(GateReleControlPin,HIGH);
}
if (param1 == "ApriEBlocca")
{
digitalWrite(GateReleControlPin,LOW);
delay(100);
digitalWrite(GateReleControlPin,HIGH);
delay(23000);
digitalWrite(GateReleControlPin,LOW);
delay(100);
digitalWrite(GateReleControlPin,HIGH);
}
}
}
Ciao Stè, non ho letto il codice nel dettaglio ma un delay() lo puoi sostituire con un millis() ottenendo il vantaggio che il codice non si blocca (da modificare il codice....)
Probabilmente, essendo la stampa "Apertura e blocco cancello eseguita." subordinata a if(command == "Cancello/ApriEBlocca"), con il delay così lungo command torna a nullo e quando riesegue il loop non entra nell'if
Ho visualizzato sulla console la variabile command dopo il ritardo di 23000ms ed è valorizzata. Inoltre
client.print("Apertura cancello eseguita.");
è all'interno dell' if quindi anche se si azzerasse dovrebbe comunque fare il print in quanto sono dentro all'if.
Sembrerebbe proprio un problema della variabile "client". Questo però starebbe a significare che non posso fare elaborazioni lunghi lato arduino, se devo avere un ritorno e questo mi pare strano.
In alternativa dovrei inserire sulla pagina html un timer javascript che interroghi arduino per sapere se l'operazione è terminata.
... guarda, la memoria potrebbe tradirmi e potrei dire una stupidaggine, ma mi pare che il protocollo HTTP abbia un timeout per la "sessione" ... ovvero se apri una "sessione" e non la chiudi in un tempo X ... la sessione viene "abortita".
Ripeto, è un vago ricordo ... però lo status code 408 recita: The server timed out waiting for the request. According to HTTP specifications: "The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."
Eh no ste... non così... hai sostituito un delay con un altro delay: il programma comunque si blocca li per 23 secondi!
Il programma NON deve fermarsi li ma deve proseguire e ricominciare il loop in modo da far lavorare bene il tutto.
Lì devi solo testare una variabile "millis_inizio" con millis() e se millis()-millis_inizio > 23000
Il "trucco" sta nel valorizzare correttamente millis_inizio
EDIT: mi spiego meglio.....
Potresti quando:
if (param1 == "ApriEBlocca"){
digitalWrite(GateReleControlPin,LOW);
delay(100);
digitalWrite(GateReleControlPin,HIGH);
millis_inizio=millis();
apEb = 1;
param1 =""; // la resetto.... non mi serve più
}
Ho provato a sostituire il delay come mi hai suggerito, ma comunque non ottengo risposta sul browser.
A questo punto mi pare di capire che l'unico modo è quello di richiedere lo stato del processo con uno script javascript che gira nella pagina html.