Pages: [1]   Go Down
Author Topic: Arduino-Python USB serial communication  (Read 1730 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I've a problem interfacing arduino with a python program that I've written. I'd like to read a string of 231 char at least ten time per second. When I try to read the strings I see that the entire message is broken in more strings (not the buffer size) randomly in time.
Baudrate is 115200.
Can anyone help me in solving this problem?
Thank you in advance,
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12482
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Can you post your code, both Arduino and Python? That makes it easier for us to give some advice.

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok,

Code:

void setup() {
 int i;
 
 Serial.begin(115200);
 pinMode(outPin1,OUTPUT);
 pinMode(outPin2,OUTPUT);
 pinMode(outPin3,OUTPUT);

 flag=0;
 j=0;
 
 for (i=0; i<pidPinNum; i++) {
   Input[i] = myPID[i].getInput();
   myPID[i].SetMode(AUTOMATIC);
   myPID[i].setNTCcoefficents(-4.16734e-4,6.4803e-4,-2.0405e-6);
 }
}

void loop() {
 
  unsigned long start = millis();
  double f_value;
  int i_value,i_string,i,k;
  char signal_type;  
    
  if (start-previous > interval) {
      //Serial.println("Alive");    
      
          
      Serial.print("#A00#");
      Serial.print(analogRead(tempPin0));
      Serial.print("#A01#");
      Serial.print(analogRead(tempPin1));
      Serial.print("#A02#");
      Serial.print(analogRead(tempPin2));
      
      /*
      Serial.print("#s00#"); Serial.print(Setpoint,6);
      Serial.print("#p00#"); Serial.print(consKp,6);
      Serial.print("#i00#"); Serial.print(consKi,6);
      Serial.print("#d00#"); Serial.print(consKd,6);
      */
      for (k=0; k<pidPinNum; k++) {
        
        for (i=0; i<100; i++) { string[i]='\0';} Serial.print("#s0"); Serial.print(myPID[k].pinOutput); Serial.print("#"); dtostre(Setpoint[k]  ,string,4,' '); Serial.print(string);
        for (i=0; i<100; i++) { string[i]='\0';} Serial.print("#p0"); Serial.print(myPID[k].pinOutput); Serial.print("#"); dtostre(myPID[k].abKp,string,4,' '); Serial.print(string);
        for (i=0; i<100; i++) { string[i]='\0';} Serial.print("#i0"); Serial.print(myPID[k].pinOutput); Serial.print("#"); dtostre(myPID[k].abKi,string,4,' '); Serial.print(string);
        for (i=0; i<100; i++) { string[i]='\0';} Serial.print("#d0"); Serial.print(myPID[k].pinOutput); Serial.print("#"); dtostre(myPID[k].abKd,string,4,' '); Serial.print(string);      

        Serial.print("#m");Serial.print(myPID[k].pinOutput); Serial.print("#00"); Serial.print(myPID[k].GetMode());
      
        Serial.print("#o0");Serial.print(myPID[k].pinOutput); Serial.print("#");
        Serial.print(Output[k]);
        Serial.print("#I0");Serial.print(myPID[k].pinOutput); Serial.print("#");
        Serial.print(myPID[k].getInput());
    }


and the python side

Code:

class gui_arduino:
    def __init__(self,parent):
        self.win_os = False
        self.ser_var = ""

        try:
            self.ser = serial.Serial('/dev/tty.usbmodem1d11', 115200)
            #self.t = threading.Thread(target=self.serial_reader)
            #self.t.start()
        except:
            try:
                self.ser = serial.Serial('/dev/tty.usbmodem1a21', 115200)
            except:
                try:
                    self.ser = serial.Serial(port='COM4', baudrate=115200, dsrdtr=True)
                    #self.ser.databits=4
                    print self.ser
                except:
                    self.win_os = True

  def read_values(self):

        self.ser_var=self.ser.read(self.ser.inWaiting())
        if len(self.ser_var)>0:
            print self.ser_var

        ser_dict = {}
        ser_list = self.ser_var.split("#")
        #print ser_list
        try:
            ser_list.remove('')
        except ValueError:
            print "***********************Value Error"

        if len(ser_list) > 0:
            for i in range(0,len(ser_list)-1,2):
                ser_dict[ser_list[i]]=ser_list[i+1]
            #print ser_dict

            for key,item in ser_dict.items():
                if 'A' in key :
                    try:      
                        T=self.voltage2temperature(item)
                        #print key
                        #print key.split("A")[1]
                        #print T
                        self.AI_values["AI_%d"%(int(key.split("A")[1]))].set(T)
                    except KeyError:
                        pass
                    except ValueError:
                        pass
                      
                        
                elif 'D' in key:
                    try:
                        self.DI_values["DI_%d"%(int(key.split("D")[1]))].set(item)
                    except ValueError:
                        pass
                    except KeyError:
                            pass
                elif 'm' in key:
                    #print "%02d"%int(key.split("m")[1])
                    try:
                        button = self.AUTO_buttons["%02d"%int(key.split("m")[1])]
                        if button.getState() != int(item) :
                            button.setState(int(item))
                            
                    except KeyError:
                        pass
                elif 'I' in key:
                    self.PID_signals[key].set(item)
                    self.voltage2temperature(1023.)
                    
                elif 'o' in key:
                    self.PID_signals[key].set(item)
                else:
                    try:
                        if self.PID_entry[key][1] == True:
                        #print "here1: "+key+" "+item
                            self.PID_entry[key][0].set(item)
                    except:
                        pass

        
        self.root.after(sampling_time,self.read_values)

Obviously it's only a part of the code. Let me know if you want to know more.
Thanks,
« Last Edit: May 18, 2012, 05:40:28 am by scipius » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12482
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please post the whole code .................  as I cannot see the datatypes of vars and initialized value you use..... I cannot test the code here .....

OK,

What is the output of the Arduino sketch when you capture it with the serial monitor?

Does it shows the output you expect?
if so we can consider the arduino code to be correct,
if not what did you expect ?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Dallas, Texas
Offline Offline
Sr. Member
****
Karma: 3
Posts: 267
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, with your python code you should be more explicit in which exceptions you care to catch. The way the code is written any number of bad exceptions will be silently caught and ignored. Therefore, only catch the exceptions you know should cause that sequence of events and allow the other exceptions to alert you when you have exceptional behavior.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very good,
I try to explain the problem with a more simple and detailed example:

Arduino side:
Code:
long interval = 100;
long previous = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long start = millis();
 
  if (start-previous > interval) {
    Serial.print("1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890");
    previous = start;
  }

}


Pyhton side:
Code:
import time
import serial

if __name__ == '__main__':

    start = time.time()
    pass
   
    ser = serial.Serial(port='COM4', baudrate=115200, dsrdtr=True)
    while 1:
        ser_var=ser.read(ser.inWaiting())
        print time.asctime()+" "+ser_var
        time.sleep(0.1)
        if time.time()-start > 10:
            break
       
    ser.close()
    print "serial port close"

the output
Code:
Fri May 18 17:18:03 2012
Fri May 18 17:18:03 2012 1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890
Fri May 18 17:18:03 2012 1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890
Fri May 18 17:18:03 2012 1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890
Fri May 18 17:18:03 2012 1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890
Fri May 18 17:18:04 2012 1234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#12345678901234567890#0#1234567890#1#1234567890
Fri May 18 17:18:04 2012 #2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#12345678901234567890#0#1234567890#1#1234567890#2#1234567890#3#1234567890#4#1234567890#5#1234567890#6#1234567890#7#1234567890#8#1234567890#9#1234567890#10#1234567890#11#1234567890#12#1234567890#13#1234567890#14#1234567890

I cannot explain the last two communication strings (Fri May 18 17:18:04 2012). Can anyone help me?
Logged

Dallas, Texas
Offline Offline
Sr. Member
****
Karma: 3
Posts: 267
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

For starters, you have clock skew. You're making the assumption that both have exactly the same timing.

For testing, change your python:
Code:
import time
import serial

if __name__ == '__main__':

    start = time.time()
  
    ser = serial.Serial(port='COM4', baudrate=115200, dsrdtr=True)
    while 1:
        ser_var=ser.read(210)
        print time.asctime()+" "+ser_var
        
    ser.close()
    print "serial port close"

Also, are you sure you need dsrdtr enabled? You might just use, "serial.Serial(port='COM4', baudrate=115200)".
« Last Edit: May 18, 2012, 10:40:32 am by gerg » Logged


Pages: [1]   Go Up
Jump to: