Generare richiesta Get al arrivo di in segnale IR

Buongiorno,

Ho replicato il progetto di una automobilina tramite L298N per il controllo dei motori e una scheda con ESP8266 e WiFI. Da un applicazione android vengono inviati i comandi tramite una stringa del genere: Http://192.168.4.1/?Stato=A (Dove A sta per avanti).

Ho aggiunto un sensore IR per poter inviare comandi anche con questo. I comandi IR arrivano e vengono anche eseguiti ma per come ho impostato/pasticciato il codice i comandi IR si sovrappongono a quelli WIFI e vanno in conflitto.

Credo che la soluzione sia un richiesta GET in modo che alla ricezione di un segnale IR anzichè eseguire direttamente il comando venga invece prima inviata una stringa tramite WIFI e poi eseguita.
Non riesco però ad implementare questa richesta e non so nemmeno se è fattibile a dire il vero.

Allego il codice se qualcuno può aiutarmi grazie mille!


// Include le Librerie per il Server WiFi
#include <ESP8266WiFi.h>                              
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>


// Include le Librerie per il sensore IR
#include <IRremote.h>


// Definire Motori su Modulo L298N
#define ENA   D8    // Motore Destra  
#define IN_1  D7    // In1 motore Destra       
#define IN_2  D6    // In2 motore Destra      
#define IN_3  D5    // In3 motore Sinistra        
#define IN_4  D4    // In4 motore Sinistra       
#define ENB   D3    // Motore Sinistra    



// Impostare Ricevitore IR 
const int pinRicevitoreIR = D1;      // pin a cui  collegato il ricevitore
IRrecv irrecv(pinRicevitoreIR);      // pin a cui  collegato il ricevitore
decode_results risultato;            // salva il risultato ricevuto dal rilevatore IR


String command;       //String per lo stato di comando


// Impostare velocita' motori
int velocita = 1023;   



// Creazione di un server web in ascolto sulla porta 80
const char* ssid = "Tank WiFI";
ESP8266WebServer server(80);


void setup() {
 

Serial.begin(115200);    // inizializza Serial monitor


irrecv.enableIRIn();     // Attiva l'oggetto del ricevitore


//Definire Pin
pinMode(ENA,  OUTPUT); 
pinMode(IN_1, OUTPUT);
pinMode(IN_2, OUTPUT);
pinMode(IN_3, OUTPUT);
pinMode(IN_4, OUTPUT);
pinMode(ENB,  OUTPUT); 


// Connessione WiFi

WiFi.mode(WIFI_AP);
WiFi.softAP(ssid);

IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);

// Starting WEB-server
server.on ( "/", HTTP_handleRoot );
server.onNotFound ( HTTP_handleRoot );
server.begin();
}


void HTTP_handleRoot(void) {
if( server.hasArg("State") ){
Serial.println(server.arg("State"));
}
server.send ( 200, "text/html", "" );
delay(1);
}


// Impostazioni per i motori
void Avanti(){ 
digitalWrite(IN_1, LOW);
digitalWrite(IN_2, HIGH);
analogWrite (ENA, velocita);

digitalWrite(IN_3, HIGH);
digitalWrite(IN_4, LOW);
analogWrite (ENB, velocita);
}


void Indietro(){ 
digitalWrite(IN_1, HIGH);
digitalWrite(IN_2, LOW);
analogWrite (ENA, velocita);

digitalWrite(IN_3, LOW);
digitalWrite(IN_4, HIGH);
analogWrite (ENB, velocita);
}



void Sinistra(){ 
digitalWrite(IN_1, LOW);
digitalWrite(IN_2, HIGH);
analogWrite (ENA, velocita);

digitalWrite(IN_3, LOW);
digitalWrite(IN_4, HIGH);
analogWrite (ENB, velocita);
}



void Destra(){
digitalWrite(IN_1, HIGH);
digitalWrite(IN_2, LOW);
analogWrite (ENA, velocita);

digitalWrite(IN_3, HIGH);
digitalWrite(IN_4, LOW);
analogWrite (ENB, velocita);
}


void Fermo(){  
digitalWrite(IN_1, LOW);
digitalWrite(IN_2, LOW);
analogWrite(ENA, velocita);

digitalWrite(IN_3, LOW);
digitalWrite(IN_4, LOW);
analogWrite(ENB, velocita);
}




void loop() {

server.handleClient();
command = server.arg("State");
if (command == "A") Avanti();
else if (command == "I") Indietro();
else if (command == "D") Destra();
else if (command == "S") Sinistra();


if (irrecv.decode(&risultato) == true) // vero se si e' ricevuto un messaggio
{Serial.println(risultato.value, HEX);
irrecv.resume();
}
else if (risultato.value == 0xCDB54565) Fermo();
else if (risultato.value == 0xFFFFFFFF) Avanti();


}

Zero risposte! Sto evidentemente sbagliando qualcosa ma non so cosa! Grazie a chi vorra aiutarmi!

Ciao.
Premetto che sono poco ferrato su questi argomenti... Però leggendo il codice mi suona strana l'ultima parte...

