Problema con Web client e JavaScript

Ciao a tutti
Sono relativamente novizio con Arduino, ho seguito varie guide ed articoli ed alla fine ho realizzato, quasi totalmente, il progetto che avevo in mente, in realtà è qualcosa di semplicissimo ma… non funziona…
Brevemente è un web server che espone su una pagina web il valore del sensore di luminosità ed in più scrive la data della rilevazione e scrive le informazioni sulla sd della ethernet shield.
questo il codice

#include <String.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>
#include <Wire.h>

/* Classe per acquisizione valori dei sensori */
class Sensore {

  private:
    int lumenSensor;
    double lumen;

  public:
    boolean bReady;
    
  public:
    Sensore() { bReady = false;
    lumenSensor = 5;
    lumen = 0.0; } // constructor
    
    double readLumen(){
      return analogRead(lumenSensor);
    }  

    double getInstLumen() { return lumen; }
    int getLumenSensor(){ return lumenSensor; };
    void setInstLumen(double lm) { lumen=lm; }
};

// impostazione indirizzi MAC e IP dell'Ethernet Shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {192,168,2, 177 };
const int chipSelect = 4;
const int SDpin = 10;

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
String data ="";

// server in ascolto sulla porta 80 (default per il protocollo HTTP):
Server server(80);
String readString;
Sensore sensore;
boolean currentLineIsBlank = true;
int val;

