Consiglio libreria Ethernet

Salve,
come da titolo avrei bisogno di un consiglio (o meglio, l'instradamento) per la realizzazione di un progetto che prevede l'utilizzo di alcuni sensori tramite la rete locale (offline).

Ho un Arduino Uno con Ethernet Shield e l'attuale scopo del progetto sarebbe quello di:

  • poter accendere e spegnere un led cliccando su un bottone nella pagina web e cambiarne i valori di luminosità;
  • premere un tasto fisico connesso ad Arduino e far partire un alert (popup/notifica nella pagina web) a schermo.

E' da circa una settimana che scandaglio la rete alla ricerca di un sistema ottimale, ma non sono ancora riuscito a trovare una risposta che sia a me chiara.
Utilizzando solo l'HTML sono riuscito a far accendere/spegnere e cambiarne i valori di luminosità di un led, e leggere la pressione di un bottone con l'aiuto però di un refresh della pagina ogni 3 secondi, ma non è il sistema di cui ho bisogno; il refresh dovrebbe essere dinamico e non totale.

Ho trovato un bel tutorial che spiega come poter gestire le letture/scritture analogiche e digitali tramite l'utilizzo dell'AJAX e Java, ma non essendo pratico di entrambi i linguaggi non riesco a comprendere, e modificare, gran parte del codice...
Ho inoltre trovato le librerie Webduino e TinyWebServer con però poche sipegazioni, e non riesco a riadattarle alle mie esigenze.

Le domande che vorrei porvi sono:

  • A livello di semplicità programmativa, quale metodo mi conviene utilizzare?
  • E' possibile utilizzare il jquery per il refresh dinamico dei contenuti?
  • E' possibile fare pagine separate per la lettura di valori? (Es. pag1.html per accendere e spegnere 2 led / pag2.html per visualizzare lo stato del bottone).

Domanda bonus non essenziale:

  • E' possibile, con l'aiuto di un pc e un database locale, utilizzare il PHP con GET e POST per leggere e scrivere i valori?

Grazie in anticipo ;D

Ajax non è un linguaggio, è piu una tecnica, implementata in Javascript, si puoi usare il framework jQuery, ti semplifica il codice, la richiesta piu semplice in Javascript necessita di circa 10 righe di codice, in jQuery si semplifica in appena 10 caratteri.
Puoi tranquillamente rimuovere il refresh, e sostituire il tutto con una richiesta asincrona. Il minimo è conescere almeno le basi di Javascript.

Avrai necessità di gestire piu di un url da Arduino per distinguere una chiamata alla pagina web e una richiesta di dati. Purtroppo Arduino è uno dei sistemi peggiori su cui gestire stringhe dinamiche, affidati a qualcosa di gia fatto. Esiste il metodo classico di Arduino che io trovo poco elegante, ed estensibile(quello del tutorial webserver)
Io uso un codice del genere

typedef enum { httpMethodGet, httpMethodPost } httpMethod_t;

typedef struct {
  httpMethod_t method;
  char page[HTTP_REQUEST_PAGE_SIZE];
} httpRequest_t;

httpRequest_t httpRequest;
void WaitRequest() {
  byte i = 0;
  char c;
  bool isPage = false;

  do {
    client = server.available();
  } while (!client);
  delay(1);

  while (client.connected()) {
    if (client.available()) {
      c = client.read();

      if (isPage) {
        if (c == ' ' || i == HTTP_REQUEST_PAGE_SIZE - 1) break;
        httpRequest.page[i] = c;
        i++;
      } else {
        if (c == 'G') {
          httpRequest.method = httpMethodGet;
          i = 3;
        } else {
          httpRequest.method = httpMethodPost;
          i = 4;
        }
        isPage = true;
        for (; i != 0; i--) client.read();
      }
    }
  }
  httpRequest.page[i] = '\0';
  client.flush();
}
void loop() {
  Serial.println(F("Wait..."));
  WaitRequest();
  Serial.print(F("Method:\t\t"));
  Serial.println(httpRequest.method ? F("POST") : F("GET"));
  Serial.print(F("Request:\t"));
  Serial.println(httpRequest.page);
  Serial.println("");

  if (!strcmp(httpRequest.page, "/js/control.js")) SendPage("text/javascript", "js/control.js");
  else if (!strcmp(httpRequest.page, "/css/control.css")) SendPage("text/css", "css/control.css");
  else if (!strcmp(httpRequest.page, "/css/style.css")) SendPage("text/css", "css/style.css");
  else if (!strcmp(httpRequest.page, "/favicon.png")) SendPage("image/png", "favicon.png");
  else if (!strcmp(httpRequest.page, "/")) SendPage("text/html", "index.htm");
  else if (strstr(httpRequest.page, "/update.json") != 0) {
    if(httpRequest.page[12] == '?') {
      if(httpRequest.page[13] == '0') digitalWrite(7, httpRequest.page[14] == '1');
      else if(httpRequest.page[13] == '1') digitalWrite(3, httpRequest.page[14] == '1');
      else if(httpRequest.page[13] == '2') digitalWrite(2, httpRequest.page[14] == '1');
      else if(httpRequest.page[13] == '3') OCR0A = (httpRequest.page[14] - 48) * 100 + (httpRequest.page[15] - 48) * 10 + (httpRequest.page[16] - 48);
      else if(httpRequest.page[13] == '4') OCR0B = (httpRequest.page[14] - 48) * 100 + (httpRequest.page[15] - 48) * 10 + (httpRequest.page[16] - 48);
    }
    SendUpdate();
  } else SendPage("text/html", "404.htm");

  delay(1);
  client.stop();
}

E un idea di richiesta asincrona mediante Jquery.

$(function() {
			setInterval(function() {
				$.getJSON("update.json", update);
			}, 5000);
			$("div[data-control-switch]").change(function() {
				id = $(this).attr("id");
				if(id == "led1") id = 0;
				else if(id == "led2") id = 1;
				else if(id == "led3") id = 2;
				
				$.getJSON("update.json?" + id + ($(this).attr("data-control-switch") == "true" ? "1" : "0"), update);
			});
			$("div[data-control-slider]").change(function() {
				id = $(this).attr("id");
				if(id == "dimmer1") id = 3;
				else if(id == "dimmer2") id = 4;
				
				$.getJSON("update.json?" + id + ("00" + $(this).attr("data-control-slider")).slice(-3), update);
			});
		});

Capisco che ti sto dicendo poco o niente, ma partiamo da quello che ti ho scritto.

Grazie per la risposta.

Ho letto il codice e credo di aver capito cosa fa, ma sto avendo problemi ad integrarlo con l'esempio base.

Non mi è chiara inoltre questa riga di codice:

else if(httpRequest.page[13] == '3') OCR0A = (httpRequest.page[14] - 48) * 100 + (httpRequest.page[15] - 48) * 10 + (httpRequest.page[16] - 48);

Posso chiederti uno sketch completo con una pagina web (nel caso in cui le letture/scritture passassero per l'SD) da potermi studiare e riadattare per il mio progetto?

Grazie.

è proprio questo che volevo esprimere, quei spezzoni sono parte di una demo che sto preparando(per appunto la gestione di un simil webserver su Arduino), che di per se senza commenti e ne visione di insime puo solamente confondere. Se vuoi comunque posso postarti il progetto completo comunque.
Quella riga non fa altro che aggiornare il PWM su una porta in base al dato ricevuto dal browser(non uso analogWrite, ma il risultato è lo stesso).

RobertoBochet:
è proprio questo che volevo esprimere, quei spezzoni sono parte di una demo che sto preparando(per appunto la gestione di un simil webserver su Arduino), che di per se senza commenti e ne visione di insime puo solamente confondere. Se vuoi comunque posso postarti il progetto completo comunque.

Se hai modo di postarlo, mi fa sempre piacere osservare i progetti e capire come viene scritto un codice da chi ne sa di più :slight_smile:

RobertoBochet:
Quella riga non fa altro che aggiornare il PWM su una porta in base al dato ricevuto dal browser(non uso analogWrite, ma il risultato è lo stesso).

Ah ok, ora ho capito, anche se mi torna più difficile del comando classico.

Grazie!

Ho inoltre trovato le librerie Webduino e TinyWebServer con però poche sipegazioni, e non riesco a riadattarle alle mie esigenze.

le avevo studiate entrambe la tiny però si è rivelata più efficente e completa con la possibilità di essere espansa a fare altre cose interessanti.
Ho dato diverse spegazioni dal 2012 - 2014 sul suo funzionamento, che apparentemente può sembrare complessa, ma invece tuttosommato semplice da usare, sono cambiate alcune cose da allora, lato arduino e lato browser, però il principio è sempre quello.
Ci sono anche argomenti dove avevamo costruito degli slider lato browser per pilotare i pwm mi sembra con un utente di nome lluca

Ne avevo apportato modifiche con ottimi risultati per implementare

  • un semplice Digest access authentication con cifratura MD5
  • Basic access authentication base64
  • WebSocket con una velocità di scambio dati fin troppo elevata per arduino

Anche la possibilità di fare gli upload dei file sulla SD da remoto era una caratteristica che mi è stata molto utile (opzione già presente nella lib tinyweb).

Il suo limite è l'AVR, il segreto è ridurre al minimo lo scambio dati e impegnarlo il meno possibile.
Già con arduino DUE il risultato è nettamente superiore, si ha il tempo di lavorare sulla parte web e anche elaborare gli I/O senza perdere eventi (ovviamente se è richiesta una certa velocità di aggiornamento).

Se hai una UNO però .... non iniziare nemmeno.

ciao

pablos:
Se hai una UNO però .... non iniziare nemmeno.

Ho scoperto la tiny grazie ai tuoi post sul forum, a dir la verità :grinning:

Ho una UNO ma sto pensando di passare a Mega 2560 perchè mi servono più connessioni fisiche; la differenza tra Mega e Due immagino sia parecchio visibile in termini di prestazioni, però lo shield che ho è sicuramente compatibile ed ha un costo più accessibile al momento.

Il discorso su Mega cambia o mi sconsigli ugualmente di giocare con la rete?

La mega si, ha sufficiente ram per fare un po di sketch e supportare le librerie necessarie al webserver

pablos:
La mega si, ha sufficiente ram per fare un po di sketch e supportare le librerie necessarie al webserver

Perfetto allora, la domanda resta valida per poter fare qualche prova in attesa del nuovo acquisto :slight_smile:

Vi pongo un'altra domanda, sempre inerente al progetto:
vorrei far riprodurre dei suoni, per adesso in base agli eventi ma più in la selezionabili dal web; uso attualmente uno speaker e il comando tone, ma mi piacerebbe poter utilizzare dei suoni più complessi (ad esempio riprodurre il suono di un campanello per la porta d'ingresso, o il miagolio di un gatto);
ho visto che esistono degli shield appositi ma non riesco a trovarne sul mercato italiano (se non a cifre per me impossibili, +50€), e non vorrei occupare tutte le porte a disposizione.
Esiste un sistema valido che mi permetta di utilizzare Wav o Mp3 presi dall'SD dello shield? naturalmente previa costruzione di un circuito.
In caso contrario, esiste un qualsiasi convertitore che converta le note da un file campionato in cifre 8 bit per essere inserite nello sketch? Immagino la resa sia totalmente peggiore, ma mi basta che si capisca il tipo di suono, non dev'essere pulito.

Esiste un sistema valido che mi permetta di utilizzare Wav o Mp3 presi dall’SD dello shield? naturalmente previa costruzione di un circuito.

non credo, forse un MIDI, ma non me ne sono mai preoccupato, hai cercato in rete?

RobertoBochet:
è proprio questo che volevo esprimere, quei spezzoni sono parte di una demo che sto preparando(per appunto la gestione di un simil webserver su Arduino), che di per se senza commenti e ne visione di insime puo solamente confondere. Se vuoi comunque posso postarti il progetto completo comunque.

A me interessa darci un occhiata :slight_smile:

Per mp3 serve un modulo o shield Mp3.

pablos:
non credo, forse un MIDI, ma non me ne sono mai preoccupato, hai cercato in rete?

Si ho cercato in rete negli ultimi giorni ma senza troppa fortuna; mi spiego:

Shield Mp3:

Shield Wav:

Tutti da market americani con spedizioni superiori ai 20/30$.

Per quanto riguarda Arduino Due ho trovato questo tutorial sito ufficiale: Simple Audio Player
...e nella ricerca di un effettivo funzionamento anche su Mega (e credo di no) mi sono imbattuto in questo vecchio Thread:
Do not follow Simple Audio Player example - DAC0 now non-functional on DUE
...sperando naturalmente che il tutorial sia stato fixato :o

Non avevo però pensato ad una soluzione Midi:
esiste una libreria ufficile che richiede uno shield apposito, poichè ci vuole un connettore Midi per poter funzionare (quindi input/output esterno);

vista la situazione generale credo sia infattibile con un costo irrisorio, l'ultima spiaggia sarebbe un convertitore per ricreare semplici tonalità senza doverle cercare ad orecchio, non essendo pratico.

Per semplici toni, comando Tone() di Arduino. Usa un timer quindi occhio se altri componenti hw usano lo stesso timer.

Per wav esistono modulini cinesi per suonarli, sono un pò difficili da usare ma non impossibili.
Esempio (solo un esempio, ne trovi altri): QUI
Sono rognosi perchè devi avere una SD che sia "compatibile", non tutte vanno. E il file deve essere un wave ma con un determinato formato.

nid69ita:
Sono rognosi perchè devi avere una SD che sia "compatibile", non tutte vanno.

"Il prodotto supporta plug-massimo 32M ~ 1 G. a capacità della scheda SD;"
Giusto per parlare....ormai costa più trovare una MicroSD da 32mb che prendere uno stereo e premere play quando serve :stuck_out_tongue: :stuck_out_tongue_closed_eyes:

Ironia a parte, mi era sfuggito durante la ricerca! Se supportasse le SD ne avrei anche una, ma micro di quel taglio oramai non se ne vedono...

nid69ita:
Per semplici toni, comando Tone() di Arduino. Usa un timer quindi occhio se altri componenti hw usano lo stesso timer.

Uso il comando Tone per adesso, ma non posso ricreare suoni complessi e non riesco a simularne di decenti... il 'dling dlong' del campanello ad esempio, o una sorta di miagolio (che potrei recuperare da un pokemon volendo, ma non saprei come) mi stanno risultando impossibili. Non esiste un software per generare la tonalità 8 bit che però mi dia le note inseribili nello sketch? Sono ignorante in materia, scusate.