String Write from Python

Hello,

I am working on a project that uses a Python UX to transmit a String to the arduino in order to write to an RFID tag. I am having issues with the python code writing to the arduino. Below is the arduino code that is receiving the string from python. For some reason I can input this string through the IDE and the code functions fine but the Python string is not making it to the arduino for lack of a better description. I have built in a function to confirm connection between the python UX and arduino and that works just fine. Any help would be greatly appreciated.

#include <SoftwareSerial.h>


SoftwareSerial softSerial(2, 3); // RX, TX

#include "SparkFun_UHF_RFID_Reader.h"
RFID nano; // Create instance

String partNumber = "";  // To store the part number received from Python
unsigned long lastRFIDWriteTimestamp = 0;
const unsigned long WRITE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
int error = "";
int error2 = "";

void setup() {
  Serial.begin(115200);
  while (!Serial);  // Wait for serial port to be ready


  if (setupNano(38400) == false) {
    Serial.println(F("Module failed to respond. Please check wiring."));
    while (1);  // Freeze!
  }
  

  nano.setRegion(REGION_NORTHAMERICA);
  nano.setReadPower(500);
  nano.setWritePower(500);

  while (Serial.available()) {
    String request = Serial.readStringUntil('\r');
    request.trim();
    //Serial.println(request); //show sent string from python

    if (request == "checkConnection") {
      Serial.println("Connected");
      while (1);} //Freeze!
  }
}

void loop() {//else 
    while (Serial.available()>0)
    {
      String request = Serial.readStringUntil('\r');
    request.trim();
    
    if
      (request != "checkConnection") {
      partNumber = request; // Directly assign the received request to partNumber
      Serial.print("Part Number ");
      Serial.println(partNumber);
        

Here is the python command to send the string to the arduino.

def write_partNumber(self):
        selected_port = self.com_port_combobox.get()
        partNumber = self.part_number_entry.get()

        if not selected_port:
            messagebox.showerror("Error", "Please select a COM port.")
            return

        if not partNumber:
            messagebox.showerror("Error", "Please enter a valid Part Number.")
            return

        try:
            ser = serial.Serial(selected_port, 115200, timeout=1)
            if not ser.is_open:
                ser.open()

            # Send part number to Arduino
            ser.write((partNumber + "\r").encode('utf-8'))
            #ser.write((partNumber).encode('utf-8'))
            
            # Wait for a response from Arduino with a timeout
            start_time = time.time()
            TIMEOUT = 5  # 5 seconds timeout for example
            while ser.in_waiting <= 0 and (time.time() - start_time) < TIMEOUT:
                time.sleep(0.1)  # Don't hog the CPU

            if ser.in_waiting > 0:
                response = ser.readline().decode("utf-8").strip()
                self.serial_output.insert(tk.END, f"Received: {response}\n")  # Display in the textbox
                self.serial_output.see(tk.END)  # Auto-scroll
            else:
                self.serial_output.insert(tk.END, f"No response from Arduino after {TIMEOUT} seconds.\n") 
                self.serial_output.see(tk.END)  # Auto-scroll
        except serial.SerialException as e:
            if not ser.is_open:
             messagebox.showerror("Error", "Port is not open!")
            else:
                messagebox.showerror("Error", f"Communication error: {str(e)}")

You are reading in a string that must be terminated with a carriage return.
to analyse what your python-code is sending
write a small test-code that just receives single bytes and print the bytes as ASCII and as hex-value.
Then you will see what your python code is really sending

Here are some common solutions:

  1. Serial Communication Setup:
  • Ensure that both the Python script and the Arduino are using the same baud rate for the serial communication. Mismatched baud rates can cause communication failures.
  • Check that the correct COM port is being used in your Python script. The COM port your Arduino is connected to can be found in the Arduino IDE under Tools > Port.
  1. Python Code:
  • If you're using the pyserial library in Python, ensure you are opening the serial port correctly, and there are no issues with the Python code sending data.
  • Make sure you're writing the string to the serial port correctly, and it's being sent in the format expected by the Arduino. You might need to encode the string before sending.
  • Example:
import serial
ser = serial.Serial('COM3', 9600)  # Update COM port and baud rate
ser.write("Your string here".encode())

Arduino Code:

  • On the Arduino side, make sure you're reading from the serial port correctly. If you're using Serial.readString() or similar functions, remember that these functions might behave differently depending on timeouts or available data.
  • Consider using Serial.readStringUntil('\n') and ensure your Python code sends a newline character \n at the end of the string.

One important thing to note. When you open the serial port from you python script, this resets your arduino so you have to give it some time to power up and start receiving data before you send your information from the python script.

It is usually a good practice to have your arduino print something like "ready" or "hello world" inside setup() so your python code can

  1. open the serial port
  2. wait for the "ready" message to know the arduino is powered up
  3. send your actual data.

So what is the question?

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