Freezing and connection issues between Arduino WebSockets server and Python client

Currently, I am building a system composed of a Arduino WebSockets server (running on ATmega328P with a W5500 Ethernet Shield), which sends a value to a python client when it is queried every 2 seconds. It then takes the obtained value with the corresponding timestamp and writes it to a .csv file. I have recently upgraded to python 3.9.6 in order to use asyncio.run() in the python client too. The Arduino WebSockets server is given below:

#include <WebSocketServer.h>
using namespace net;


//------------------------------------------------------
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[]{0xA8, 0x61, 0x0A, 0xAE, 0x69, 0x13};
IPAddress ip(198, 162, 1, 177);
IPAddress gateway(0,0,0,0);
IPAddress DNSserver(0,0,0,0);
IPAddress subnet(255,255,255,0);

constexpr uint16_t port = 80;
WebSocketServer wss{port};

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  pinMode(Pulses, INPUT);
  attachInterrupt(digitalPinToInterrupt(Pulses), CountPulses, FALLING);
  
  Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");

  // start the Ethernet connection and the server:
  Ethernet.begin(mac,ip,DNSserver,gateway,subnet);

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  wss.onConnection([](WebSocket & ws) {
    const auto protocol = ws.getProtocol(); 
    if (protocol) {
      Serial.print(F("Client protocol: "));
      Serial.println(protocol);
    }

    ws.onMessage([](WebSocket & ws, const WebSocket::DataType dataType,
    const char *message, uint16_t length) {
      switch (dataType) {
        case WebSocket::DataType::TEXT:
          Serial.print(F("Received: "));
          Serial.println(message);
          break;
        case WebSocket::DataType::BINARY:
          Serial.println(F("Received binary data"));
          break;
      }

      ws.send(dataType, message, length);
    });

    ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
    uint16_t) {
      Serial.println(F("Disconnected"));
    });

    Serial.print(F("New client: "));
    Serial.println(ws.getRemoteIP());


    char temperature[10];
    char str_temp[8];
    float temp = 1001.01;
/* 4 is mininum width, 2 is precision; float value is copied onto str_temp*/
    dtostrf(temp, 6, 2, str_temp);
    sprintf(temperature,"%s", str_temp);
    float value;
    value = 0.1;
    const char message[] {value};
    ws.send(WebSocket::DataType::TEXT, temperature, strlen(temperature));
  });

  wss.begin();
  Serial.println(Ethernet.localIP());
}

void loop() {
  wss.listen();
}

The asyncio python client is given below:

import logging
import datetime

logger = logging.getLogger("websockets")
logger.setLevel(
    logging.DEBUG
)  # Switch to DEBUG for full error information
logger.addHandler(logging.StreamHandler())


async def get_data():
    async with websockets.connect(
        "ws://198.162.1.177:80/",
        ping_interval=None,
    ) as websocket:
        await websocket.send(str(1.001))
        response = await websocket.recv()
        return response


def save_data(response):
    now = datetime.datetime.now()
    dataline_pv1 = f"{now.isoformat()},{response},0\n"
    file_name_pv1 = f"{now:%Y%m%d}_flow.csv"

    with open(file_name_pv1, "a") as etherm_file1:
        etherm_file1.write(dataline_pv1)


async def test():
    while True:
        response = await get_data()
        save_data(response)
        await asyncio.sleep(1)

asyncio.run(test())

However, I am experiencing some very odd behavior with the connection (perhaps memory related, since I want to have the Arduino effectively operate continuously?). Sometimes, my laptop cannot connect to the Arduino,leading to a Connection Refused error, despite being able to ping it from the terminal.

On other occasions, both the client and the server can run successfully, but then the connection appears to freeze and the .csv file appears to stop updating after about 3 minutes or so, without giving an error message in the terminal.

What is happening here, and how do I fix this such that Arduino can run continuously without this freezing occurring?

Your Arduino code doesn't compile. I guess you have much more code and that code uses too much RAM. But that's wild guessing because you failed to provide the necessary information.

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