Problema con logica degli stati durante comunicazione bluettoth

Buonasera, Vorrei un aiuto per capire come mai il codice non fa ciò che voglio. Più In particolare in questo esempio uso un' arduino portenta h7 che funge da server con un imu bno055 attaccato.
Sostanzialmente il problema dovrebbe essere banale. Infatti lo stesso codice, l ho creato con comunicazione bluetooth: usando un'app come client, premendo il tasto per rendere lo stato readacc=1, riesco a leggere in realtime come variano i dati che voglio leggere (fin quando non premo il tasto che rendo readacc=0). Se uso la comunicazione wifi la stessa logica non vale. Infatti premo il tasto per rendere lo stato readacc=1 e solo una riga viene restituita come output. Non capisco se sto sbagliando qualcosa nella lettura dello stato oppure altro.

#include <WiFi.h>
#include "arduino_secrets.h"
#define Serial _UART_USB_

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>

#define BNO055_SAMPLERATE_DELAY_MS (100)

// Check I2C device address and correct line below (by default address is 0x29 or 0x28)
//                                   id, address
Adafruit_BNO055 bno = Adafruit_BNO055(-1, 0x28);





///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;             // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
int read_acc=0;
WiFiServer server(80);

void setup() {
  // put your setup code here, to run once:
  _UART_USB_.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  delay(1000);
  bno.setExtCrystalUse(true);
  
 
  
  _UART_USB_.println("Access Point Web Server");

  pinMode(LEDR,OUTPUT);
  pinMode(LEDG,OUTPUT);
  pinMode(LEDB,OUTPUT); 
digitalWrite(LEDG, HIGH); 
digitalWrite(LEDB, HIGH); 
digitalWrite(LEDR, HIGH); 

  // by default the local IP address of will be 192.168.3.1
  // you can override it with the following:
  // WiFi.config(IPAddress(10, 0, 0, 1));

  if(strlen(pass) < 8){    
    _UART_USB_.println("Creating access point failed");
    _UART_USB_.println("The Wi-Fi password must be at least 8 characters long");
    // don't continue
    while(true);
  }
    
  // print the network name (SSID);
  _UART_USB_.print("Creating access point named: ");
  _UART_USB_.println(ssid);

  //Create the Access point
  status = WiFi.beginAP(ssid,pass);
  if(status != WL_AP_LISTENING){
    _UART_USB_.println("Creating access point failed");
    // don't continue
    while (true);
  }

  // wait 10 seconds for connection:
  delay(10000);

  // start the web server on port 80
  server.begin();

  // you're connected now, so print out the status
  printWiFiStatus();
  
}

void loop() {

          
 // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // a device has connected to the AP
      _UART_USB_.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      _UART_USB_.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // listen for incoming clients
  
  if (client) {                             // if you get a client,
    
    String currentLine = "";                // make a String to hold incoming data from the client
  
    while (client.connected()) {            // loop while the client's connected
     
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
         
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
           // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      
        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LEDR, LOW);
          client.println("The led is high ");
          _UART_USB_.print("PROVALOW:  ");
          _UART_USB_.println(currentLine);
          readacc=1;
          if (readacc==1){
          imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

            /* Display the floating point data */
            _UART_USB_.print("X: ");
            _UART_USB_.print(euler.x());
            _UART_USB_.print(" Y: ");
            _UART_USB_.print(euler.y());
            _UART_USB_.print(" Z: ");
            _UART_USB_.print(euler.z());
            _UART_USB_.print("\t\t");
                    
          }
        }

       
        if (currentLine.endsWith("GET /H")) {
          readacc=0;
          digitalWrite(LEDR, HIGH);  
          client.println("The led is low ");// GET /Lr turns the Red LED off
          _UART_USB_.print("PROVALOW:  ");
          _UART_USB_.println(currentLine);
          
        }
         
         }
        
      }
    }
    // close the connection:
//    client.stop();
//    Serial.println("client disconnected");
  }

  


void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  _UART_USB_.print("SSID: ");
  _UART_USB_.println(WiFi.SSID());

  // print your Wi-Fi shield's IP address:
  IPAddress ip = WiFi.localIP();
  _UART_USB_.print("IP Address: ");
  _UART_USB_.println(ip);

  // print where to go in a browser:
//  Serial.print("To see this page in action, open a browser to http://");
//  Serial.println(ip);
}

Buonasera,

prima di tutto ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato, dopo di che ...

... essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il succitato REGOLAMENTO ... Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nel rispetto del suddetto regolamento nessuno ti risponderà (eventuali risposte verrebbero cancellate), quindi ti consiglio di farla al più presto. :wink:

Buonasera Guglielmo, ero convinto fosse la sezione giusta. Presterò più attenzione la prossima volta. Intanto la ringrazio anche del passaggio nella sezione in italiano. Ho fatto come mi è stato chiesto, presentandomi a tutti. Grazie

nel tuo codice per ogni richiesta "GET /L" stai rispondendo solo e soltanto una volta

readacc=1;
if (readacc==1){

questo pezzo non ha senso, puoi rimuovere readacc completamente e avrai lo stesso comportameto.

@lestofante Grazie della risposta.
Si è vero, quella è una cosa che ho copiato dal codice con comunicazione bluetooth. Non ha senso effettivamente qui. Infatti senza lo stato funziona allo stesso modo: una riga viene data in uscita al serial monitor.
In ogni caso il codice completo prevede vari comandi ma ciò che vorrei inserire è che fino a quando il comando inviato è uno, allora la scheda deve dare continuamente l'output richiesto, in questo caso la lettura dell'imu. Immaginavo che dentro il loop si ripetesse autonomamente, motivo per il quale avevo inserito lo stato.

Allora lo devi mettere dentro il while, o alla fine o all'inizio come mostrato sotto.

Dimenticavo premi CTRL-T nell'IDE arduino così identa il codice e diventa più leggibile.
Ciao.

@Maurotec Grazie anche a te. Quel comando è già dentro il while. Ho creato un'applicazione tramite che invia l'url /L e l'url/H tramite la pressione su 2 tasti. ecco allora che il currentLine è quindi il comando che invio. Quando riceve/L mi deve stampare continuamente la lettura. Con /H si deve semplicemente fermare.

WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,

    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected()) {            // loop while the client's connected

      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then

        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LEDR, LOW);
          client.println("The led is high ");
          _UART_USB_.print("PROVALOW:  ");
          _UART_USB_.println(currentLine);
             imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

            /* Display the floating point data */
            _UART_USB_.print("X: ");
            _UART_USB_.print(euler.x());
            _UART_USB_.print(" Y: ");
            _UART_USB_.print(euler.y());
            _UART_USB_.print(" Z: ");
            _UART_USB_.print(euler.z());
            _UART_USB_.print("\t\t");

        }


        if (currentLine.endsWith("GET /H")) {
           digitalWrite(LEDR, HIGH);
          client.println("The led is low ");// GET /Lr turns the Red LED off
          _UART_USB_.print("PROVALOW:  ");
          _UART_USB_.println(currentLine);

        }

      }

    }
  }

Ok grazie della spiegazione che conferma ciò che avevo già capito. Ora però ti estorco il CTRL-T in cambio della soluzione. :grinning:Quindi premi CTRL-T copia la funzione loop e postala nuovamente, se è identata correttamente io posterò la funzione loop modificata che fa quello che desideri.

Ciao.

@Maurotec il codice che ti ho inviato l'ho identato col tuo metodo. Anzi ti ringrazio, non lo conoscevo. E quando mi serviva un pò d'ordine andavo di tab. Ho provato anche il tuo modo comunque e non funziona. Lo stato per ora lo accantono. Se devo bloccare un'iterazione lo riaggiungo.

void loop() {


  // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // a device has connected to the AP
      _UART_USB_.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      _UART_USB_.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,

    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected()) {            // loop while the client's connected

      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then

        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LEDR, LOW);
          client.println("The led is high ");
          _UART_USB_.print("PROVA:  ");
          _UART_USB_.println(currentLine);
            imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

            /* Display the floating point data */
            _UART_USB_.print("X: ");
            _UART_USB_.print(euler.x());
            _UART_USB_.print(" Y: ");
            _UART_USB_.print(euler.y());
            _UART_USB_.print(" Z: ");
            _UART_USB_.print(euler.z());
            _UART_USB_.println("\t\t");

          
        }


        if (currentLine.endsWith("GET /H")) {
           digitalWrite(LEDR, HIGH);
          client.println("The led is low ");// GET /Lr turns the Red LED off
          _UART_USB_.print("PROVALOW:  ");
          _UART_USB_.println(currentLine);

        }

      }

    }
  }

}


Prova così e fa sapere.

Ciao.

