Uno Rev2 Wifi server/client connection problems

Good afternoon,
I have two Arduino Uno Rev2 WiFi boards with one as the server, while the other a client. The client uses a ultrasonic sensor to detect if an object goes in front of it. Then sends a GET request to the static IP of the server indicating that someone is blocking its view.

Both the server and client can work, and have worked several times with one another. The problem is that if the client doesn't find the server within 10 minutes, it likely will never find it.

On the other end of this problem is that, if there is connectivity it lasts only an hour or two before freezing up on both ends. I believe that it's client.connect()'s issue, because it takes at least 10 seconds to try and connect before timing out. But also the server freezes as well, so I'm not too sure what the issue is.

I just need a bit of help with making sure that both connect within at least a minute of being reset/powered-on externally, and lasting at minimum 24 hours.

If you can help in any way, thank you and I appreciate your input.

This is the Server code:

#include <SPI.h>
#include "WiFiNINA.h"
#include "arduino_secrets.h" 

#define greenLED 10

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

IPAddress ip(192, 168, 46, 244);
IPAddress dns(8, 8, 8, 8);
IPAddress gateway(192, 168, 46, 1);
IPAddress subnet(255, 255, 255, 0);

WiFiServer server(80);
String readString;

//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(greenLED, OUTPUT);

  while (!Serial) {;}

  digitalWrite(LED_BUILTIN, LOW);
  WiFi.config(ip, dns, gateway, subnet);
  while (status != WL_CONNECTED) {status = WiFi.begin(ssid, pass);}
  digitalWrite(LED_BUILTIN, HIGH);

  IPAddress ip = WiFi.localIP();
  Serial.print("http://");
  Serial.println(ip); //Prints to the newly generated IP Address
  server.begin();
}

void loop(){
  WiFiClient client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()){
      if (client.available()){
        char c = client.read();
        if (readString.length() < 50){
          readString += c;
        if (c == '\n') {
          currentLineIsBlank = true;
          if (readString.indexOf("one") > 0){
            analogWrite(greenLED, 15);
          }
          else{
            analogWrite(greenLED, 0);
          }
          readString = "";
        } else if (c != '\r') {
          currentLineIsBlank = false;
          }
        }
      }
    }
  }
  delay(1);
  //Serial.print(millis()/1000);
  //Serial.println(" seconds elapsed");
}

This is the Client code:

#include <SPI.h>
#include "WiFiNINA.h"
#include "arduino_secrets.h" 

#define bluePin 10
#define trigPin 8
#define echoPin 9

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

char setIP[] = "192.168.46.244"; //IP Address trying to connect to
int port = 80; //The port for HTTP transmission

WiFiClient client;

//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  while (!Serial) {;}

  digitalWrite(LED_BUILTIN, LOW);
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    }
  digitalWrite(LED_BUILTIN, HIGH);
}

int sensorDist() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  if (pulseIn(echoPin, HIGH) < 500){return 1;}
  else{return 0;};
}

void loop(){
  if (sensorDist() == 0) {
    if (client.connect(setIP, port)) {
      client.write("GET /zro HTTP/1.1\r\n");
      analogWrite(bluePin, 0);
    }
  } else {
    if (client.connect(setIP, port)) {
      client.write("GET /one HTTP/1.1\r\n");
      analogWrite(bluePin, 15);
    }
  }
  if (client.connected()) {client.stop();}
  delay(1000);
  //Serial.print(millis()/1000);
  //Serial.println(" seconds elapsed");
}

Hi @malathisguy ,

Welcome to the forum..

Really need a state machine in your loop keeping tack of everything that could possibly go wrong..
for starters, you connect wifi in setup one time, what happens when it disconnects..
these boards only got like 6k of ram available, your probably chewing it up in a few minutes, which would lock them up..

using a String could lead to memory fragmentation..
having a global client connect and disconnect once per second, will cause you grief..
TCP is a guaranteed protocol, hence you must connect and disconnect both of which take time..
you might have better results leaving the client connected..

i'm thinking this would be better using UDP..
the client could broadcast once per second, the server listens for these, it's not guaranteed but it also does not require a connection..

here's something to look over..
a nice state machine..
UDP Sender..
UDP Receiver..
the above is for esp32 but the udp should be easily adaptable to your board..

good luck.. ~q

I'm currently trying to debug the code sent, and for my board Wifi.mode(WIFI_STA) throws the following error:

Compilation error: 'class WiFiClass' has no member named 'mode'

I've already looked through the github repo, and can't find an equivalent for my Uno. When I comment out that line from both ends, the "Receiver" doesn't capture any data transmitted.

commenting out the mode was correct..
and you should have replaced <WiFi.h> with <WiFiNINA.h>..

looking through the official demo..
seems the same..
please post the sketches for the sender and receiver, i'll take a look at them for you..

~q

what do these do..

sender..

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h" 

#define bluePin 10
#define trigPin 8
#define echoPin 9

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

