我做了一个项目,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.
}
}
}
}
}
}
有关详细信息,您还可以查看我的视频:
答案 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