Grazie mille!! Funziona!!

@Maurotec Buonasera, spero tu abbia passato buone vacanze. Vorrei chiederti un aiuto per dei perfezionamenti minimi riguardo la comunicazione wifi. Spero tu possa aiutarmi, senza chiederti tanto disturbo. Purtroppo non sono ancora esperto in comunicazione wifi, infatti questo è il primo uso che ne faccio.
In ogni caso ti giro il codice con un applicazione costituita da soli pulsanti per mettere alla prova il codice. Ci sono 2 problemi:

  1. la ricezione: se spingo on la risposta l'imu si accende e posso leggere con continuità i dati.Spingo off ma non si spegne e la risposta nell'app è che non riesco a caricare la pagina web all'indirizzo http://ip...../ROFF a causa di net::ERR_CONNECTION_RESET. per spegnerlo devo ripigiare on e off più volte (non so se si tratta di un ritardo o un conflitto).

  2. quando pigio SET dopo aver inserito un numero quell'ultimo non viene unito alla currentline come pensavo di riuscire a fare mediante il blocco dell'app.

#include <WiFi.h>
#include "arduino_secrets.h"
#define Serial _UART_USB_

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
  
Adafruit_BNO055 bno = Adafruit_BNO055(55);

#define BNO055_SAMPLERATE_DELAY_MS (100)
float q0,q1,q2,q3,gx,gy,gz,norm,phi;
int Value,readacc;
float radtodeg = 57296/1000;

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;    // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;             // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
int read_acc=0;
WiFiServer server(80);

void setup() {
  

  _UART_USB_.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
   
  /* Initialise the sensor */
  if(!bno.begin())
  {
    /* There was a problem detecting the BNO055 ... check your connections */
    _UART_USB_.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }
  
  delay(1000);
    
  bno.setExtCrystalUse(true);

  
  
 
  
  _UART_USB_.println("Access Point Web Server");

  pinMode(LEDR,OUTPUT);
  pinMode(LEDG,OUTPUT);
  pinMode(LEDB,OUTPUT); 
digitalWrite(LEDG, HIGH); 
digitalWrite(LEDB, HIGH); 
digitalWrite(LEDR, HIGH); 

  // by default the local IP address of will be 192.168.3.1
  // you can override it with the following:
  // WiFi.config(IPAddress(10, 0, 0, 1));

  if(strlen(pass) < 8){    
    _UART_USB_.println("Creating access point failed");
    _UART_USB_.println("The Wi-Fi password must be at least 8 characters long");
    // don't continue
    while(true);
  }
    
  // print the network name (SSID);
  _UART_USB_.print("Creating access point named: ");
  _UART_USB_.println(ssid);

  //Create the Access point
  status = WiFi.beginAP(ssid,pass);
  if(status != WL_AP_LISTENING){
    _UART_USB_.println("Creating access point failed");
    // don't continue
    while (true);
  }

  // wait 10 seconds for connection:
  delay(10000);

  // start the web server on port 80
  server.begin();

  // you're connected now, so print out the status
  printWiFiStatus();
  
}


void loop() {


  // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      // a device has connected to the AP
      _UART_USB_.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      _UART_USB_.println("Device disconnected from AP");
    }
  }

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,

    String currentLine = "";                // make a String to hold incoming data from the client

    while (client.connected()) {            // loop while the client's connected

      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then

        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /RON")) {
          digitalWrite(LEDR, LOW);
          digitalWrite(LEDB, HIGH);
          client.println("ON ");
          _UART_USB_.print("ON");
          _UART_USB_.println(currentLine);
          readacc = 1; // accendo readacc
                    
        } else  if (currentLine.endsWith("GET /ROFF")) {
           digitalWrite(LEDR, HIGH);
           digitalWrite(LEDB, HIGH);
           client.println("OFF ");// GET /Lr turns the Red LED off
          _UART_USB_.print("OFF ");
          _UART_USB_.println(currentLine);
          readacc = 0;  //spengo readacc
        }

        else  if (currentLine.endsWith("GET /SET")) {
           digitalWrite(LEDB, HIGH);
           client.println("Setting a number ");// GET /Lr turns the Red LED off
          _UART_USB_.println("Setting a number");
          String thr= currentLine.substring(9);Value = thr.toInt();
          _UART_USB_.print("Thr: ");_UART_USB_.println(thr);
          _UART_USB_.print("Value: ");_UART_USB_.println(Value);
          _UART_USB_.print("currentLine: ");_UART_USB_.println(currentLine);
         } // end if (currentLine.endsWith("GET /SET"))

      } // end if (client.available()) 
      if ( readacc == 1 ) {
          

          //uint8_t system, gyro, accel, mg ;

          imu::Quaternion quat = bno.getQuat();
          q0= quat.w();
          q1=quat.x();
          q2= quat.y();
          q3=quat.z();
          
          gx = q1 * q3 - q0 * q2;
          gy = q0 * q1 + q2 * q3;
          gz = q0 * q0 + q3 * q3 -0.5f;
          norm = sqrt(gx * gx + gy * gy + gz * gz);                                                             
          norm = 1.0 / norm;
          gx *= norm; gy *= norm; gz *= norm;
          phi = acos(gx); phi = phi*radtodeg;
        
          _UART_USB_.print("IMU=");_UART_USB_.println(phi);
          delay(BNO055_SAMPLERATE_DELAY_MS);
      }
      
    } // end while (client.connected())
  } // end if (client)

} // end loop()

