Problema Arduino

Salve ragazzi, ho un problema con arduino, devo aprire diciamo una scatola o cassaforte che sia, tramite un codice che dovrò generare sul web, quindi su un sito web apposito, come faccio a comunicare ad arduino il codice che ho generato sul sito web? considerando che ogni volta che genero un codice, la macchina arduino deve sapere che il codice è cambiato e quindi quando andrò ad aprire la scatola, dovrò inserire il codice generato dalla pagina web?

Materiale che sto utilizzando:
Arduino uno
tastiera 4x4
Display LCD 16x2
servo motore
mini ethernet shield
(breadboard)

Non sono molto esperto di internet con arduino ma quello che dovrai realizzare è un webclient con arduino, di cui puoi trovare esempi.
Arduino non può accorgersi del cambiamento della pagina, magari puoi pensare di fare una richiesta al server ogni pochi secondi, la pagina risponde inviando la password, se la password è diversa dalla precedente avviene qualcosa.
La comunicazione web con arduino è molto limitata, sia che si tratti di un webserver o di un webclient, quello che può fare arduino è trasmettere o ricevere caratteri. Per cui se ricevi qualcosa sarà una successione di caratteri che dovrai elaborare per ricavare la password.

grazie per la risposta, stavo pensando di usare il metodo GET per la comunicazione, non so se c'entra qualcosa

ElleLwaliet:
grazie per la risposta, stavo pensando di usare il metodo GET per la comunicazione, non so se c'entra qualcosa

Ciao,
stavo proprio per dirlo io.

Lo userei insieme al tag di HTML

<form <form name="form1" action="get" method="get">
        testo1 <input type="text" name="testo"> 
        

        <input type="radio" name="opt" value="one" autocomplete="off" checked="true"> 1
        

        <input type="radio" name="opt" value="two" autocomplete="off"> 2
        

        <input type="submit" name="btn" value="OFF">
</form>

e ti trovi il link fatto cosi:

il_tuo_ip/get?testo=val1&opt=val2&btn=OFF

quindi poi li scorpori ed hai i tuoi valori

Adesso io non so con il modulo Ethernet come funzioni perché io programmo web solo con ESP8666 o ESP32 che per quello che costano li consiglio veramente.

Alan Masutti

Grazie mille per la risposta, a proposito di questo, spiego cosa dovrà fare:
in pratica dal lato web devo generare un numero random, mi sto aiutando con javascript conla funzione randomize. arduino deve poter prendere questo numero generato e salvarlo, cosicchè quando andrò ad aprire questa "scatola/cassaforte" se inserisco il codice cheho generato dal web mi deve aprire la scatola. Come potrei procedere a riguardo?

1)Mi creo la pagina web che stampa la password. In base a una richiesta get da parte di arduino il server mi trasmette la pagina con la password. Renderebbe la ricerca più semplice se la password avesse una lunghezza fissa.

2)Su arduino creo un webclient e un contatore di tempo tramite funzione millis(). Al passare di un certo numero di secondi invio una richiesta get con il webclient.

3)Col webclient ricevo carattere per carattere la pagina web contenente la password e la salvo in un array di char di opportune dimensioni.

4)Elaboro l'array, ad esempio scorro l'array alla ricerca di un carattere che mi indichi l'inizio password, esempio *, sapendo la lunghezza della password, prelevo i caratteri della password e le inserisco in un array di char.

  1. Tramite funzione strcmp() posso confrontare la password recuperata dal web con quella inserita manualmente e compiere delle azioni.

Dipende cosa metti nella cassaforte.

Se tutto questo é solo un gioco ok va bene.

