Programmare arduino da webserver

ciao mi presento sono michele con basi di elettronica ed alcuni circuiti sviluppati con pic e arduino,vorrei realizzare un progetto che si basa sul mega e ethernet shield,tramite il webserver dovrei essere in grado di leggere e modificare un file csv salvato sulla sd card che sarà il runtime dell'arduino,nel quale ci sarà scritto per esempio:secondo 22;uscita 1;fade in di 5 secondi;con un valore luminoso max di 80%.voi avete già realizzato qualcosa di simile?quali problematiche posso incontrare?grazie

mi servirebbe per creare un interfaccia semplice anche per chi non ha conoscenze di programmazione arduino per attivare e disattivare uscite a tempo in un ciclo che si ripeta all'infinito.grazie

Non mi è chiaro qual'è il problema per il quale chiedi aiuto...

Hai imbastito uno sketch?
Se non sai da dove partire, fai una cosa per volta e a step successivi. Ad esempio:

  • fai funzionare l'ethernet shield con i classici esempi inclusi;
  • metti su un webserver con i classici esempi inclusi e verifica che funzioni ad esempio facendo accendere e spegnere il solito led;
  • scrivi e leggi un file sulla SD;
  • inizializza una variabile dello sketch leggendo il valore dalla SD;
  • crea una funzione che in seguito ad un tuo input (esempio pulsante o comando inviato da monitor seriale) va a leggere il file di configurazione dall SD e assegna i nuovi valori alle variabili interessate;

e solo alla fine:

  • scrivi una pagina web esposta dal webserver che prevede le funzionalità necessarie replicando quanto fatto al punto precedente.

ciao, grazie per la risposta,ho già lavorato con gli esempi webserver,e non ho molti problemi, volevo sapere se è una cosa possibile per performance ecc,sono partito da una pagina excel, poi riscritta in html ma non so se dal webserver posso leggere-modificare e salvare il file csv sulla sd,e non so come si comporterà l'arduino .per adesso sono alla parte html,ho caricato molti esempi che danno la possibilità di caricare il file csv,ma quando pio deve generare la nuova pagina con la tabella il browser non trova il file generato.grazie

Come linea di principio una pagina web non potrà mai eseguire azioni dirette sul server dove viene ospitata (per questioni intrinseche di sicurezza).

Ma a livello di webserver però, considerato che è "embedded" nel tuo dispositivo, potrai fare tutto quello che vuoi in risposta ad una specifica chiamata HTTP.

Prendi il classico esempio che accende spegne il led fatto con delle chiamate GET o POST:
http://tuo_webserver/ledon per accendere
http://tuo_webserver/ledoff per spegnere.

Nel tuo caso dovrai fare degli "handler" specifici per leggere il file csv dalla SD e preparare la risposta, oppure per salvare il file csv inviato con la pagina web.

Non conosco molto bene la classe EthernetServer che presumo tu stia utilizzando, ma da quanto ricordo non è molto completa e non ha metodi diretti per gestire l'upload di file.
Ad ogni modo un file csv è essenzialmente un file di testo e quindi al posto di fare l'upload puoi semplicemente trasmettere il suo contenuto come payload e "ricostruirlo" lato Arduino-Webserver.

ciao, mi spiego meglio,ho un file csv che alla prima riga contiene:
1;fade on;2;5;80;ecc
1 sta per il secondo della runtime
fade on sta per l'azione da eseguire
2 sta per l'uscita da comandare
5 sono i secondi di fade da applicare
80 è la luminosità massima che l'uscita deve avere in questa azione

e potrei eseguire 7 operazioni ogni secondo

vorrei che arduino esegua questo file fino a che trova l'azione reboot e poi riparta da 1

e dal webserver vorrei leggere questo file ,modificarlo e poi salvarlo di nuovo per farlo eseguire

grazie

Ma usare webbino proprio non vi piace? ... Si disegnano belle videate html, si inseriscono i vari tag identificativi e ... gestisce tutto lui senza stare a giocare con l'html, il pasing di cosa si riceve, ecc. ecc.

Guglielmo

A me personalmente no :joy:

Preferisco scrivere dell'HTML/Javascript "puro" e non stringhe di cui è necessario fare il parsing per inserire/aggiornare dei tag perché è un approccio statico che difficilmente si sposa con il principio delle web application, ma ovviamente queste sono solo delle preferenze personali :wink:

