Client Server communication, client doesn't receive answer

Hello everyone,

I'm trying to connect two Arduinos R4 via Wifi. The main Board should trigger the sub to turn on/off it's LED (in the long run, it should trigger several LEDs on several boards, but one step at a time). Unfortunately I fail to get the response back, so the main Board, can't decide, if turn on or off.

Code for the Main:

#include <WiFi.h>
//Choose which LED on own or remote Boards to turn on

const char* ssid = "test_wifi";        // Replace with your WiFi SSID
const char* password = "Test_wifi_password_12"; // Replace with your WiFi password

const char* serverIP = "192.168.178.152"; // Static IP address of Arduino 1 (Server)
const int serverPort = 80;            // Port the server is listening on
IPAddress localIP(192, 168, 178, 151);  // Set static IP address (use any available IP in your network range)
IPAddress gateway(192, 168, 1, 1);    // Set gateway address (usually your router IP)
IPAddress subnet(255, 255, 255, 0);   // Set subnet mask
int status = WL_IDLE_STATUS;
WiFiClient client;

void setup() {
  Serial.begin(115200);
  // Connect to WiFi
  WiFi.config(IPAddress(localIP));
  // print the network name (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);
  // Create open network. Change this line if you want to create an WEP network:
  status = WiFi.beginAP(ssid, password);
  if (status != WL_AP_LISTENING) {
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }
  // wait 10 seconds for connection:
  delay(10000);
  Serial.println("Connected to WiFi");
}

void loop() {
  // Request the current LED status
  if (client.connect(serverIP, serverPort)) {
     delay(100);
    Serial.println("Connected to server");
    // Send the request to get the LED status
    client.println("LED_STATUS");
    // Wait for and print the server's response
    String response = client.readStringUntil('\n');  // Use '\n' to match the server's end of line
    if (response.length() > 0) {
    Serial.print("Server Response: ");
    Serial.println(response);  // Print out the response from the server
    } else {
    Serial.println("No response from server or empty response");
    }

    // Parse the response to check the current LED status
    if (response.indexOf("LED Status: ON") != -1) {
      Serial.println("LED is ON, requesting to turn it OFF");
      toggleLED("OFF");  // If the LED is ON, request to turn it OFF
    } else if (response.indexOf("LED Status: OFF") != -1) {
      Serial.println("LED is OFF, requesting to turn it ON");
      toggleLED("ON");  // If the LED is OFF, request to turn it ON
    }
    client.stop();  // Disconnect from the server
    Serial.println("Disconnected from server");
    delay(10000); // Wait for 5 seconds before sending the next request
  } else {
    Serial.println("Connection to server failed");
    delay(1000); // Retry after 1 second
  }
}

void toggleLED(const String& status) {
  if (client.connect(serverIP, serverPort)) {
    // Send the request to toggle the LED
    client.println("TOGGLE_LED");
    // Wait for and print the server's response
    String response = "";
    while (client.available()) {
      response += client.readString();
    }
    Serial.println("Server Response to toggle:");
    Serial.println(response);

    client.stop();  // Disconnect from the server
    Serial.println("Disconnected from server");
  } else {
    Serial.println("Failed to send toggle command");
  }
}

Code for the sub

#include <WiFi.h>
//Waiting for Client, to choose which LED to Pin

const char* ssid = "test_wifi";        // Replace with your WiFi SSID
const char* password = "Test_wifi_password_12"; // Replace with your WiFi password

// Static IP Configuration
IPAddress localIP(192, 168, 178, 152);  // Set static IP address (use any available IP in your network range)
IPAddress gateway(192, 168, 1, 1);    // Set gateway address (usually your router IP)
IPAddress subnet(255, 255, 255, 0);   // Set subnet mask

WiFiServer server(80);  // Server will listen on port 80 (HTTP)

const int builtInLED = LED_BUILTIN; // Built-in LED pin on the Arduino R4 Wi-Fi
bool ledStatus = LOW;  // Initial LED status (LOW = OFF)

void setup() {
  Serial.begin(115200);
  
  // Connect to WiFi with static IP configuration
  WiFi.config(localIP, gateway, subnet);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // Start the server
  server.begin();
  Serial.println("Server started");
  Serial.print("Server IP Address: ");
  Serial.println(WiFi.localIP());  // Print the static IP address of the server
  
  pinMode(builtInLED, OUTPUT); // Set the LED pin as output
  digitalWrite(builtInLED, ledStatus);  // Set the initial LED state
}

