Can't read arduino with python on linux

Hey Guys,

I have a very simple project: some DS18B20 sensors that should measure the temperature and my Arduino Uno sends the data to my computer. Everything works perfectly fine on Windows 7. And it also works when I use the Serial Monitor in the Arduino API on Linux (OpenSuse 13.2).

Here’s what it looks like in the Serial Monitor (Win and Linux) for 2 connected sensors:

ROM = 28EC98A5500DE 26.69 C
ROM = 281CFFA450063 27.31 C
No more Sensors
ROM = 28EC98A5500DE 26.69 C
ROM = 281CFFA450063 27.31 C
No more Sensors

The problem starts when I want my python script to store the values. Again, on Windows it works.

This is what some typical lines, send by the arduino, look like in my python script:

ROM = 281CFFA450063ROM = 28EC98A5500DE 26.44 C
50063 27.62 C
26.44 C

Most of the lines received are just weird. Missing characters or missing ‘\n’. That makes it very annoying …

Does anyone has an idea what could cause this problem?

Arduino Code (more or less just copied from the examples):

#include <OneWire.h>

// temperature sensors DS18B20 to serial port
// one data request of all sensors per second

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)

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

void loop(void) {
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;
  
  if ( !ds.search(addr)) {
    Serial.println("No more Sensors");
    ds.reset_search();
    delay(1000);
    return;
  }

  Serial.print("ROM = ");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE, 1);         // Read Scratchpad, with parasite power on at the end

  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  
  celsius = (float)raw / 16.0;
  Serial.print(" ");
  Serial.print(celsius);
  Serial.println(" C");

And the interesting python3 part:

import serial

arduino = serial.Serial(port="/dev/ttyS0", baudrate=9600, timeout=5)

while True:
    line = arduino.readline()
    print(line)
    if not ("No more Sensors" in line):
       do_something()
    else:
        break

This Python demo works on Linux

I wonder are you allowing enough time for the Arduino to complete its reset process when Python opens the serial port ?

It may be worth checking the setting for serial.rtscts. I think it needs to be set to True

...R

Thanks for reply, your tip seems to help. I just added the piece of code from your link (the "waitForArduino"-thing)

Wondering, why this causes no troubles on a windows machine?

Btw., is it better to leave the connection to the arduino open or, as I do it now, open and close it every time I want a measurement?

Greetings,
Chewy

metalchewy:
Btw., is it better to leave the connection to the arduino open or, as I do it now, open and close it every time I want a measurement?

You MUST leave it open. Otherwise the Arduino will reset everytime you re-open the serial port.

Wondering, why this causes no troubles on a windows machine?

I only came across the need for setting serial.rtscts = True in a recent project I did. I have not done any extensive tests to understand exactly what it does and I suspect sometimes it defaults to True and other times to False. I think that the Arduino does not reset if it is set to False. In the project where I needed it, I definitely wanted it to reset. I so rarely try Windows that I almost don't know how.

...R

Robin2:
You MUST leave it open. Otherwise the Arduino will reset everytime you re-open the serial port.

Well, that is actually not a serious problem, at least for my codes, it makes no difference. Only thing I can think of, is that it could damage the Arduino somehow if I open/close it every minute for let's say 2 month (as for a weather station for instance).

Robin2:
I only came across the need for setting serial.rtscts = True in a recent project I did. I have not done any extensive tests to understand exactly what it does and I suspect sometimes it defaults to True and other times to False. I think that the Arduino does not reset if it is set to False. In the project where I needed it, I definitely wanted it to reset. I so rarely try Windows that I almost don't know how.

Hmm... I really have no idea what this kind of stuff is/does/means. And as long as it works, I will just leave it as it is.

Thanks!