if (irrecv.decode(&risultato) == true) // vero se si e' ricevuto un messaggio
{Serial.println(risultato.value, HEX);
irrecv.resume();
}
else if (risultato.value == 0xCDB54565) Fermo();
else if (risultato.value == 0xFFFFFFFF) Avanti();

Verifichi se è arrivato qualcosa col primo if, ma metti la verifica del tipo di messaggio ricevuto negli else... Se il primo if è vero non entrerà mai nei 2 else...
Sicuro che sia corretto?

Grazie per la risposta!
Hai sicuramente ragione ora ricontrollo quella parte!
Quello che vorrei fare però è riuscire ad inviare una stringa del genere: Http://192.168.4.1/?Stato=F quando arriva l'impulso IR, in modo che venga poi letta dal server.
Grazie ancora!

Ciao, non capisco cosa vuoi dire con questa frase :woozy_face:

La parte del sensore IR non la conosco molto bene, ma la parte del WebServer credo che sia da rivedere!

Il server non invia comandi ma risponde a richieste!
Quindi è il client (pagina web o app che sia) che effettua una richiesta in GET oppure POST, PUT o DELETE ed il server risponde con il suo messaggio, che sia HTML, JS, CSS, JSON, un'immagine o semplicemente testo; un'altra possibilità è quella di rispondere solo con l'header di HTTP ad esempio con il codice HTTP 307 e l'header "Location: nuova directory" che serve per fare una redirect!

La sintassi:
/resource?par1=val1&par2=val2
è quella della GET di HTTP.

Ora passiamo alla tua richiesta!!
Tu vuoi che alla richiesta in GET della ROOT ("/") il server riceva il comando e lo esegua!!

Questo vene gestito nella funzione HTTP_handleRoot che è impostata come handler quando chiami il metodo on del server:
server.on ( "/", HTTP_handleRoot );
In sostanza ogni qual volta il server riceva una GET sulla sua root eseguirà HTTP_handleRoot una sola volta!

// Include le Librerie per il Server WiFi
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>


// Include le Librerie per il sensore IR
#include <IRremote.h>


// Definire Motori su Modulo L298N
#define ENA   D8    // Motore Destra  
#define IN_1  D7    // In1 motore Destra       
#define IN_2  D6    // In2 motore Destra      
#define IN_3  D5    // In3 motore Sinistra        
#define IN_4  D4    // In4 motore Sinistra       
#define ENB   D3    // Motore Sinistra    



// Impostare Ricevitore IR
const int pinRicevitoreIR = D1;      // pin a cui  collegato il ricevitore
IRrecv irrecv(pinRicevitoreIR);      // pin a cui  collegato il ricevitore
decode_results risultato;            // salva il risultato ricevuto dal rilevatore IR


String command;       //String per lo stato di comando


// Impostare velocita' motori
int velocita = 1023;



// Creazione di un server web in ascolto sulla porta 80
const char* ssid = "Tank WiFI";
ESP8266WebServer server(80);


void setup() {


  Serial.begin(115200);    // inizializza Serial monitor


  irrecv.enableIRIn();     // Attiva l'oggetto del ricevitore


  //Definire Pin
  pinMode(ENA,  OUTPUT);
  pinMode(IN_1, OUTPUT);
  pinMode(IN_2, OUTPUT);
  pinMode(IN_3, OUTPUT);
  pinMode(IN_4, OUTPUT);
  pinMode(ENB,  OUTPUT);


  // Connessione WiFi

  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);

  // Starting WEB-server
  server.on ( "/", HTTP_handleRoot );
  server.onNotFound ( HTTP_handleRoot );  //Non proprio canonica come cosa!! SECONDO ME EVITEREI DI CHIAMARE QUELL HANDLER MA NE FAREI UNO APPOSITO
  server.begin();
}


void HTTP_handleRoot(void) {
  if ( server.hasArg("State") ) {
    Serial.println(server.arg("State"));
    command = server.arg("State");
    if (command == "A") {
      Avanti();
    } else if (command == "I") {
      Indietro();
    } else if (command == "D") {
      Destra();
    } else if (command == "S") {
      Sinistra();
    }
  }
  server.send ( 200, "text/plain", "OK" );
  delay(1);
}


// Impostazioni per i motori
void Avanti() {
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, HIGH);
  analogWrite (ENA, velocita);

  digitalWrite(IN_3, HIGH);
  digitalWrite(IN_4, LOW);
  analogWrite (ENB, velocita);
}


void Indietro() {
  digitalWrite(IN_1, HIGH);
  digitalWrite(IN_2, LOW);
  analogWrite (ENA, velocita);

  digitalWrite(IN_3, LOW);
  digitalWrite(IN_4, HIGH);
  analogWrite (ENB, velocita);
}



void Sinistra() {
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, HIGH);
  analogWrite (ENA, velocita);

  digitalWrite(IN_3, LOW);
  digitalWrite(IN_4, HIGH);
  analogWrite (ENB, velocita);
}



void Destra() {
  digitalWrite(IN_1, HIGH);
  digitalWrite(IN_2, LOW);
  analogWrite (ENA, velocita);

  digitalWrite(IN_3, HIGH);
  digitalWrite(IN_4, LOW);
  analogWrite (ENB, velocita);
}