void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  _UART_USB_.print("SSID: ");
  _UART_USB_.println(WiFi.SSID());

  // print your Wi-Fi shield's IP address:
  IPAddress ip = WiFi.localIP();
  _UART_USB_.print("IP Address: ");
  _UART_USB_.println(ip);

  // print where to go in a browser:
//  Serial.print("To see this page in action, open a browser to http://");
//  Serial.println(ip);
}

Grazie in ogni caso

Io non ho esperienza pratica con il web, e quindi potrei sbagliarmi ma non vedo nulla di sbagliato.
L'unica cosa che non mi convince è questa riga:

String thr= currentLine.substring(9);

Dove specifichi solo indice di partenza (9). Ora se currentLine termina con "GET /SET" in thr ci finisce anche questa stringa che non è convertibile in numero. Di substring c'è anche quella che ti permette di specificare il fine indice, sempre che stampando nel serial monitor currentLine ci sia il numero.

Mentre per ERR_CONNECTION... non so dirti se il delay BNO055_SAMPLERATE_DELAY_MS
possa fare cadere la connessione. Aspetta l'utente @cotestatnt sicuramente ne capisce più di me.
Io proverei a verificare se esiste un timeout che una volta scaduto faccia cadere la connessione e da li l'errore, e allora aumenterei questo timeout.

Ciao.

Va bene, grazie delle dritte.
Ho provato a ridurre o ad eliminare il delay. Non mi da più errore! QUindi grazie di nuovo! ma una volta partita la lettura, dura solamente per un pò di tempo, poi si blocca, clicco off e allora manda in output un'ultima sfilza di letture e poi la ricezione dello spegnimento. A differenza di prima, posso ridare l'on e l'off senza notare ritardi eclatanti.
Per quanto riguarda l'altro problemino, il fatto è che ero abbastanza sicuro che col comando join potessi unire le due stringhe. Ciò che invece è la currentLine al momento della pressione di "SET" è currentLine: GET /SET

Ciao

Non ho guardato ancora con molta attenzione il codice, ma l'errore in questione significa che il server per qualche motivo ha resettato la connessione (quindi lato Arduino).

Fino a quelche release fa, c'era lo stesso problema anche su ESP32 (che ultimamente hanno fixato) e questo problema si presentava solo con il browser Chrome ed i suoi derivati...

@yellowred giusto per capire se si tratta della stessa casistica, puoi provare a fare la stessa cosa con Firefox?

Grazie ad entrambi per la disponibilità.
Non sembra ci siano differenze utilizzando motori di ricerca diversi

Scusate se ci provo ancora, nessun'idea? @Maurotec @cotestatnt

Riguardo al codice contenuto in

if ( readacc == 1 ) {

dovresti provare a temporizzarlo con millis() in modo da interrogare il BN ad intervalli regolari senza l'effetto bloccante del delay. Credo che ti possa tornare utile anche per stampare ogni 500ms invece che stampare a raffica.

Ciao.

Il fatto è che per l'uso che ne farò la stampa e implicitamente la lettura dovrà essere a "raffica",

Ok, però andrebbe fatto comunque con millis al posto di delay, rispettando i 100ms tra una interrogazione e l'altra, tempistiche che puoi facilmente modificare. Alcuni chip tollerano male interrogazioni troppo frequenti e non so se questo è il caso del BN tocca studiare il manuale.

Ciao.