0

Well, I'm trying to get a Python script to communicate with an Arduino Uno. Basically the issue is the same as this, where the solution was to add a time.sleep(xx) (didn't work to me).

I've tried this on both Archlinux (jan-26 2014 up to date) and OSX 10.9.1 with the same results, both with Python 3.3.3.

BUT(!), if I run the .py while having the Arduino Monitor on, OR if I run the very same commands on ipython/python consoles, OR while running (pdb) the code runs just fine (!?!?) ...

This is my .ino:

char incomingByte;
const int comDelay = 200;
int count;
const int led = 3;              

void imHere(int led, int time, int blinks){ // blink led for bug control
  for (count  = 1; count <= blinks; count++){
    digitalWrite(led, HIGH);
    delay(time);
    digitalWrite(led, LOW);
    delay(time);
  }
}

void setup(){
  Serial.begin(9600); 
  pinMode(led, OUTPUT);
}

void loop(){   
  if( Serial.available() > 0){  
    incomingByte = Serial.read();
    delay(comDelay);    
    switch (incomingByte){
    case 't':                      // -t | 'test': communication test flag       
      imHere(led, 500, 2);         // incomingByte received witness 
      Serial.print('0');
      imHere(led, 50, 10);         // response sent witness
      //Serial.flush();
      break;
    default:
      imHere(led, 1500, 1);        // communication error witness
      Serial.print('-1');
      break; // error?
    }
  }
}

And this is my .py

#!/usr/bin/env python

import serial
import time
import sys
import os
import re
import pdb

def port_check():

    ## Check for the traditional Arduino port's on Linux and OSX, and check communication ##
    if sys.platform == 'linux':
        for file in os.listdir('/dev/'):
            if re.match('ttyA',file):
                port_name = '/dev/' + file

    elif sys.platform == 'darwin':
        for file in os.listdir('/dev/'):
            if re.match('tty.usbmodem',file):
                port_name = '/dev/' + file

    pdb.set_trace() ### DEBUG BEGINS

    ## create serial communication
    ser = serial.Serial(port_name, 9600) ## create serial communication
    #ser = serial.Serial(port_name, 9600, timeout = 3, interCharTimeout = 5) 

    print('\nDevice ' + port_name + ' detected')
    print('Stablishing communication throught ' + port_name)

    if ser.writable():
        print('Device writable')
        print('Testing communication ... ', end = "")
        ser.write(bytes('t','utf-8'))
        time.sleep(2)
        ser.flushInput()
    else:
        print('Device non writable')
        return -1

    time.sleep(2)
    response = 'no response'

    while ser.inWaiting() > 0:
        response = ser.read().decode('utf-8') 

    print(response)

    if response == '0':
        print('Done! :)\n')
        return ser
    else:
        print('Failed :(\n')

    ser.flush()
    ser.close() ## rember to take this out after debugging

if __name__ == "__main__":
    #check port configuration
    ser = port_check()

Basically the .py sends a 't', the .ino receives it and returns back a '0'.

Community
  • 1
  • 1
Fernando
  • 63
  • 1
  • 3

1 Answers1

1

Try adding a delay after the serial port has been opened. May not be fully ready to go by the time data is going in/out. Just for safety do it on both platforms!

Basically sleep/delay after:

ser = serial.Serial(port_name, 9600)

and

Serial.begin(9600); 
Wilsonator
  • 407
  • 1
  • 5
  • 14
  • It worked ... it was also critical to check that the delay time in the .ino is less than the time between time after opening the port and listening the response in the .py. – Fernando Jan 27 '14 at 03:12