void loop() {
  WiFiClient client = server.available();

  if (client) {
    if (client.connected()){
      Serial.println("client connected");
      delay (10);
      String request = "";
      request = client.readStringUntil('\r');
      Serial.print("Request: " );
      Serial.println(request);

      // Handle the LED status request
      if (request.indexOf("LED_STATUS") != -1) {
        client.print("LED Status: ");
        client.println(ledStatus == HIGH ? "ON" : "OFF");
        Serial.print("LED Status: ");
        Serial.println(ledStatus == HIGH ? "ON" : "OFF");
        Serial.println("LED status sent to client");
      }
    }

    // Handle the toggle LED request
    if (request.indexOf("TOGGLE_LED") != -1) {
      ledStatus = (ledStatus == LOW) ? HIGH : LOW;  // Toggle LED status
      digitalWrite(builtInLED, ledStatus);  // Set the LED to the new status
      client.print("LED is now ");
      client.println(ledStatus == HIGH ? "ON" : "OFF");
      Serial.println("LED status toggled");
    }
    
    client.stop();
    Serial.println("Client disconnected");
  }
}

Output wise I see on the sub:

Request: LED_STATUS

LED Status: OFF

LED status sent to client

Client disconnected

So I know this direction works, but the Main board gives me this:

Connected to server

No response from server or empty response

Disconnected from server

Probably the solution is pretty simple, I already tried to find help in the internet, but the code parts I find are much more elaborate than what I try to achive.

Thank you in adavance for any hint, where I did a mistake.

wait for the response

Those two may be sent in 2 different 'packets'. So in the code that's receiving them:

It may be failing to find the string you are looking for the end of, because only the first half has been received.

As @Juraj said "wait for the response". It would help perhaps if you sent the length as the first byte of any message, then you could wait until you'd received that many bytes before trying to parse what you received.

I am confused. I expected from your post you'd run a web server on 192.168.178.152 but you are only running the client. There is no web server present or am I missing something?

Tbh I'm not a good programmer (hence probably my problem). I've took most of the code regarding the communication from examples in the internet, trying to understand what they did, but I often failed...
I thought that server.begin() would start the server.

I tried to add a delay after sending the

client.println("LED_STATUS");

but it still doesn't receive anything. What is even more confusing, that today, without changing the code, the sub doesn't receive the "LED_Status" message, as it did yesterday.

You need a server and a client to communicate. Since you've used port 80 I assumed you wanted a web-based communication. But basically it doesn't matter, you can transmit any kind of data over any port.

You need to run a web server on the device that has the AP and a web client on the other one that connects to AP (or vice versa).

If you need an example how to set up a simple web server, please take a look at (only the loop () function): https://github.com/BojanJurca/Key-value-database-for-Arduino/blob/main/src/src.ino. The client part is already working I guess.

V V pet., 20. dec. 2024 ob 11:13 je oseba Klasoj via Arduino Forum <notifications@arduino.discoursemail.com> napisala:

If I were you, I'd use some code like this to see exactly what the server is receiving from the client. When you have seen that, and worked out how to parse it in your code, then go back to making it process the client requests as you want to.

void loop() {
  WiFiClient client = server.available();

  if (client) {
    if (client.connected()) {
      Serial.println("client connected");
      unsigned long startTime = millis();
      Serial.println("Received bytes:");
      while (millis() - startTime < 2000) {
        if (client.available())
        {
          startTime = millis();
          int value = client.read();
          if (value > -1) { // Should never be -1 because available was true
            Serial.print("0x");
            if (value < 16) Serial.print("0");
            Serial.println(value, HEX);
          }
        }
      }
      Serial.println("Nothing more received");
    }
    client.stop();
    Serial.println("Client disconnected");
  }
}

I tested code similar to the above using Serial.available() and Serial.read() instead of client.available() and client.read(). The above code compiles, but I haven't tested it. It should print the hex code for each byte received from the client, and tolerate a delay of upto 2 seconds during receiving the request.

you don't wait for the answer in the client sketch. you immediately check client.available() and continue in the sketch when it is 0. so you never read the response, which arrives a little later