/************** Client functions ************/
// predispone la visualizzazione della pagina html
void printHeader(Client c )
{
  c.println("HTTP/1.1 200 OK");
  c.println("Content-Type: text/html");
  c.println();
  c.print("<html><head><title>STATION</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
  c.println("<center><h1> Station</h1></center>");
  c.println("
");
  c.println("<hr />");
}

void printMenu(Client c )
{
  c.print("<center><h4><a href='/?L=1'>Leggi sensori</a> | <a href='/?L=4'>Salva su SD</a></h4></center>");
}


void stampaValori(Client client){
     printHeader(client);
     printMenu(client); 
     client.print("Luminosita ");
     client.println(sensore.getInstLumen());
     client.println("
");
     client.println("
");
     client.println("data: " + data + "
");
}

/************** END Client functions ************/

/*********** SD FUNCTIONS **************/

void leggiSD(Client client){
    File dataFile = SD.open("datalog.txt");
    // if the file is available, write to it:
    if (dataFile) {
      while (dataFile.available()) {
        client.write(dataFile.read());
      }
      dataFile.close();
    }  
    // if the file isn't open, pop up an error:
    else {
      client.println("error opening datalog.txt");
    } 
}

void deleteFile(){
  SD.remove("datalog.txt");
}

void salvaValori(){

    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
      return;
    }

    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    if (dataFile ) {
       dataFile.print("Luminosita ");
       dataFile.println(sensore.getInstLumen());
       dataFile.print("Data: ");           
       dataFile.println(data);
    }  
    dataFile.close();

}

void setup()
{
  pinMode(SDpin, OUTPUT);
  Ethernet.begin(mac, ip);
  server.begin();
}

void loop()
{  
  // in attesa di richieste da parte dei client  
  Client client = server.available();
  if (client) {
    // una linea bianca delimita la fine di una richiesta HTTP
    readString="";
    sensore.setInstLumen(sensore.readLumen());

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        readString.concat(c); 
        if (c == '\n') { break; }
       }
    }
    
     if(readString.indexOf("L=1") > 0) {
      stampaValori(client);
      
      client.println("<script type='text/javascript'>");
      client.println("<!--");
      client.println("var data = new Date();");
      client.println("var Hh, Mm, Ss, mm;");
      client.println("Hh = data.getHours() + ':';  ");
      client.println("Mm = data.getMinutes() + ':'; ");
      client.println("Ss = data.getSeconds() + ':';  ");
      client.println("document.write('Sono le ore ' + Hh + Mm + Ss); ");
      client.println("//--> ");
      client.println("</script>"); 
      client.println("

</body></html>");
      
    }
        
    if(readString.indexOf("L=4") > 0) {
      printHeader(client);
      printMenu(client); 
      //delay(2000);
      salvaValori();
      client.println("

</body></html>");
     }
    delay(1);
  }
    // chiusura della connessione
    client.stop();
}

Funziona tutto tranne lo script JavaScript, in pratica se lo commento mi viene mostrata la pagina in maniera corretta, senza ovviamente la data che è compito dello script, mentre se lo decommento la pagina non viene proprio caricata, il browser va in timeout dopo tot secondi.
Potreste darmi una mano?
Aggiungo che se lo script lo modifico in modo da stamparmi solo l’ora (non minuti e secondi quindi) funziona solo alla prima richiesta, alla seconda mi appaiono caratteri strani (come se il baudrate fosse errato per capirci), mentre alla terza richiesta non risponde più.
Grazie 1000 a chiunque mi possa dare una mano.

E’ molto strano perchè effettivamente lo script è corretto, se proprio volessimo fare i precisini dovresti togliere i due punti dopo la stampa dei secondi.
ma sei sicuro che gli script funzionano con un arduino webserver?
hai provato ad interrogare la pagina con diversi browser? non è che hai qualche opzione che blocca l’esecuzione degli script ?

no purtroppo non dipende dal browser

ciao

lo stavo provando, ma alla connessione non ho assuletamente nulla pag bianca

comunque all’interno dei javascript i commenti si fanno con // per la singola linea
se vuoi raccogliere più linee devi mettere

/*



*/

client.println("<!–"); è sbagliata

messe così escludono tutte le linee del js

client.println("");

è quello che vuoi fare ? escludere le linee del js? però quando una funzione lo richiama hai comunque un errore

ciao

Ti ringrazio per il commento ma permettimi di dirti che la riga “<!–” è un modo per informare i browser che non supportano javascript che tutto quello che segue è un commento, e quindi non lo esegue; per sicurezza ho provato ad eliminare le due righe ma non cambia nulla.
Per visualizzare la mia pagina bisogna chiamarla con “http://192.168.2.177/?L=1” sostituendo l’ip con quello locale.

Ho aggiunto un delay(10) prima della costruzione dello script, funziona una volta, alla seconda richiesta si blocca nuovamente ed appaiono strani caratteri ASCII tipo  forse c'è qualche errore nella gestione della sessione del client? o della connessione?

Volendo abbandonare la costruzione della data con javascript cosa mi consigliate? Ho provato con Udp ma non è stabile neanche quella....

ma se il browser non supporta il javascript come mai allora metti
client.println("");

dal momento che usi questo dici al browser di interpretare le righe successive come comandi js

ho capito che questo script lo hai preso da qui,

cio’ non toglie che all’interno dei js si usano //

ci sono gli stessi errori ripetuti da te … i : alla fine che non servono :grin:

Ti darei volentieri una mano, però ti ripeto, come la giro la giro a me da una pagina bianca.

ciao

come la giro la giro a me da una pagina bianca.

dovresti collegarti ad Arduino con una GET così: http://192.168.2.177/?L=4 o come detto da alasandra, così: http://192.168.2.177/?L=1

Il js va bene (anche se hai lasciato i ':' dopo i secondi). Ho provato a caricare il tuo sketch (un poco ripulito ma sostanzialmente è lui), e non risocntro i problemi che segnali, relativamente allo script js..

pitusso:

come la giro la giro a me da una pagina bianca.

dovresti collegarti ad Arduino con una GET così: http://192.168.2.177/?L=4 o come detto da asalandra, così: http://192.168.2.177/?L=1

Il js va bene (anche se hai lasciato i ':' dopo i secondi). Ho provato a caricare il tuo sketch (un poco ripulito ma sostanzialmente è lui), e non risocntro i problemi che segnali, relativamente allo script js..

scusami prova a lanciare lo sketch con L=1 e poi clicca varie volte sul link "Leggi sensori" tu non hai problemi? grazie 1000

forse mi sto perdendo in un bicchiere d'acqua: come faccio ad avere la data corrente senza avere un computer a cui collegarmi? Quindi senza una seriale a disposizione l'unica interfaccia è il l'Ethernet che collega Arduino ad internet.

scusami prova a lanciare lo sketch con L=1 e poi clicca varie volte sul link "Leggi sensori" tu non hai problemi?

no Che browser stai utilizzando? Se hai problemi o dubbi con JS, puoi utilizzare un browser come Firefox, con l'estensione FireBug.

come faccio ad avere la data corrente

Sembra che tu voglia utilizzare NTP, in realtà hai copiato solo parte del codice che ti serve. L'ora che vai a scrivere la ottieni invece con l'oggetto js Date(), che così istanziato è basato sull'orologio del visitatore.

In realtà potresti fare tutto con NTC - sia recupero data che ora. Chiaramente Arduino deve essere in rete.

pitusso:

scusami prova a lanciare lo sketch con L=1 e poi clicca varie volte sul link "Leggi sensori" tu non hai problemi?

no Che browser stai utilizzando? Se hai problemi o dubbi con JS, puoi utilizzare un browser come Firefox, con l'estensione FireBug.

Veramente strano, uso sia firefox che explorer, ma la stessa cosa mi succede col browser Android, inizio a pensare sia un problema del router al quale sono collegati sia Arduino che il pc allora

come faccio ad avere la data corrente

Sembra che tu voglia utilizzare NTP, in realtà hai copiato solo parte del codice che ti serve. L'ora che vai a scrivere la ottieni invece con l'oggetto js Date(), che così istanziato è basato sull'orologio del visitatore.

In realtà potresti fare tutto con NTC - sia recupero data che ora. Chiaramente Arduino deve essere in rete.

NTC? forse volevi dire RTC? altrimenti ti sarei grato se mi fornissi un link. grazie 1000

NTC? forse volevi dire RTC? altrimenti ti sarei grato se mi fornissi un link.

…a dire il vero intendevo NTP, ma nello scrivere mi è scappato un dito :stuck_out_tongue:

Questa parte di codice che hai inserito:

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

è parte di codice che serve a recuperate data e ora via rete (Network Time Protocol)…

Potresti quindi passare per NTP, oppure usare appunto RTC (Real-Time Clock), il quale richiede pero un IC apposito.
Qui:
http://www.arduino.cc/playground/Main/InterfacingWithHardware#time
trovi molti link a tema.

Oppure ancora (ma qui non vorrei mettere troppa carne al fuoco) potresti gestire data e ora con swRTC, una libreria scritta da Leo
http://arduino.cc/forum/index.php/topic,73496.0.html
qui devi però inizializzarla con data e ora corrette.

pitusso: Questa parte di codice che hai inserito:

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

è parte di codice che serve a recuperate data e ora via rete (Network Time Protocol)...

Potresti quindi passare per NTP, oppure usare appunto RTC (Real-Time Clock), il quale richiede pero un IC apposito. Qui: http://www.arduino.cc/playground/Main/InterfacingWithHardware#time trovi molti link a tema.

Oppure ancora (ma qui non vorrei mettere troppa carne al fuoco) potresti gestire data e ora con swRTC, una libreria scritta da Leo http://arduino.cc/forum/index.php/topic,73496.0.html qui devi però inizializzarla con data e ora corrette.

Quella parte di codice è un refuso dal tentativo che ho fatto per utilizzare NTP, funziona una sola volta anche quello... dopo il secondo click la pagina non viene più caricata... A questo punto proverò swRTC provvedendo a creare un piccolo form web per inizializzare la data in caso servisse. Grazie di nuovo

Ragazzi ho individuato il problema, non so se sia un baco o una funzionalità nota, in pratica il client.println non funziona come dovrebbe quando ci sono delle stringhe da concatenare con degli interi:

...
client.println("data: " + data + "
");
...
client.println("document.write('Sono le ore ' + Hh + Mm + Ss); ");
....

fanno dei casini, spezzando una riga in più println funziona tutto... Grazie delle risposte

Antonio