Python-Arduino USB communication floats problem

Robin2:
I would be very suspicious of that. It may fail sometime. The concept of "float" is not limited to 3 decimal places.

And pleas post code in the Forum so we don't need to go to another website.

...R

As PaulS said in a previous post it's not a good idea to compare floats with "==".
In fact something like 'if (fabs(float1-float2)<epsilon (epsilon could be=0.0001...)'which means float1=float2 is better.
So when you limit (or round) the float only to 3 decimal places its like compare the difference with epsilon. I also tested many numbers that i had problem and worked properly.

The big disadvantage is that you are limited to 3 decimal.

NON_STRUCT

arduino

//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

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

STRUCT

arduino

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

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