Hiho,
i have a project using an Arduino Duemilanove to communicate with a Python-skript on my ubuntu-11.10-machine. The Skript is running as a deamon, that starts when the computer is coming up and the Ardunino-Board is detected on something like ttyUSB0. Now the skript waits for an input from the Arduino and process it.
Python 2.7
pyserial 2.6
Well, the arduino-skript works fine, and the communication with the Arduino-IDE (1.0) aswell. But with the connection that the python-skript tries to establish is something very odd.
After a long time testing I had very chaotic results of sometimes working, sometimes not or with corrupted input from the Board.
At the moment I can observe the following behavior:
When the computer is coming up and detects the arduino, the skript starts and establish a connection.
The Board restarts.
But I get no input.
When ever I restart the deamon (connection closed and re-established), the board restarts aswell.
But no proper communication.
Now I stop the deamon and start the Arduino-IDE.
The board restarts and everything works fine.
I stop the IDE and restart the deamon.
The Board restarts and everything works fine!!!
I restart the deamon, but the board does NOT restart anymore. Even so the connection is still working.
I tried a lot of stuff, like flushing the connection-input (port.flushInput()) right after opening it. Or try to set port.setRTS(False) (but I'm not sure what it means). I tried a lot of delay-time-stuff to synchronize the starting-process of the board and the deamon. Most time I've got some input, but either only the line-ending of a word or only few characters like "pwr_f" of "power_off". At the moment I get nothing or everything (like described above) but cannot say what excactly makes the difference.
I also tried to reload the ftdi_sio- and usbserial-driver just before establishing the connection. But it didn't helped.
Well, here is some code. It would be gorgeous if somebody could help me... I really don't know any further.
I tried to cut the code to the essentials...
// outputs
int pin_led_red = 12;
int pin_led_green = 13;
int reply = 0;
// timer
unsigned long timer;
long fifty_sec = 50000L;
long half_sec = 500L;
void setup() {
delay(1500);
Serial.begin(9600);
// set pin-modes
pinMode(pin_led_red, OUTPUT);
pinMode(pin_led_green, OUTPUT);
// init-signal
blink(pin_led_green, 500, 100);
// test serial connection
test_connection();
}
void loop() {
// some other code-stuff
}
// test the serial connection
void test_connection() {
Serial.println("check");
/* Serial.flush();*/
reply = wait_for_reply(fifty_sec);
if (reply == 520) {
blink(pin_led_green, 3000, 300);
} else {
blink(pin_led_red, 3000, 300);
}
}
// wait for an answer and return it as crossfoot
int wait_for_reply(long wait) {
timer = millis();
while (millis() - timer < wait) {
reply = Read();
if (reply) {
Serial.println(reply);
break;
}
delay(20);
}
return reply;
}
// get coming-in-data and return as crossfoot
int Read() {
reply = 0;
while (Serial.available() > 0) {
reply += Serial.read();
delay(10);
}
return reply;
}
// let a led blink for 4 seconds
void blink(int led, int duration, int speed) {
timer = millis();
while (millis() - timer < duration) {
digitalWrite(led, HIGH);
delay(speed);
digitalWrite(led, LOW);
delay(speed);
}
}
#!/usr/bin/python
import serial, time, logging, os, subprocess, sys, traceback, signal
from serial.tools import list_ports
from fotobox.mailing import Email
#initiate logging
LOG_FILE = "/var/log/arduino_control.log"
logger = logging.getLogger('')
logger.setLevel(logging.DEBUG)
f = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh = logging.FileHandler(LOG_FILE)
fh.setFormatter(f)
logger.addHandler(fh)
class ArduinoControl:
def __init__(self, dev):
signal.signal(signal.SIGTERM, self.signal_handler)
self.dev = dev
self.run = True
self.open_port(dev)
self.go()
def open_port(self, dev):
self.port = serial.Serial(dev, 9600)
logger.debug(self.port.getSettingsDict())
def process_data(self, data):
if data == 'check':
self.port.write(data + '\n')
logger.info('written: "%s"', data)
def go(self):
while self.run:
try: data = self.port.readline().strip('\r\n')
except: self.error_handling()
if not data: continue
logger.info('received: "%s"', data)
self.process_data(data)
time.sleep(0.01)
def error_handling(self):
lines = traceback.format_exception(*sys.exc_info())
lines = [l[:-1] for l in lines]
logger.error(' ### '.join(lines))
def signal_handler(self, num, frame):
self.run = False
self.port.flushInput()
self.port.flushOutput()
self.port.close()
logger.info(num)
sys.exit()
def main():
port_name = sys.argv[1]
logger.debug(port_name)
arduino = ArduinoControl(port_name)
if __name__ == "__main__": main()