Python-Arduino USB通信浮动错误

时间:2018-05-23 11:37:06

标签: python c++ arduino serial-communication

我做了一个项目,python脚本与arduino进行通信,发送各种数据类型。 好吧一切都很好,除非arduino在某些情况下发回浮动。

例如: 当arduino发送数字4112.5时,-7631.5 python接收它们是正确的 在4112.112的情况下,-7631.23 python收到4112.11181641,-7631.22998047

造成这种情况的原因是什么?

Python代码:https://drive.google.com/file/d/1uKBTUW319oTh6YyZU9tOQYa3jXrUvZVF/view

import os 
import struct 
import serial
import time
print('HELLO WORLD!!!!\nI AM PYTHON READY TO TALK WITH ARDUINO\nINSERT 
PASSWORD PLEASE.')
ser=serial.Serial("COM5", 9600) #Serial port COM5, baudrate=9600
ser.close()
ser.open() #open Serial Port
a = int(raw_input("Enter number: ")) #integer object
b = int(raw_input("Enter number: ")) #integer object
c = float(raw_input("Enter number: ")) #float object
d = float(raw_input("Enter number: ")) #float object
time.sleep(2) #wait 
ser.write(struct.pack("2i2f",a,b,c,d)) #write to port all all number bytes
if a == 22 :
if b == -22 :
if c == 2212.113 :
   if d == -3131.111 :
      print("Congratulations!!! Check the ledpin should be ON!!!")
      receivedbytes=ser.read(16) #read from Serial port 16 bytes=2 int32_t + 2 
       floats from arduino
      (number1,number2,number3,number4,)=struct.unpack("2i2f",receivedbytes) 
      #convert bytes to numbers
      print "Arduino also send me back 
      ",str(number1),",",str(number2),",",str(number3),",",str(number4)
   else :
         print("WRONG PASSWORD")                           
os.system("pause") #wait for user to press enter

Arduino代码:https://drive.google.com/file/d/1ifZx-0PGtex-M4tu7KTsIjWSjLqxMvMz/view

struct sendata { //data to send
  volatile int32_t a=53;
  volatile int32_t b=-2121;
  volatile float c=4112.5;
  volatile float d=-7631.5;
};

struct receive { //data to receive
  volatile int32_t a; //it will not work with int 
  volatile int32_t b;
  volatile float c;
  volatile float d;
};

struct receive bytes;
struct sendata values;


const int total_bytes=16; //total bytes to send
int i;
byte buf[total_bytes]; //each received Serial byte saved into byte array


void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT); //Arduino Mega ledpin
  }


void loop() {

}

void serialEvent() { //Called each time Serial data is received
      if (Serial.available()==total_bytes){ //Receive data first saved 
  toSerial 
  buffer,Serial.available return how many bytes are saved.The Serial buffer 
  space is limited.
         while(i<=total_bytes-1){
             buf[i] = Serial.read(); //Save each byte from Serial buffer to 
  byte 
  array
             i++;
         }
         memmove(&bytes,buf,sizeof(bytes)); //Move each single byte memory 
  location of array to memory field of the struct,the numbers are 
  reconstructed 
  from bytes.
         if (bytes.a==22){ //Access each struct number.
           if (bytes.b==-22){
            if (bytes.c==2212.113){
              if (bytes.d==-3131.111){ //If the password is right
                  Serial.write((const uint8_t*)&values,sizeof(values)); 
  //Write 
  struct to Serial port.
                  delay(100);
                  digitalWrite(13,HIGH);//Turn ON LED.
              }
            }
          }
        }
     }
   }  

有关详细信息,您还可以查看我的视频:

https://www.youtube.com/watch?v=yjfHwO3qSgY&t=7s

1 个答案:

答案 0 :(得分:0)

好吧,经过几次测试后,我发现我只能在8位Arduino和Python之间发送浮点数,最多可以精确计算3位小数。 我还写了一个非结构代码:

编辑:添加代码

NON_STRUCT

Arduino方面:https://drive.google.com/file/d/1lvgT-LqQa7DxDorFF0MTe7UMpBfHn6LA/view?usp=sharing

//values to send//
int32_t aa=53; 
int32_t bb=-2121;
float cc=4112.3; //each float must have max 3 decimal places else it will 
#rounded to 3!!
float dd=-7631.23;
////***/////

///values to receive////
int32_t a; //it will not work with int 
int32_t b;
float c;
float d;
int i,e;
/////****////

void setup() {
 Serial.begin(9600);
  pinMode(13,OUTPUT); //Arduino Mega ledpin
  }


void loop() {

}

void serialEvent() { //Called each time Serial data is received
  a=Serial.parseInt();
  b=Serial.parseInt();
  c=Serial.parseFloat();
  d=Serial.parseFloat();
  if (a==22){ //Access each struct number.
     if (b==-22){
         if (c==2212.113){
            if (d==-3131.111){ //If the password is right
                Serial.println(aa);
                Serial.println(bb);
                Serial.println(cc,3); //must be <=3 decimal places else it 
//will 
//rounded
                Serial.println(dd,3); //must be <=3 decimal places else it 
//will 
//rounded
                delay(100);
                digitalWrite(13,HIGH);//Turn ON LED.
            }
         }
      }
   }
}

