Trasformare Arduino in Server

Salve ragazzi, scusate se rompo sempre. Dopo aver fatto un po di esperimenti con arduino, ethernet shield, rele stadio pilota e luce 220V vorrei rendere un pò più serio il mio progetto.

Quello che vorrei fare è tramite Smartphone (Android o IOS) far eseguire dei comandi ad arduino. Ora la soluzione più semplice è che su Arduino + Ethernet Shield realizzo una sorta di Sito web con pulsanti ed altro e poi Collegandomi all indirizzo IP di Arduino posso eseguie operazioni, per far ciò ci sono già riuscito.

Quello che vorrei far invece è avere una applicazione sullo Smartphone che invia richieste ad arduino, trasformare quindi arduino in un server che rimane in ascolto e accetta comandi in INPUt e poi li interpreta.

E' possibile fare una cosa del genere? Potete aiutarmi please?

Grazie a tutti

Sì è possibile però se ci carichi sopra le librerie per gestire il collegamento ethernet, poi un serverino web, alla fine di risorse non è che te ne restino molte libere per il tuo codice. Se si tratta di aprire/chiudere dei contatti bene, ma se devi fare cose più complesse non so quanto spazio di manovra tu possa avere. Forse ti converrebbe di più l'inverso, ossia un'applicazione lato smartphone più completa e l'Arduino che deve solo eseguire i comandi inviati, niente web server.

Ok allora mi sono espresso male, quello che vorrei fare io è proprio questo, un applicazione smartphone che manda dei comandi ad Arduino, arduino deve solo eseguire?

Tipo lato smartphone manderò ad Arduino una stringa in questo modo (è un esempio)

PIN=1&MODE=ON

Arduino fa il parser ed andrà a dare corrente al PIN 1....

Mi potete aiutare?

Guarda che se nell'IDE vai negli esempi, sia per l'Ethernet che per il WiFi ... trovi un esempio già fatto di Server che fa più o meno quello che vuoi tu (... aspetta di essere interrogato e manda dei valori) ... studiatelo e poi adattalo alle tue esigenze !

Guglielmo

Ciao Grazie io avevo utilizzato lo schetch

WebServer non so se anche tu intendevi quello in particolare il codice è questo

void loop()
{
  if (client.connected()) {
    if (client.available()) {
      // read incoming bytes:
      char inChar = client.read();
if(inChar="pippo"){
   eseguiMedoto1();
}else
   eseguiMedoto2();
        
      }
    }   
  }

Quindi vado a leggere la stringa che il programma Smartphone ha inviato e lui esegue un metodo ecc ecc giusto?

Se è cosi, diciamo che mi torna tutto, credevo più he alro esistesse un altro meccanismo cmq ok.

Ora se ho capito tutto come dovrebbe essere formata la chiamata dal programma Smartphone? (Supponiamo di avere Android)

No, perdona ma ... non ci siamo ...

Prima di affrontare un progetto così ... ti devi fare delle migliori BASI di C ... e dimostri le tue lacune qui :

char inChar = client.read();
if (inChar = "pippo") {

Primo, se dichiari inChar di tipo char (che è giusto) come poi fai ad aspettarti che contenga più di UN carattere ... ... secondo la condizione di uguaglianza in C è == e non = :roll_eyes:

Così purtroppo non arrivi da nessuna parte ... ripeto ... fatti prima solide basi di C (... con programmini più semplici in cui svisceri le varie istruzioni) e poi affronti questi problemi ...

Guglielmo

si hai ragione ma questo pezzetto di codice l ho scritto al volo era solo per far capire niente di più. Sono un programmatore JAVA quindi so che le uguaglianze si fanno con == è stato un errore dovuto alla fretta più che altro

Ok, ma ... C è diverso da Java e ... ti tocca studiarlo se vuoi arrivare rapidamente a fare qualche cosa ... XD XD XD

Guglielmo

sicuramente....

comunque il concetto che ho espresso prima è corretto? Cioè il software su Arduino lo devo costruire in quel modo? E la chiamata dal app smartphone come deve essere fatta? Piu che altro mi manca il passaggio da smartphone ad Arduino

Supponendo che Arduino sia collegato tramite LAN al indirizzo 192.168.1.110 come faccio a passargli l'informazione?

Se sei collegato tramite LAN allora guarda l’esempio che c’è nella Ethernet … WebServer … nella

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

… ricevi un carattere alla volta dalla richiesta HTTP GET che farai dal tuo smartphone. Devi aggiungere una parte che memorizzi questi caratteri uno ad uno in modo da avere un’immagine completa della richiesta … un qualche cosa tipo :

while (client.connected()) {
      if (client.available()) {
        inChar = client.read();
        if (WiFi_Idx < WiFi_BUFFERSIZE) {
          WiFi_Data[WiFi_Idx] = inChar;
          WiFi_Idx++;
        } else {
          << qui devi gestire l'overlow del buffer>>
        }

in modo da avere nell’array WiFi_Data (… nell’esempio) la richiesta e poi devi fare il parse alla ricerca della “GET /” che troverai, appunto, in una richiesta HTTP GET , per poi recuperare il comando trasmesso … :wink:

Guglielmo

si si mi è chiaro, per il momento ti ringrazio molto, appena rientro a casa proverò a tirare giù, lo sketch e il programma per smartphone sperando di non avere problemi ma credo di no.

Per il momento mi interessa questo poi dopo avrò bisogno di consigli su come integrarlo con l impianto elettrico di casa mia. L'obiettivo è quello di utilizzare l'attuale impianto anche quando arduino è spento ed inoltre non vorrei che fossero due impianti separati ma un unico impianto, tipo se accendo la Luca con il tasto fisico, vorrei che sul programma SmartPhone sia segnalato che la luce è accesa e quindi dallo smartpone la posso spegnere. Non so se è chiaro

bircastri: Per il momento mi interessa questo poi dopo avrò bisogno di consigli su come integrarlo con l impianto elettrico di casa mia.

Se fai un po' di ricerche sul forum ... troverai DECINE di progetti di questo tipo e potrai prendere spunto ;)

Guglielmo

si si sto facendo un pò di ricerche ma non sono espertissimo di elettronica e di impianti elettrici quindi credo di aver bisogno di un aiutino di tanto in tanto

Ragazzi ho creato questo script e diciamo che ci siamo nel senso che riesco a far eccitare il relè stadio pilota (autocostruito).

Per utilizzare lo sketch per il momento tramite browser passo all’indirizzo ip la stringa ON9 significa che accendo il led 9, OFF9 spengo il led 9.

Ora funziona tutto perfettamente, il problema è che se collego il rele al pin 9 si accende e si spegne, se invece lo collego a qualsiasi altro LED non funziona nulla anzi è come se Arduino andasse in TILT, mi sapete dire il perchè?

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 
byte ip[] = { 192, 168, 1, 177 }; // indirizzo IP della shield
byte gateway[] = { 192, 168, 1, 1 }; // indirizzo ip del router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); 

int pin1 = 1; // LED pin
int pin2 = 2; // LED pin
int pin3 = 3; // LED pin
int pin4 = 4; // LED pin
int pin5 = 5; // LED pin
int pin6 = 6; // LED pin
int pin7 = 7; // LED pin
int pin8 = 8; // LED pin
int pin9 = 9; // LED pin
int pin10 = 10; // LED pin
int pin11 = 11; // LED pin
int pin12 = 12; // LED pin
int pin13 = 13; // LED pin
String readString; 
boolean LEDON = false; 

void setup(){
Ethernet.begin(mac, ip, gateway, subnet);

pinMode(pin1, OUTPUT);
pinMode(pin2, OUTPUT);
pinMode(pin3, OUTPUT);
pinMode(pin4, OUTPUT);
pinMode(pin5, OUTPUT);
pinMode(pin6, OUTPUT);
pinMode(pin7, OUTPUT);
pinMode(pin8, OUTPUT);
pinMode(pin9, OUTPUT);
pinMode(pin10, OUTPUT);
pinMode(pin11, OUTPUT);
pinMode(pin12, OUTPUT);
pinMode(pin13, OUTPUT);

Serial.begin(9600);
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
   boolean currentLineIsBlank = true;
   while (client.connected()) {
     if (client.available()) {
       char c = client.read();
       readString.concat(c); 
       //Serial.print(c);
       if (c == '\n' && currentLineIsBlank) {
       
        // Serial.print(readString);
        //a questo punto avrò la stringa completa di GET comando da eseguire HTTP 
        //devo eliminare il get e http e interpretare il comando
        readString = getValue(readString, ' ', 1);
        //Serial.print(readString);
         if(readString.indexOf("ON") > 0) {
           //in questo caso devo leggere in pin ed accendere la luce
           //Serial.println(readString);
           String prova = readString.substring(3);
           int pinOn = prova.toInt();
           digitalWrite(pinOn, HIGH); 
           LEDON = true;
         }else if (readString.indexOf("OFF")>0){
           //in questo caso devo leggere in pin e spegnere la luce
           //Serial.println("pippo ");
           String prova = readString.substring(4);
           int pinOn = prova.toInt();
           digitalWrite(pinOn, LOW); 
           LEDON = false;
         }
         
         if (LEDON) {
           client.println("LUCE-ACCESA");
         }
         else
         {
           client.println("LUCE-SPENTA");
         }
         readString="";
         client.stop();
      
      }//FINE IF DI LETTURA 
    }//FINE IF CLIENT 
  }//FINE WHILE 
 }//FINE IF PRINCIPALE 
}//FINE LOOP


String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}//fine metodo getvalue

Se faccio 192.168.1.177/ON10 mi esce dal browser la finestra salva pagina con nome, se invece lo collego al PIN13 non ho errori di questo tipo ma il rele rimane sempre eccitato.
Sapete dirmi dove sbaglio?

Fai stampare pinOn sul monitor seriale. Ho guardato molto superficialmente ma ho l'impressione che quando il numero è formato da due cifre ne becchi solo una. Hai contato correttamente - inoltre - l'indice della stringa?

Allora credo di aver risolto, i calcoli sono corretti nel senso che se metto un numero a 2 cifre funziona il pin lo rileva correttamente solo che ritengo il problema dipenda dalla Ethernet Shield in quanto i PIN 13 12 11 10 sono utilizzati da lei infatti tutti gli altri PIN funzionano perfettamente. Ovviamente è una mia supposizione, chiedo a voi che siete più esperti

Certo, se usi PIN già usati dalla shield... Il troppo panettone mi ha impedito di pensare a questo dettaglio!

credo che la lib wevduino faccia a caso tuo