char setIP[] = "192.168.46.244"; //IP Address trying to connect to

IPAddress udpServer(192, 168, 46, 244);

#define UDP_PORT 3000
WiFiUDP udp;

// UDP Datagram
struct __attribute__((packed)) UDPDatagram {
  int16_t sdata;                         // 16 bit integer data
  uint16_t crc;                          // crc check
} udpDatagram = { 0, 0 };  // initial values



//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  while (!Serial) {;}

  digitalWrite(LED_BUILTIN, LOW);
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(10000);
    }
  digitalWrite(LED_BUILTIN, HIGH);
}

int sensorDist() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  if (pulseIn(echoPin, HIGH) < 500){return 1;}
  else{return 0;};
}

void loop(){

  if (sensorDist() == 0) {
      analogWrite(bluePin, 0);
      udpDatagram.sdata = 0
  } else {
      analogWrite(bluePin, 15);
      udpDatagram.sdata = 1;
    }

//calc checksum..
  udpDatagram.crc = 0;
  for (int i = 0; i < sizeof(udpDatagram) - 2; i++) {
    udpDatagram.crc += ((uint8_t *)&udpDatagram)[i];
  }
  // Send Packet to UDP server
  udp.beginPacket(udpServer, UDP_PORT);

  delay(1000);

}

receiver..

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h" 

#define greenLED 10

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

IPAddress ip(192, 168, 46, 244);
IPAddress dns(8, 8, 8, 8);
IPAddress gateway(192, 168, 46, 1);
IPAddress subnet(255, 255, 255, 0);

#define UDP_PORT 3000
WiFiUDP udp;
// UDP Datagram
struct __attribute__((packed)) UDPDatagram {
  int16_t sdata;                         // 16 bit integer data
  uint16_t crc;                          // crc check
} udpDatagram = { 0, 0 };  // initial values


uint8_t buff[sizeof(UDPDatagram)];

//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(greenLED, OUTPUT);

  while (!Serial) {;}

  digitalWrite(LED_BUILTIN, LOW);
  WiFi.config(ip, dns, gateway, subnet);
  while (status != WL_CONNECTED) {status = WiFi.begin(ssid, pass); delay(10000);}
  digitalWrite(LED_BUILTIN, HIGH);

  IPAddress ip = WiFi.localIP();
  Serial.print("http://");
  Serial.println(ip); //Prints to the newly generated IP Address
  udp.begin(UDP_PORT);
}

void loop(){


  if (udp.parsePacket()) {
    //new packet..
    int recv = udp.read(buff, sizeof(buff));
    if (recv == sizeof(UDPDatagram)) {
      memcpy(&udpDatagram,&buff, sizeof(UDPDatagram));
      if (crcVerify()) {
        Serial.println("Packet received..");
        if (udpDatagram.sdata == 1 ){
            analogWrite(greenLED, 15);
        } else{
            analogWrite(greenLED, 0);
        }
      } else{
        Serial.println("Ignoring packet..");
      }
    }
  }
}

bool crcVerify() {
  uint16_t crc = 0;
  Serial.print("Datagram data ");
  for (int i = 0; i < sizeof(udpDatagram) - 2; i++) {
    Serial.print((uint8_t)((uint8_t *)&udpDatagram)[i], HEX);
    Serial.print(' ');
    crc += ((uint8_t *)&udpDatagram)[i];
  }
  return (crc == udpDatagram.crc);
}

~q

I've tested the code you both the sender/receiver. The "sender" code is sending out udpDatagram values while shining its blue light, but the "receiver" is not collecting any packets. The Port and IP remain the same.

Once in the main loop, if (udp.parsePacket()){...} always returns false.

I'll still keeping looking into what the issue is.

@malathisguy i see an issue with the sender..

try this..

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h" 

#define bluePin 10
#define trigPin 8
#define echoPin 9

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

char setIP[] = "192.168.46.244"; //IP Address trying to connect to

IPAddress udpServer(192, 168, 46, 244);

#define UDP_PORT 3000
WiFiUDP udp;

// UDP Datagram
struct __attribute__((packed)) UDPDatagram {
  int16_t sdata;                         // 16 bit integer data
  uint16_t crc;                          // crc check
} udpDatagram = { 0, 0 };  // initial values



//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(bluePin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  while (!Serial) {;}

  digitalWrite(LED_BUILTIN, LOW);
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(10000);
    }
  digitalWrite(LED_BUILTIN, HIGH);
}

int sensorDist() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  if (pulseIn(echoPin, HIGH) < 500){return 1;}
  else{return 0;};
}

void loop(){

  if (sensorDist() == 0) {
      analogWrite(bluePin, 0);
      udpDatagram.sdata = 0
  } else {
      analogWrite(bluePin, 15);
      udpDatagram.sdata = 1;
    }

//calc checksum..
  udpDatagram.crc = 0;
  for (int i = 0; i < sizeof(udpDatagram) - 2; i++) {
    udpDatagram.crc += ((uint8_t *)&udpDatagram)[i];
  }
  // Send Packet to UDP server
  udp.beginPacket(udpServer, UDP_PORT);
   int len = udp.write((const uint8_t *)&udpDatagram, sizeof(udpDatagram));
  udp.endPacket();
  delay(1000);

}

sorry.. ~q

No need to apologize.
I incorporated the section and reran the code, but still got the same result.

I also added a Serial.println() to the "receiver" (shown below), and nothing is being printed to the Serial other than the static IP.

void loop(){
  if (udp.parsePacket()) {
    Serial.println("Found!");
    //new packet..
    int recv = udp.read(buff, sizeof(buff));

network issue??
the sender is using dhcp the receiver a static..
add some code to print the dhcp ip the sender is assigned, it should also be in the 192.168.46.xxx range..
run a network sniffer to actually see if the packet is getting out..

strange..~q

I've tested it on a couple of different networks (without a network sniffer), and continue to get the same result. I'll work on getting a network sniffer and let you know what I find tomorrow.

I finally figured it out! Now, one Arduino can send packets to the other! The sender code needed to contain respectively the following:

WiFiServer server(UDP_PORT);
...
server.begin();

Below is the final sender code:

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h" 

#define bluePin 10
#define trigPin 8
#define echoPin 9

char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

IPAddress udpServer(192, 168, 46, 244);
unsigned int UDP_PORT = 2390;

WiFiUDP udp;
WiFiServer server(UDP_PORT);

struct __attribute__((packed)) UDPDatagram {
  int16_t sdata;                         // 16 bit integer data
  uint16_t crc;                          // crc check
} udpDatagram = { 0, 0 };  // initial values

void setup() {
  Serial.begin(115200);
  pinMode(bluePin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  while (!Serial) {;}
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(5000);}

  udp.begin(UDP_PORT);
  server.begin();

  Serial.println("I'm Ready!");
}

int sensorDist() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  if (pulseIn(echoPin, HIGH) < 500){return 1;}
  else{return 0;};
}

void loop(){    
  if (sensorDist() == 0) {
    analogWrite(bluePin, 0);
    udpDatagram.sdata = 0;
  } else {
    analogWrite(bluePin, 15);
    udpDatagram.sdata = 1;
  }

  udpDatagram.crc = 0;
  for (int i = 0; i < sizeof(udpDatagram) - 2; i++) {
    udpDatagram.crc += ((uint8_t *)&udpDatagram)[i];
  }

  udp.beginPacket(udpServer, UDP_PORT);
  udp.write((const uint8_t *)&udpDatagram, sizeof(udpDatagram));
  udp.endPacket();
  delay(1000);
}

I only added a delay to the void loop() and changed the UDP_PORT's datatype for the receiver. Below is the final code for it.

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFiUdp.h>
#include "arduino_secrets.h" 

#define greenLED 10

//Network specific variables
char ssid[] = SECRET_SSID;    // WiFi SSID
char pass[] = SECRET_PASS;    // WiFi Password
int status = WL_IDLE_STATUS;

WiFiUDP udp;
IPAddress ip(192, 168, 46, 244);
IPAddress dns(8, 8, 8, 8);
IPAddress gateway(192, 168, 46, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int UDP_PORT = 2390;

// UDP Datagram
struct __attribute__((packed)) UDPDatagram {
  int16_t sdata;                         // 16 bit integer data
  uint16_t crc;                          // crc check
} udpDatagram = { 0, 0 };  // initial values

uint8_t buff[sizeof(UDPDatagram)];

//Setup Function
void setup() {
  Serial.begin(115200);
  pinMode(greenLED, OUTPUT);

  while (!Serial) {;}

  WiFi.config(ip, dns, gateway, subnet);
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(5000);}

  udp.begin(UDP_PORT);

  Serial.println("Send in the Packets!");
}

void loop(){
  if (udp.parsePacket()) {
    int recv = udp.read(buff, sizeof(buff));
    if (recv == sizeof(UDPDatagram)) {
      memcpy(&udpDatagram,&buff, sizeof(UDPDatagram));
      if (crcVerify()) {
        if (udpDatagram.sdata == 1 ){
            analogWrite(greenLED, 15);
        } else{
            analogWrite(greenLED, 0);
        }
      }
    }
  }
  delay(100);
}

bool crcVerify() {
  uint16_t crc = 0;
  for (int i = 0; i < sizeof(udpDatagram) - 2; i++) {
    //Serial.print((uint8_t)((uint8_t *)&udpDatagram)[i], HEX);
    //Serial.print(' ');
    crc += ((uint8_t *)&udpDatagram)[i];
  }
  return (crc == udpDatagram.crc);
}

The only thing I'm concerned with is how long the program can run for now. I was hoping for it to be 24/7, but that's the least of my problems at this point. Thank you again for all your help! Truly beneficial!

1 Like