Data is missing when receiving back over WiFi

Hi,

I have two arduino's (a Portenta H7 and a Uno Wifi rev2) that must communicate with each other over 2.4GHz (WiFi-frequency).

On the arduino Portenta there is an acces Point where the Arduino Uno WiFi connect with. Then the Arduino Uno send the word "START\n" and the Portenta start measuring the value on the analog port (together with the time). when 1000 measurements have been performed, the data is transferred over WiFi to the Arduino Uno WiFi. But something goes wrong here.

If you look at the outputs of both arduino's (see below) all values are printed on the arduino Portenta. But on the Arduino Uno Wifi only the last values are printed. What am I doing wrong here?

output Arduino Portenta H7:

web server is running
Device connected to AP
new client
----------------start measuring---------
----------------end measuring---------

39495691;81.00;0
39495759;74.00;1
39495825;75.00;2
39495893;73.00;3
.....
.....
39563911;67.00;997
39563978;69.00;998
39564046;71.00;999#

client disconnected

Output Arduino Uno Wifi rev2:

%% Connected %%
;990
39563497;69.00;991
39563564;72.00;992
39563632;74.00;993
39563704;70.00;994
39563771;72.00;995
39563844;70.00;996
39563911;67.00;997
39563978;69.00;998
39564046;71.00;999

Here is the code for the Arduino Portenta:

/*
 * Code for the Arduino Portenta H7.
 * This code set up an acces point where an other device can connect to.
 * First an acces point is created
 */
#include <WiFi.h>
#include "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;
bool START = false; // true when the arduino is recording.

double amplitude_array[1500]; // array that save the analog values
unsigned long timestamp_array[1500]; // array that save the time of each corresponding analog values

int analogValue = 0; // read analog value from port
double volt = 0.00; // converted analog value
double voltageLevel = 2.00; // minimum amplitude to detect a high level.
int numberOfHigh = 8; // how many times the ADC high must read to detect a pulse.

//int n = 0; // current measurement number
int numberOfMeasurements = 1000; // wanted number of measurements
int x = 0;

WiFiServer server(23); // start Telnet server

void setup() {
  WiFi.config(IPAddress(192, 168, 3, 1)); // local IP address
  Serial.print("Creating access point named: ");
  Serial.println(ssid);
  //Create the Access point
  status = WiFi.beginAP(ssid,pass);
  if(status != WL_AP_LISTENING){
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }
  delay(10000);// wait 10 seconds for connection:
  server.begin();// start the web server
  Serial.println("web server is running");
}

void loop() {
  
 // check if a client is connected (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
      Serial.println("Device connected to AP");
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      Serial.println("Device disconnected from AP");
    }
  }

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

  if (client) {                             // if you get a client,
    Serial.println("new client");           

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

      Serial.println("----------------start measuring---------");
      measureOnAnalogPort(); // call function to detect pulses
      Serial.println("----------------end measuring---------");

      String bufferToWrite = "";
      int u = 0;
      for (int x = 0; x< numberOfMeasurements; x++){
        // eerst in buffer steken en dan 
        u++;
        bufferToWrite = bufferToWrite + "\n" + timestamp_array[x] + ";" + String(amplitude_array[x],2) + ";" + String(x);
        if (u == 50){
          client.print(bufferToWrite);
          Serial.print(bufferToWrite);
          bufferToWrite = "";
          u = 0;
         }
       }
      bufferToWrite = bufferToWrite + "#" + "\n" + "\n";
      client.println(bufferToWrite);
      Serial.print(bufferToWrite);


      break;
    }
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}


// take analog value and time
void measureOnAnalogPort(){ 
    for (int n = 0; n< numberOfMeasurements; n++){
    amplitude_array[n] = analogRead(A0); // detect pulse (high level)
    timestamp_array[n] = micros(); // set corresponding time in array
  }
}

And here is the code for the Arduino Uno WiFi rev2:

/*
 * Code for the Arduino Uno WiFi rev2.
 */
#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h" // use seperate file for ssid/pass
#define LF 0x0A // enter

///////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 status = WL_IDLE_STATUS;     // the WiFi radio's status
IPAddress server(192,168,3,1);  // IP of the server
WiFiClient client;


void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("%%Communication with WiFi module failed!%%");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
  }
  Serial.println("%% Connected %%");
}


void loop() {
// WHEN command "START" is writen to the serial port -> request to start send to the server
bool DataIsPrinted = false;
char input_serial_str[10]; 
//Serial.print("start\r\n");
int idx = 0;
bool endOfDataFile = false;

do{
if (Serial.available() > 0) {
    input_serial_str[idx] = Serial.read();
    if (input_serial_str[idx] == '\n') { // detect '/n'
        input_serial_str[idx] = 0;
        idx = -1; // detect 'START'
        if ((input_serial_str[0] == 'S') && (input_serial_str[1] == 'T') && (input_serial_str[2] == 'A') && (input_serial_str[3] == 'R') && (input_serial_str[4] == 'T')){
          if (client.connect(server, 23)) {
            String data = "";
            do{
              if (client.available()) {
                char c = client.read();
                //Serial.print(c);
                if (c=='#'){ // character '#' is the end of the data transfer
                  endOfDataFile = true;
                }else{ // other conditions -> data transfer continue
                  data = data + c;
                }
              } 
            }while (endOfDataFile == false);
            Serial.println(data); // data without the HTTP header
            DataIsPrinted = true;
          } else {
            Serial.println("%%connection failed%%");
          }
        }  
    }
    idx++;
  }
        // stop the client
    if (!client.connected()) {
      client.stop();
  }
}while( DataIsPrinted == false);
}

can you explain what the output is?

the last 3 lines from both seem the same to me

why is the linefeed, "\n" in the middle of the string instead of at the end?

Thank you for your answer.
The output is in the following format:

<time in µs>; <pulse amplitude(0-255)>;<iteration_number>
39563911;67.00;997
39563978;69.00;998
39564046;71.00;999

Indeed, the last lines are the same. But the output of the Arduino Uno Wifi is all I receive. I would also like to receive all data from the beginning. The problem is that I only receive the last 9 lines of data on the Arduino Uno Wifi.

Of course I can also put the linefeed at the end of the string. But I think this is not the reason why I am not getting all my data on the receiving arduino.

can you explain your arduino code

it looks like it only monitors the wifi input after some serial input is received and then only if it matches "START".

why not just read (client.read()) and print any wifi input that is received

void loop() {
    if (client.available())
        Serial.print (client.read();
}
1 Like

@gcjr
At the end of all data I send the character '#'. When the receiver encounters that character, it knows that all data has been sent. But maybe I should change that part a bit...

is there something specific the code should do when all the data has been received? do you care? why?

@gcjr Thanky you for you help.
I've implemented this into my code and it works.