Sending serial communication (using Python on Ubuntu) to Arduino

Question:

This is the strangest thing I have seen in quite a while.

I have very basic Python code to send commands to a Arduino Uno R3 using Python running on Ubuntu.

import serial
import time

ser = serial.Serial('/dev/ttyACM0', 115200)
time.sleep(2)
if ser.isOpen():
    print "Port Open"
print ser.write("STARTn")
ser.close()

The above code works accordingly and it prints:

Port Open
6

And I have an Arduino running which receives this command and toggles an LED. It is that simple.

The strange thing is that if I remove the line time.sleep(2), the Arduino stops toggling the LED. Python still prints that the port is open and it has successfully transmitted 6B.

Why is that delay needed?

I have seen it nowhere else? I have also tested the program from a PC running Windows with the same result.

I have tested with different baud rates. It does not matter and the behavior is the same.

The following is the Arduino code, but I don’t think it is relevant.

#define LED_PIN  2
#define FAKE_DELAY 2*1000

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  Serial.begin(115200);
  inputString.reserve(50);
}


void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {

    digitalWrite(LED_PIN, HIGH); // turn the LED on (HIGH is the voltage level)

    Serial.print("Processing incoming command: ");
    Serial.println(inputString);

    if (inputString.startsWith("START")) {
      Serial.print("processing START...");
      delay(FAKE_DELAY);
    }

    // clear the string:
    inputString = "";
    stringComplete = false;

    digitalWrite(LED_PIN, LOW); // turn the LED off
  }
}


/*
  SerialEvent occurs whenever a new data comes in the
  hardware serial RX.  This routine is run between each
  time loop() runs, so using delay inside loop can delay
  response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    inputString += inChar;

    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inputString.endsWith("n")) {
      stringComplete = true;
    }
  }
}
Asked By: theAlse

||

Answers:

Arduino Uno resets automatically when opening or closing the serial port through USB. So you have to give enough time to Arduino to complete the reset. I normally use a ready check (print (Arduino) – read (Python)) to avoid the delay in Python:

Arduino:

void setup ()
{
    // ..... //
    Serial.begin (115200);
    Serial.print ("Ready...n");
}

Python:

import serial

ser = serial.Serial('/dev/ttyACM0', 115200)
print (ser.readline())

In this way, Python waits until the ready message is read, giving time to complete the reset.

You have to wait too for Arduino to finish its tasks before closing the serial port.

If auto-reset is a problem for your project, you can try to disable it Disabling Arduino auto reset

Answered By: credondo
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.