Sending Serial Communication (Ubuntu, Python) to Arduino
This is the strangest thing I've seen for quite some time.
I have very simple python code to send commands Arduino Uno R3
using Python
, working on Ubuntu
.
import serial
import time
ser = serial.Serial('/dev/ttyACM0', 115200)
time.sleep(2)
if ser.isOpen():
print "Port Open"
print ser.write("START\n")
ser.close()
The above code works as expected and prints:
Port Open
6
And I have an Arduino job that receives this command and toggles the LED. It's simple.
The weird thing is that if I delete the line the time.sleep(2)
Arduino stops toggling the LED. Python is still printing that the port is open and it successfully passed 6B.
Why is this delay necessary? Didn't I see him again? I also tested a program from a PC running windows with the same result.
EDIT I tested with different baud rates, it doesn't matter and the behavior is the same. Below is the Arduino code, but I don't think this 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;
}
}
}
source to share
Arduino UNO automatically resets when opening or closing the serial port via USB. Therefore, you must give the Arduino enough time to complete the reset. I usually use a prepared check (print (Arduino) - read (Python)) to avoid 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())
This way python waits until the ready message is read, giving time for the reset to complete.
You must also wait for the Arduino to complete its tasks before closing the serial port.
If auto-reset is a problem for your project, you can try to disable it Disable auto-reset Aruduino reset
source to share