Go Down

Topic: Arduino-Python USB serial communication (Read 2 times) previous topic - next topic

scipius

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,

robtillaart


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

Rob Tillaart

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

scipius

#2
May 18, 2012, 12:37 pm Last Edit: May 18, 2012, 12:40 pm by scipius Reason: 1
ok,

Code: [Select]


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: [Select]


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,

robtillaart

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 ?
Rob Tillaart

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

gerg

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.

scipius

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

Arduino side:
Code: [Select]

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: [Select]

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: [Select]

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?

gerg

#6
May 18, 2012, 05:37 pm Last Edit: May 18, 2012, 05:40 pm by gerg Reason: 1
For starters, you have clock skew. You're making the assumption that both have exactly the same timing.

For testing, change your python:
Code: [Select]

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)".

Go Up