0

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

2
  • Hi! I am also James B! I don't see any screenshots of the error? Would you mind sending an image of the random junk that it sends, also check if the serial terminal is set to the right frequency (the same frequency you set in your arduino program 9600 baud rate) I think you tried to include the screenshot, but there was a formatting issue, I see the image link in the python code. Commented Feb 5, 2021 at 20:47
  • One other possibility is that you have the serial terminal settings setup wrong, for example there are multiple settings that you have to set to communicate with an arduino. This includes the Data Bits, Stop Bits, Parity and Flow Control. Commented Feb 5, 2021 at 20:53

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

1 Comment

Hey I got to work today and found the bug in my code. Turns out I just had to delete the pointer of char in arduino code, so that the memory is free to allocate the next wave of data. Thanks for you help though, I cleaned up my code and now it looks neat :)

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.