... premesso che devi ricordarti che stai su piccole MCU e NON su un server Linux, per cui, i webserver che fai, sono ad uso estremamente limitato (aggiornare paramentri, settare impostazioni, e banalità del genere), una volta definiti i campi di I/O con i vari tag (che tanto, proprio per il tipo d'applicazione, non toccherai praticamente mai più), tutto il parsing, le sostituzioni, ecc. ecc. NON sono a tuo carico, le fa la libreria e tu manco te ne accorgi.

Guglielmo

Proprio per questa ragione preferisco fare dei webserver che devono limitarsi SOLTANTO ad inviare una pagina web (una volta sola, senza fare inutili refresh), magari salvata pure sulla SD cosi da non rubare RAM e spazio prezioso e successivamente rispondere a semplici chiamate Ajax con una manciata di caratteri.

Il lavoro pesante lo farà tutto il browser su un computer oppure uno smartphone e mi posso permettere di realizzare interfacce moderne e ricche di funzioni anche su piccole MCU. Inoltre in questo modo la risorsa richiesta è statica (ma non il contenuto) ed il browser potrà fare anche efficacemente il caching ottimizzando i tempi di caricamento.

... mi sa che dovresti suidiarti un po' meglio webbino, perché, secondo me, non lo conosci abbastanza e lo sottovaluti. :roll_eyes:

Ah, le pagine web, le memorizzi in Flash, su SPIFFS, LittleFS o SD ... :grin: ... tutto gestito dalla libreria.

Guglielmo

Guglielmo, premesso che è una libreria che comunque ho provato sia su piattaforma AVR che ESP, per quale ragione dovrei investire tempo in qualcosa di cui non vedo i vantaggi per quello che è il mio modo di lavorare?

Anche se metto i file sulla SD o flash o quel che sia, il principio è sempre quello del tag da sostituire che non mi piace.

Ci tengo a sottilineare che non sto denigrando o sminuendo in alcun modo l'ottimo lavoro fatto con Webbino da sukkopera, ma solo che io preferisco fare in altro modo e che in generale non mi sento di consigliare a prescindere qualcosa che conosco poco.

Per ritornare un po' in tema, se non ho capito male, i dubbi di @ilbotta su come procedere ad ogni modo prescindono dal metodo/libreria con cui vorrà generare le pagine web.

ciao, per ora carico il file e lo stampo su seriale, ma come faccio a caricare riga per riga allo scadere di ogni secondo e farlo ripartire dalla riga 0 appena trova il reboot?grazie

//libs
#include <SPI.h>
#include <SD.h>

//SD vars
File myFile;

//parse data vals
int dataarr[60] = {};     //array of parsed data
int arrpointer = 0;       //array pointer
int column = 29;           //column to parse
int columncount = 1;      //start at column 1 not 0
int rowincrement = 1;     //increment the number of parse rows - set to 1 for all rows
int rowcount = 2;         //start at row 1 not 0
String datatemp;          //temp to store datapoint
int a, b, c, d ;
String msg;

void setup() {

  Serial.begin(9600);

  if (!SD.begin(4)) {
    Serial.println("Errore SD!");
    return;
  }
  Serial.println("SD pronta.");

  //Read file
  myFile = SD.open("PRESE.csv");

  if (myFile) {

    Serial.println();

    while (myFile.available()) {

      int filedata = myFile.read();

      //////////////
      // parse
      //////////////

      //read data vals into string
      if ((filedata != ',') && (filedata != ' ')) {

        //test for row increment
        if (rowcount % rowincrement == 0) {

          //look for column
          if (columncount == column) {

            //push datapoint to array
            Serial.print("*");
            datatemp = datatemp += (filedata - '0');
            dataarr[arrpointer] = datatemp.toInt();

          }

        }

      }

      Serial.write(filedata);

      //end of datapoint
      if (filedata == ',') {
        columncount++;
      }

      //end of row
      if (filedata == '\n') {

        //print data temp at end of line
        Serial.write(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        Serial.print(datatemp.toInt());
        Serial.println();

        //reset vars to read next row
        rowcount++;
        columncount = 1;
        datatemp = "";
        //arrpointer++;

      }

      //////////////
      // end parse
      //////////////

    }
  }

  Serial.println();
  Serial.println();
  Serial.println("--------------------------");

  //cycle through data array
  for (int i = 0; i < arrpointer; i++) {
    Serial.print("Selected Data >>>>>>> ");
    Serial.println(dataarr[i]);
    Serial.print(", ");
  }

  myFile.close();

}


void loop(void) {
{

@ilbotta : in conformità al REGOLAMENTO , punto 7, cortesemente edita il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita :pencil2: che si trova in basso del tuo post), seleziona TUTTA la parte di codice e premi l'icona </> nella barra degli strumenti per contrassegnarla come codice.

Inoltre, così com'è, non è molto leggibile ... assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa premendo ctrlT su un PC o cmd T su un Mac all'intero del IDE). Per maggiori informazioni ... punto 17.2 del succitato regolamento. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà sistemato il codice, nel rispetto del suddetto regolamento nessuno ti risponderà, quindi ti consiglio di fare il tutto al più presto. :wink:

scusami ho riedittato grazie

Ecco appunto, sei ancora ben lontano dal preoccuparti per la pagina web... :rofl:

Come prima cosa devi modificare il post curando la posizione del tag [code] perché cosi è tutto incasinato, altrimenti Guglielmo si arrabbia moltissimo :sweat_smile:

Per quanto riguarda il codice ho dei dubbi che possa funzionare cotrrettamente: tu leggi i caratteri contenuti nel file PRESE.CSV carattere per carattere e poi fai la conversione da ASCII ad integer con il metodo della sottrazione di '0' == 0x32

datatemp = datatemp += (filedata -'0');

Ma cosa succede se il numero ha 2 o 3 cifre?

Devi cambiare approccio ed hai diverse strade, la più semplice prevede l'uso della classe String e dei suoi metodi pronti all'uso.
Una seconda opzione è un pelo più complessa, ma "forum compliant" ovvero fare il "tokenizing" usando la virgola come carattere di divisione e l'istruzione "cstring" strtok() evitando quindi l'uso di String che se usata in modo improprio può essere "dannosa".

Un esempio con il secondo metodo dove ho dovuto usare un char array per simulare il file. Prendi spunto e prova ad adattarlo al tuo caso specifico.

ok ,ti ringrazio x il tuo esempio, la prima cosa che faccio cambio gli stato da parola a numero in modo da semplificare la lettura, poi mi studio il tuo codice e cerco di ampliarlo .grazie

anche se il mio codice legge e stampa in seriale 3 cifre e anche le parole

Ma la conversione in intero è corretta? Hai verificato che nell'array ti trovi i valori attesi?

Puoi mettere il contenuto esatto di un paio di righe del file?

questo e quello che mi rimanda sulla seriale:

0;on;1;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>0
1;fade in;2;5;80;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>0
2;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>0

mentre questo è il testo del file csv:

0;on;1;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100
1;fade in;2;5;80;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100
2;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100;vuoto;vuoto;0;100

mentre la foto è il foglio di excel per elaborare il csv