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'.

有帮助吗?

解决方案

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); 
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top