void Fermo() {
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, LOW);
  analogWrite(ENA, velocita);

  digitalWrite(IN_3, LOW);
  digitalWrite(IN_4, LOW);
  analogWrite(ENB, velocita);
}




void loop() {
  server.handleClient();


  ///////////////////////////// DA SISTEMARE ////////////////////////
  if (irrecv.decode(&risultato) == true) { // vero se si e' ricevuto un messaggio
    Serial.println(risultato.value, HEX);
    irrecv.resume();
  }
  else if (risultato.value == 0xCDB54565) Fermo();
  else if (risultato.value == 0xFFFFFFFF) Avanti();

  //Una possibile soluzione potrebbe essere:
  if (irrecv.decode(&risultato) == true) { // vero se si e' ricevuto un messaggio
    Serial.println(risultato.value, HEX);
    if (risultato.value == 0xCDB54565){
      Fermo();
    }else if (risultato.value == 0xFFFFFFFF){
      Avanti();
    }
    irrecv.resume();
  }

}

Ora, non so esattamente come vuoi sviluppare l'applicazione lato client, ma se vuoi che vi sia comunicazione bilaterale devi usare una WebSoket.

Scrivi in questo topic che fin che so ti posso aiutare!!
Alan

Direi proprio di no. Il server è già il programma che gira su ESP8266, inviare a se stesso il comando mi pare improponibile.
Dubito inoltre che tu possa mischiare un programma server e il sensore IR.
Il sensore IR si appoggia ad un timer e richiede tempistiche che (credo) con il server web che gira fanno a cazzotti.

Comunque la parte IR deve essere tutta dentro al primo if (come ti hanno già detto)

if (irrecv.decode(&risultato) == true)    // vero se si e' ricevuto un messaggio
{ Serial.println(risultato.value, HEX);
  switch (results.value) {
    case 0xCDB54565: Fermo();  break;
    case 0xFFFFFFFF: Avanti(); break;
  }
  irrecv.resume();
}

Innanzitutto grazie a tutti per le risposte!!

Ecco pensavo che la soluzione fosse questa, invece era una strada non praticabile.

Come mi avete consigliato ho riscritto la parte del sensore IR e direi che ci siamo!!!

Ora, quando viene inviato il segnale IR, arduino fa prima quello che gli viene richiesto dall'IR (ad esempio fermarsi) e poi riprende ha rispondere ai comandi che gli arrivano dall'app.

Non so perche mi ero fissato con la richiesta GET.
Così com'è adesso funziona come volevo!! Grazie a tutti!!!


void loop() { 

server.handleClient();
command = server.arg("State");
if      (command == "A") Avanti();
else if (command == "I") Indietro();
else if (command == "D") Destra();
else if (command == "S") Sinistra();
else if (command == "F") Fermo();
else if (command == "G") Gioco();


if (irrecv.decode(&risultato)) {
Serial.println("Ricevuto = ");
Serial.print(risultato.value,HEX);


switch (risultato.value) {

//Pulsante X
case 0xCDB54565:
Fermo();
delay(10000);
break;

//Pulsante Y
case 0xC1AAC936:
Sinistra();
delay(3000);
Destra();
delay(3000);
Fermo ();
delay(10000);
break;
}

irrecv.resume();
}
}

Ciao, non ho capito quindi, hai risolto??

Questa cosa secondo me non va fatta qua ma nell'handler corrispondente!! Ovvero nella funzione HTTP_handleRoot!!

Detto questo, che applicazione è quella che usi per fare le richieste in GET? [EDIT]: L'app ha necessità di sapere in che stato è il programma o non importa??

Poi, per cortesia quando posti codice usa la formattazione e l'indentazione che lo rendono molto piu leggibile( CTRL + T su Win, CMD + T su Mac)

Alan

Si ho risolto, anche se non come pensavo! Ma per ora l'importante è che tutto funzioni!!
Sbagliavo nella gestione del segnale IR e pensavo che solo una richesta GEt avrebbe risolto. Invece bastava scrivere bene il programma!

Sicuramente questa parte devo studiarmela per bene!! Penso che anche il resto del codice per come l'ho scritto abbia ampi margini di miglioramento!

L'applicazione è creata con mit app inventor, e a seconda del tasto premuto, invia una stringa del genere: Http://192.168.4.1/?Stato=F che viene letta da arduino, che poi si comporta di conseguenza.

Per come l'ho scritto adesso non serve che l'applicazione conosca lo stato del programma. Certo sarebbe molto interessante, ma non sono ancora in grado di avventurarmi in una comunicazione bidirezionale del genere.

Chiedo scusa e grazie ancora!!!

Allora visto che l'hai sviluppata tu, sconsiglio di fare una GET sulla root perchè per non specifichi che risorsa vuoi raggiungere e consiglio di usare ad esempio il path "/command", non influisce sul funzionamento del programma però ha più coerenza con quello che fai!!

Per questo se hai piacere di approfondire siamo qua... :stuck_out_tongue_winking_eye: (non sono navigato ma finché so posso aiutare!!)
Alan

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.