Python方面:https://drive.google.com/file/d/1gPKfhTvbd4vp4L4VrZuns95yQoekg-vn/view?usp=sharing

import os 
import struct 
import serial
import time
print('HELLO WORLD!!!!\nI AM PYTHON READY TO TALK WITH ARDUINO\nINSERT 
PASSWORD PLEASE.')
ser=serial.Serial("COM5", 9600) #Serial port COM5, baudrate=9600
ser.close()
ser.open() #open Serial Port
a = int(raw_input("Enter number: ")) #integer object
b = int(raw_input("Enter number: ")) #integer object
c = float(format(float(raw_input("Enter number: ")), '.3f'))#float object # 
#<=3 
#decimal places
d = float(format(float(raw_input("Enter number: ")), '.3f'))
time.sleep(2) #wait 
ser.write(str(a).encode()) #convert int to string and write it to port 
ser.write('\n'.encode())
ser.write(str(b).encode())
ser.write('\n'.encode())
ser.write(str(c).encode())
ser.write('\n'.encode())
ser.write(str(d).encode())
ser.write('\n'.encode())
if str(a) == "22" :
 if str(b) == "-22" :
  if str(c) == "2212.113" :
   if str(d) == "-3131.111" :
    print("Congratulations!!! Check the ledpin should be ON!!!")
    number1=int(ser.readline()) #read from Serial port convert to int
    number2=int(ser.readline())
    number3=float(ser.readline()) ##read from Serial port convert to float 
#(3 
#decimal places from arduino)
    number4=float(ser.readline())
    print "Arduino also send me back 
",str(number1),",",str(number2),",",str(number3),",",str(number4)
   else :
      print("WRONG PASSWORD")
os.system("pause") #wait for user to press enter

WITH_STRUCT更好的表现

Arduino方面:https://drive.google.com/file/d/153fuSVeMz2apI-JbDNjdkw9PQKHfGDGI/view?usp=sharing

struct sendata { //data to send
  volatile int32_t a=53;
  volatile int32_t b=-2121;
  volatile float c=4112.3;
  volatile float d=-7631.4;
 };

struct receive { //data to receive
  volatile int32_t a; //it will not work with int 
  volatile int32_t b;
  volatile float c;
  volatile float d;
};

struct receive bytes;
struct sendata values;


const int total_bytes=16; //total bytes to send
int i;
byte buf[total_bytes]; //each received Serial byte saved into byte array


void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT); //Arduino Mega ledpin
 }


void loop() {

}

void serialEvent() { //Called each time Serial data is received
  if (Serial.available()==total_bytes){ //Receive data first saved to Serial 
//buffer,Serial.available return how many bytes are saved.The Serial buffer 
//space 
//is limited.
       while(i<=total_bytes-1){
           buf[i] = Serial.read(); //Save each byte from Serial buffer to 
//byte 
//array
            i++;
       }
       memmove(&bytes,buf,sizeof(bytes)); //Move each single byte memory 
//location of array to memory field of the struct,the numbers are 
//reconstructed 
//from bytes.
      if (bytes.a==22){ //Access each struct number.
        if (bytes.b==-22){
          if (bytes.c==2212.113){
             if (bytes.d==-3131.111){ //If the password is right
                Serial.write((const uint8_t*)&values,sizeof(values)); //Write 
//struct to Serial port.
                delay(100);
                digitalWrite(13,HIGH);//Turn ON LED.
             }
           }
         }
      }
   }
}

Python方面:https://drive.google.com/file/d/1M6iWnluXdNzTKO1hfcsk3qi9omzMiYeh/view?usp=sharing

import os 
import struct 
import serial
import time
print('HELLO WORLD!!!!\nI AM PYTHON READY TO TALK WITH ARDUINO\nINSERT 
PASSWORD PLEASE.')
ser=serial.Serial("COM5", 9600) #Serial port COM5, baudrate=9600
ser.close()
ser.open() #open Serial Port
a = int(raw_input("Enter number: ")) #integer object
b = int(raw_input("Enter number: ")) #integer object
c = float(format(float(raw_input("Enter number: ")), '.3f'))#float object 
#<=3 
#decimal places
d = float(format(float(raw_input("Enter number: ")), '.3f'))
time.sleep(2) #wait 
ser.write(struct.pack("2i2f",a,b,c,d)) #write to port all all number bytes
if a == 22 :
 if b == -22 :
  if c == 2212.113 :
   if d == -3131.111 :
    print("Congratulations!!! Check the ledpin should be ON!!!")
    receivedbytes=ser.read(16) #read from Serial port 16 bytes=2 int32_t + 2 
#floats from arduino
    (number1,number2,number3,number4,)=struct.unpack("2i2f",receivedbytes) 
#convert bytes to numbers
   number3=float(format(number3, '.3f')) #floats must be under 3 decimal 
#points else will be rounded
    number4=float(format(number4, '.3f'))
    print "Arduino also send me back 
",str(number1),",",str(number2),",",str(number3),",",str(number4)
   else :
      print("WRONG PASSWORD")
os.system("pause") #wait for user to press enter

Youtube视频:https://www.youtube.com/watch?v=yjfHwO3qSgY&t=170s