0

from get_connected_arduinos import get_arduinos

serial_devices = []


def initialize(serial_device):
    print("initializing", serial_device)
    try:
        serial_device["serial"].write(bytes("whodis\n", encoding="utf-8"))
        name = serial_device["serial"].readline().decode().strip().strip(";")
        if not name:
            print("serial_device did not recieve a name. Possible timeout")
            name = "Not responding"
            serial_device["status"] = "No response"
            serial_device["error"] = "Error: Device is not responding"
        else:
            serial_device["status"] = "Responded"
            serial_device["error"] = ""
        
        serial_device["lastused"] = int(time.time())
        serial_device["name"] = name
    except serial.serialutil.SerialException:
        print("Device disconnected when initializing")
        return
    serial_devices.append(serial_device)
    print(f"USB device initialized: {serial_device['name']}")

def start_initialization_timer(device):
    threading.Timer(2, initialize, args=({"device": device, "serial": serial.Serial(device, 2400, timeout=1), "name": None},)).start()


start_initialization_timer("/dev/ttyUSB2")
import time, datetime
time.sleep(4)
device = serial_devices[0]

last_returned = None
command = f"p\n"
while True:
    old = last_returned
    try:
        device["serial"].write(bytes(command, encoding="utf-8"))
        time.sleep(0.05)
        last_returned = device["serial"].readline().decode(encoding="utf-8").strip().strip(";") + "\n"
        time.sleep(0.05)

    except serial.serialutil.SerialException:
        last_returned = "disconnected"
    if old != last_returned:
        print("new stuff:", last_returned)
        print(datetime.datetime.now().strftime("%d/%m/%Y, %H:%M:%S"))
    time.sleep(5)```



#include <EEPROM.h>

const int MAX_INPUT_LENGTH = 64; // Maximum length for input command
const int PWM_PINS[] = {3, 5, 6, 9, 10, 11}; // PWM-capable pins on Arduino Nano
const int NUM_PWM_PINS = sizeof(PWM_PINS) / sizeof(PWM_PINS[0]);
//const String whodis = "ch1";
const int EEPROM_START_ADDR = 0; // Starting address for EEPROM string storage

// Function to write a string to EEPROM starting at a specified address
void eepromWriteString(int addr, const char* string) {
  int i = 0;
  while (string[i] != '\0') {
    EEPROM.write(addr + i, string[i]);
    i++;
  }
  EEPROM.write(addr + i, '\0'); // Write the null terminator
}

// Function to read a string from EEPROM starting at a specified address
String eepromReadString(int addr) {
  String string;
  char ch = EEPROM.read(addr);
  while (ch != '\0' && addr < EEPROM.length()) {
    string += ch; // Append character to string
    addr++;
    ch = EEPROM.read(addr);
  }
  return string;
}

bool isPWMPin(int pin) {
  for (int i = 0; i < NUM_PWM_PINS; i++) {
    if (PWM_PINS[i] == pin) return true;
  }
  return false;
}

String doStuff(String line) {
  String returned = "";
  int pin, value;
  char name;
  String args;
  
  int index = 0;
  while (index < line.length()) {
    int nextIndex = line.indexOf(';', index);
    if (nextIndex == -1) {
      nextIndex = line.length();
    }
    String cmd = line.substring(index, nextIndex);
    index = nextIndex + 1;
  
    if (cmd.length() > 0) {
      name = cmd.charAt(0);
      args = cmd.substring(1); // Get the arguments part of the command
      args.trim(); // Trim whitespace in place

      switch (name) {
        case 's':
          if (sscanf(args.c_str(), "%d %d", &pin, &value) == 2) {
            if (isPWMPin(pin)) {
              if (value >= 0 && value <= 255){
                analogWrite(pin, value);
                returned += cmd + ";"; // Echo the command back
              } else{
                returned += "Error: Invalid value;";
              }
            } else {
              returned += "Error: Invalid pin;";
            }
          } else {
            returned += "Error: Invalid arguments for 's' command;";
          }
          break;
        case 'p':
          returned += "o;";
          break;
        case 'w':
          returned += eepromReadString(EEPROM_START_ADDR) + ";";
          break;
        case 'e': // write to eeprom
          // Write the remaining part of the command to EEPROM
          eepromWriteString(EEPROM_START_ADDR, args.c_str());
          returned += eepromReadString(EEPROM_START_ADDR) + ";";
          break;
        default:
          returned += "Error: Unknown command;";
          break;
      }
    }
  }

  return returned;
}

void setup() {
  Serial.begin(9600);

  String readd = eepromReadString(EEPROM_START_ADDR);
  if (readd == "" or readd.charAt(0) == -1) {
    // If empty, write "unnamed device" to EEPROM

    eepromWriteString(EEPROM_START_ADDR, "unnamed device");
  }
}

void loop() {
  static char inputBuffer[MAX_INPUT_LENGTH];
  static int bufferPosition = 0;

  while (Serial.available() > 0 && bufferPosition < MAX_INPUT_LENGTH - 1) {
    char inChar = Serial.read();
    if (inChar == '\n') {
      inputBuffer[bufferPosition] = '\0'; // Null-terminate the string
      String output = doStuff(inputBuffer);
      Serial.println(output);
      bufferPosition = 0; // Reset buffer position
    } else if (inChar >= 32 && inChar <= 126) { // Readable ASCII characters
      inputBuffer[bufferPosition++] = inChar;
    }
    // Ignore other characters
  }
}

I'm experiencing intermittent communication failures between a Raspberry Pi 4 and Arduino Nano devices. The setup involves a Python script running on the Raspberry Pi, which communicates with the Arduino Nano via USB. The Arduino is programmed to respond to specific commands sent from the Raspberry Pi. Initially, the communication works as expected, but after a few hours or minutes, the Arduino stops responding to commands, resulting in a timeout and an empty string being returned. Restarting the Python script on the Raspberry Pi temporarily resolves the issue. This problem has been observed with both Arduino Nano and the Arduino Uno, and sometimes when one device fails, others connected simultaneously may fail as well, though not always. I have tried different baudrates like 2400 but the issue persists. I am running Python 3.11.6 with PySerial for serial communication. Not sure if relevant, but i am using xrdp for remote desktop connection to remotely control the pi.

My goal is to control lights and pumps by using the arduino to send out PWM signals to the lamps. I know the pi has PWM pins, but there arent enough and its easier to make a failsafe on the arduino. The issue happens regardless of if i have the arduino connected to a lamp or not. And for some reason the issue has recently started to occur more often, with the bug occuring within in a few minutes. I have never been this confused with an issue before. Any help is appreciated. Thanks.

3
  • What Pi? What OS? How and why did you install python 3.11.6?
    – Milliways
    Commented Feb 7 at 21:36
  • @Milliways I am using a raspberry pi 4 2GB, with the reccomended rasberry pi os 64-bit released 2023-12-05. I installed python with the sudo apt install python3 command.
    – UnityBug
    Commented Feb 10 at 7:04
  • If you did this (which is pointless) you would have 3.11.2 - which is already installed.
    – Milliways
    Commented Feb 10 at 7:42

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.