Se vuoi usare il tutto per proteggere qualcosa tutto questo procedimento non é sicuro. Serve una connessione SSL (https://) e non possono essere mandati dati in get. Allora Ti serve altro hardware.

Ciao Uwe

Ciao,

uwefed:
Se vuoi usare il tutto per proteggere qualcosa tutto questo procedimento non é sicuro. Serve una connessione SSL (https://) e non possono essere mandati dati in get. Allora Ti serve altro hardware.

Confermo questa cosa e ti consiglio appunto di non fare affidamento a questo sistema come super affidabile. Non so quanto tu conosca di Arduino, ma ad esempio un errore di runtime () potrebbe farti perdere la tua chiave, e quindi non poter aprire più la cassa.

Premettendo che io conosco meglio l'ambiente ESP32, la richiesta get la fa il client, quindi tu quando clicchi ad esempio su un pulsante di tipo submit della pagina web, al che il tuo server cambia indirizzo e si porta al valore di action del form (nel mio esempio tuo_ip/get), il server si accorge di ciò e recupera i tuoi valori.
In generale io farei così:

String arr[5] = {"", "", "", "", ""};

const char MAIN_page[] PROGMEM = R"====(
  <head>
      <title>
          Prova
      </title>
  </head>
  <body>
      <form name="form1" action="get" method="get">
        Ora di inizio <input type="text" name="TESTO 1"> 
        

        Ora di fine <input type="text" name="TESTO 2"> 
        

        Zona 
        

        <input type="radio" name="zone" value="one" autocomplete="off" checked="true"> 1
        

        <input type="radio" name="zone" value="two" autocomplete="off"> 2
        

        <input type="radio" name="zone" value="three" autocomplete="off"> 3
        

        <input type="radio" name="zone" value="four" autocomplete="off"> 4
        

        <input type="submit" name="state" value="ON">
        <input type="submit" name="state" value="OFF">
        

        <input type="submit" name="Invia configurazione" value="Conferma">
      </form> 
  </body>
  
)====";

void arrReset() {
  arr[1] = "";
  arr[2] = "";
  arr[3] = "";
  arr[4] = "";
}

void submit() {
  arrReset();
  arr[1] = server.arg(0);
  arr[2] = server.arg(1);
  arr[3] = server.arg(2);
  arr[4] = server.arg(3);
  page();
}

void page() {
  server.send(200, "text/html", MAIN_page);
}

void setup() {
  // start the server
  server.on("/", page);
  server.on("/get", submit);
  server.begin();
}

void loop() {
  server.handleClient();
}

uwefed:
Dipende cosa metti nella cassaforte.
Se tutto questo é solo un gioco ok va bene.
Se vuoi usare il tutto per proteggere qualcosa tutto questo procedimento non é sicuro. Serve una connessione SSL (https://) e non possono essere mandati dati in get. Allora Ti serve altro hardware.

Immagino (spero) che sia una "escape room" non penso che qualcuno che debba proteggere cose preziose o di valore o riservate si metta a giochicchiare con Arduino... :wink:

Però confesso che non ho ben capito la struttura della richiesta (e le risposte che leggo sono in senso contrario a quello che avrei detto io). Lui dice che su sito web genera di tanto in tanto una nuova password e che questa vada comunicata ad Arduino.

Intanto mi chiedo cosa significhi esattamente che "genera" la password, ossia parla di javascript ma quindi viene generata in modo casuale (?) da una funzione javascript quando qualcuno (un utente? L'amministratore? Chi?) la attiva (quando? Periodicamente? Ogni tanto?) e cambia la password (che quindi è memorizzata dove? Esiste un DB?). E il server web è locale (e quindi anche accessibile per te) o è un sito web in hosting (qindi in remoto)?

Poi il sito web questa password la dovrebbe comunicare ad Arduino: se lo deve fare quando viene modificata, allora deve esserci qualcosa (cosa? Una procedura javascript? Un processo sul server web?) che contatta Arduino, ad esempio facendo una GET ad Arduino che quindi è impostato come web server, e che a sua volta la mette in memoria (e se viene spento e riacceso come fa a sapere la nuova password? La memorizza in EEPROM?). Oppure, al contrario, è Arduino che quando qualcuno (chi?) digita sulla tastiera di Arduino (se ne è mai parlato?) un codice, questo contatta il server e chiede di verificare la password immessa.

Per la comunicazione potrebbe anche bastare qualche pacchetto UDP senza scomodare inutilmente l'http, ma tutto dipende da quali siano le condizioni o requisiti del progetto.

Per cui ElleLwaliet, per favore, spiega meglio cosa vorresti realizzare: più che proporre o chiedere "come", devi dire cosa vorresti ottenere descrivendo meglio sia l'ambito (è una escape room? La tua cassaforte di casa? Fort Knox? Hai già un server web? Sai programmare in javascript e/o php e/o altro?) sia come dovrebbe funzionare il tutto (esempio "il giocatore digita un codice sulla tastiera di Arduino, quindi se corrisponde all'ultima password generata allora apre un relè che a sua volta apre la cassaforte").

Salve ragazzi, inanzi tutto vi ringrazio per l'aiuto che mi state dando, vi spiego meglio: (ovviamente non devo conservare oggetti di valore o altro ahaahh).
sto realizzando un sito web (mettiamo caso di un negozio di alimentari locale) dove aggiungo gli articoli al carrello mettiamo caso quindi parliamo di acquisti online, arrivati al pagamento, oltre al pagamento, per ritirare la merce comprata mi servirò di un codice che dovrò generare al momento dell'acquisto. (questo codice ha una lunghezza fissa es: 9 cifre (numeri e/o lettere)): quando avrò generato il codice, e mi reco allo (sportello/al negozio alimentari per esempio) ci sarà questa cassa chiusa, utilizzando arduino e quindi display LCD, tastierino, servo motore e modulo ethernet, l'utente finale inserirà il codice che hanno generato dal sito, e se la password/codice è giusto la cassa si aprirà. ecco un esempio del mio codice.

#include <Servo.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#define LED_PIN 11
#define Password_Length 6 // Inserire la lunghezza della password se la password è lunga 7 caratteri inserire 8

char Data[Password_Length]; 
char Master[Password_Length] = "12345";   //Modifica la password 
byte data_count = 0, master_count = 0;
bool Pass_is_good;
char customKey;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x27, 16, 2);  
Servo myservo;

void setup(){
  lcd.init(); 
  lcd.backlight();
  pinMode (LED_PIN, OUTPUT);
  analogWrite (LED_PIN, 50);
  Serial.begin (9600);
myservo.attach (10);
myservo.write (0);  
}

void loop(){

  lcd.setCursor(0,0);
  lcd.print("INSERIRE PASS");
  customKey = customKeypad.getKey();
  if (customKey){
    
    Data[data_count] = customKey; 
    lcd.setCursor(data_count,1); 
    lcd.print ("*");
   Serial.println(Data[data_count]); 
    data_count++; 
    }

  if(data_count == Password_Length-1){
    lcd.clear();
  if(!strcmp(Data, Master)){
      
      lcd.print("PASS CORRETTA");
      delay (1000);
      myservo.write (180);
      }
    else{
      lcd.print("PASS ERRATA");
      delay(1000);
      }
    lcd.clear();
    clearData();  
  }
}

void clearData(){
  while(data_count !=0){
    Data[data_count--] = 0; 
  }
  return;
}

questo è il codice senza la scheda ethernet, infatti funziona da semplice cassaforte da aprire con password che arduino già conosce.
Questo invece è la funzione (che premesso non ho creato io ma ho trovato sul web)

<TITLE>Numeri casuali</TITLE>

<SCRIPT>

today=new Date();
jran=today.getTime();

function Casual()
   {
   ia=9301;
   ic=49297;
   im=233280;
   jran = (jran*ia+ic) % im;
   N1=eval(document.forms[0].elements[0].value);
   N2=eval(document.forms[0].elements[1].value);
   document.forms[0].elements[3].value = Math.ceil( (jran/(im*1.0)) *(N2-N1) ) + N1 - 1;
   document.forms[0].elements[4].value += document.forms[0].elements[3].value + " ";
   }

</SCRIPT>


<CENTER>
<FORM>

<TABLE BORDER=0 WIDTH=600>

<TD align="center"><INPUT TYPE="hidden"  VALUE="100000" SIZE=0>
<TD align="center"><INPUT TYPE="hidden"  VALUE="999999" SIZE=0>
<TD align="center"><INPUT TYPE="button" VALUE="Conferma Acquisto" onClick="Casual()"> 
<TD align="center"><INPUT TYPE="text" VALUE="" SIZE=8>

</TABLE>

da adattare al sito web in questione, oppure se c'è una soluzione senza usare JS meglio ancora :smiley: partendo da questi due codici dove devo andare a modificare il tutto?

E' ovvio che il tutto debba avvenire in remoto e non in locale altrimenti non avrebbe un senso :smiley:
grazie per il vostro tempo

ElleLwaliet:
E' ovvio che il tutto debba avvenire in remoto e non in locale altrimenti non avrebbe un senso :smiley:
grazie per il vostro tempo

Ecco, pensavo di essermi sbagliato ma non era cosi....

Per fare ciò però necessiti di un IP statico a livello di rete telefonica, oppure usare dei server DNS dinamici tipo no-ip.

La cosa diventa un pochetto difficile perché tutta la gestione dello "store online" dell'esempio deve giacere sul tuo Arduino.

Alan

alanmasutti:
Ecco, pensavo di essermi sbagliato ma non era cosi....

Per fare ciò però necessiti di un IP statico a livello di rete telefonica, oppure usare dei server DNS dinamici tipo no-ip.

La cosa diventa un pochetto difficile perché tutta la gestione dello "store online" dell'esempio deve giacere sul tuo Arduino.

Alan

Esatto, volevo infatti sapere se era possibile fare ciò oppure lasciare perdere questa strada, avevo anche letto di passare i dati all'IP di arduino

Riguardo alla fattibilità, si può fare, ma magari aiutandosi con un PC, oppure un Raspberry.... in questo campo però non sono per nulla esperto, ma in qualche modo se si vuole lo si può fare

Alan

ElleLwaliet:
Esatto, volevo infatti sapere se era possibile fare ciò oppure lasciare perdere questa strada, avevo anche letto di passare i dati all'IP di arduino

Ok, ora hai spiegato un po' meglio, anche se "server web remoto" è ancora abbastanza generico , ma immagino che sia un server web in hosting (tipo Aruba) quindi su internet.

Ora, prima di pensare al codice della pagina web ed Arduino, credo che ti occorra conoscere come si fanno comunicare due programmi via internet, e le varie problematiche connesse.

La prima è l'indirizzo IP, come ti hanno accennato, ossia la rete locale dove si trova Arduino: ovviamente immagino sia una qualche ADSL del "negozio fisico" dove c'è questa sorta di "sportello" automatico. Ma gli apparati interni alla rete locale non sono raggiungibili dall'esterno (mentre loro sono generalmente autorizzati ad accedere a risorse esterne), quindi hai due opzioni: una con metodo "push" ed una "pull". Provo a spiegarti, in modo abbastanza completo spero, ma senza entrare in troppi dettagli, per farti però capire che ci sono varie cose che devi considerare quando ci deve essere una comunicazione distribuita come questa.

Il metodo "push" è più o meno quello che stai pensando tu, ossia viene generato sul sito web il codice random, e questo lo deve comunicare ad Arduino. Primo problema: l'indirizzo IP della rete dove si trova Arduino è variabile, ossia il provider ne assegna uno (diciamo "a caso" tra i suoi indirizzi) ogni volta che il modem/router si conette a internet. Questo significa che l'IP sarà sempre lo stesso ma solamente fino a che non si disconnette per qualche ragione (va via la corrente, o il provider fa dei lavori e ti disconnette temporaneamente, o il modem si blocca e devi riavviarlo, eccetera).
Questo puoi ovviarlo o "comunicando" al server il tuo indirizzo IP ad ogni cambiamento, oppure utilizzando un qualche servizio di "Dynamic DNS" il quale, grazie ad una configurazione che quasi tutti i modem router recenti hanno, viene informato automaticamente del nuovo IP, che resta associato ad un nome che tu avrai scelto.
Ci sono vari servizi gratuiti di Dynamic DNS, ma spesso richiedono di "rinnovare" il nome ogni 30 giorni, e la cosa è seccante per cui ti consiglio QUESTO che, almeno per ora, è gratuito e senza obbligo di rinnovo periodico.
Una volta fatto questo (registrazione Dynamic DNS ed impostazione del modem per aggiornare l'IP) devi aprire una porta sul firewall del modem/router per permettere dall'esterno di raggiungere Arduino, e questo però devi vederlo tu. La porta può essere una qualunque a tua scelta da 1024 in su.
Infine a quel punto devi impostare Arduino come server per accettare connessioni su quella porta ed acquisire dalla GET la password da usare per il prossimo cliente che memorizzerai in una variabile. Però dato che Arduino sarebbe di fatto esposto su internet, devi anche fare in modo che solamente il tuo web server possa contattare Arduino, quindi in qualche modo dovresti creare qualche protezione, ad esempio verificando l'IP che ti ha contattato o un qualche parametro "segreto" che ti passa a parametro della GET.

Il metodo invece "pull" prevede che sia Arduino a contattare il web server quando un cliente ha digitato una password, per verificare che corrisponda. Questo non necessita di una configurazione del router né del Dynamic DNS, però c'è il problema che la pagina che Arduino invocherà sul tuo web server deve "conoscere" l'ultima password generata. Il che significa che quantomeno dovresti mettere questa informazione dentro ad un DB locale (ma gli hosting spesso includono anche un piccolo DB gratuitamente), oppure in una qualche variabile a livello di server (spesso chiamata variabile "Application"). Ovviamente anche il web server deve essere sicuro che a contattarlo sia il tuo Arduino, anche in questo caso o IP (ma allora siamo daccapo con gli IP dinamici) o un qualche codice identificativo "segreto". Ma questi meccanismi sono spesso normali funzioni già presenti nei server web.

Pertanto è anche per questo che ti chiedevo quale fosse il tuo livello di conoscenza lato web server e di linguaggi.

Più o meno questo è quanto, vedi tu.

Ciao, grazie per la delucidazione ahaah, a quanto ho visto c'è dietro questo molto di più di quanto mi aspettavo e va oltre le mie conoscenze base dei DB e il lato web, credo che sia da studiare tutto ciò e credo sia inutile che qualcuno mi scriva il codice che devo inserire senza capire che ci fanno determinate variabili lì, quindi grazie mille del consiglio a tutti :slight_smile: