JamesB
JamesB

Reputation: 25

Arduino Python serial communication bug

This is a complex bug I have been having for a few weeks and I don't know how to fix it. I have a thermistor array plugged in the four first analog pins and they are returning a temperature on a Python script that communicates with the Arduino on a serial port. Here is the Arduino code:

float R1 = 2000;
float c1 = 8.7956830817e-4, c2 = 2.52439152444e-04, c3 = 1.94859260345973e-7;

void setup() {
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
}

int getVoltage(int i) {
  return analogRead(i);
}

float getTemp(int i) {
  int V = getVoltage(i);
  float R2 = R1 * (1023.0 / (float)V - 1.0); \\minus 1 for 1 index based
  float logR2 = log(R2);
  float T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
  return T - 273.15;
}

String getTempString(int i) {
  float temp = getTemp(i);
  String result;
  if(temp > 99.99){
    return String(temp, 2);
  } else {
    return String(temp, 3);
  }
}

void loop() {
  if (Serial.available() > 0) {
    digitalWrite(13, HIGH);
    // read the incoming byte:
    String input = Serial.readStringUntil('\n');
    digitalWrite(13, LOW);
    //send the temperature
    char* response = new char[6];
    int channelNumber = String(input[0]).toInt() - 1;//-1 to make it index based 1
    getTempString(channelNumber).toCharArray(response, 6);
    //delay(20);
    Serial.write(response, 6);
    Serial.write('\n');
  }
}

and here is the Python code:

from serial import Serial
import time

ser = Serial('COM5', 9600, timeout=1)

def readTempChannel(i):
    global ser
    
    ser.write(i+b'\n')
    raw = str.rstrip(ser.readline())
    try:
        return float(raw)
    except Exception:
        ser.close()
        ser = Serial('COM5', 9600, timeout=1)
        return 5.0[![enter image description here][1]][1]

if __name__ == "__main__":
    while 1:
        channel1 = readTempChannel('1')
        channel2 = readTempChannel('2')
        channel3 = readTempChannel('3')
        channel4 = readTempChannel('4')
        print('%.2f, %.2f, %.2f, %.2f' % (channel1, channel2, channel3, channel4))

The problem is that I get values for the first 10 seconds but after that I get either empty strings or I get random characters that are not numbers from the Arduino.

I tried closing and reopening the serial port and that works (sometimes) but it adds a delay to the stream and I need the communication to happen at high speeds for my application without any delays. I added a screenshot to this post showing the error on a PuTTY terminal (the Python code is running on a Beaglebone and it is Python 2.7).

So if any of you can help me solve this bug I would be very thankful.

enter image description here

Upvotes: 0

Views: 799

Answers (1)

Maxwell Redacted
Maxwell Redacted

Reputation: 589

This is a difficult problem to solve without having all the physical hardware to hand but I can share with you my experiences of using pyserial with arduino:

on the python side I didn't bother with the new line:

ser.write(b'{}'.format(command)) 
## writes the command as bytes to the arduino

I also used the following line to pause the python program until the it receives a response - this is quite important for flow control

while(ser.inWaiting()==0):pass ## waits until there is data

On the arduino side i used the following to read in the serial and carry out commands:

void loop() {
  switch(Serial.read()){
    case '0': ## when command (in python) = 0
              do_command_1()
              break;
    case '1': ## when command (in python) = 1
              do_command_2()
              break;
    default: break; # default - do nothing if I read garbage
  }
}

try integrating some of the above into the code and get back to me - like I said it's difficult to solve a hardware problem without the hardware and the code I have here is from a project a long time ago

Upvotes: 3

Related Questions