Fehler beim Compilieren der PID

Hallo Alle,

in dem folgendem Code wird eine PID-funktion gerechnet, und das Ergebnis (y) möchte ich per I2c an die Motoren übermitteln. dabei sind die Eingänge mit 0x48 und 0x47 definiert. Alle Parameter mit float, aber es tritt immer einen Fehler auf und kann nicht kompiliert. brauche Tipps wo der Fehler sein könnte,

...........
# define motor_left 0x47
# define motor_right 0x48


{....................
error = abs(Setpoint-Input);                                               // Abweichung=w-x

     delta_t = micros() - t_alt;                                       
     float esum = esum + (error * delta_t);                            //summiert die Abweichung 
      int_term = esum*delta_t ;                                          //berechnet Integrator über die Zeit
     e_dif = error - error_alt; 

  double y = (Kp* error) + (guard * Ki * int_term) + (Kd * diff_term) ;   // PID-funktion
       
    if (y < -255) {y = -255;}            
    else if (y > 255) {y = 255;}
   
   RightMotorOut += y;
   LeftMotorOut -= y;
    
	if (RightMotorOut < 0){RightMotorOut = 0;	}
      else if(RightMotorOut > 255){RightMotorOut = 255;}
	
	if (LeftMotorOut < 0){
		LeftMotorOut = 0;}
       else if(LeftMotorOut > 255){LeftMotorOut = 255;}
        
	Wire.beginTransmission(motor_right);
	Wire.write(RightMotorOut);                               // Fehler tritt hier auf
	Wire.beginTransmission(motor_left);
	Wire.write(LeftMotorOut);}                             // Fehler tritt hier auf

Der Fehler
“call of overloaded ‘write(double&)’ is ambiguous”

Dann zeige uns mal den kompletten Sketch.
So wie oben ist er nicht zu kompilieren.

Was da nicht eindeutig ist, ist nicht so klar, aber write() ist eigentlich für double gar nicht definiert. Sondern in der Print Klasse nur für byte, byte* (d.h. Arrays) und char* (d.h. C Strings).
In der Wire Klasse gibt es dann noch Versionen für int und long, die aber lediglich die Integer auf byte casten, wodurch sie abgeschnitten werden.

Eine einfache Lösung ist eine Union aus einem double/float und einem Byte Array der Länge 4 (auf dem AVR). Dann kann man einfach einen float schreiben und das Array per I2C verschicken. Weil sich die Variablen einer Union den gleichen Speicher teilen.

Wahrscheinlich wollen die Motor-Treiber garkeine double, schon weil es dafür zu viele unterschiedliche Formate gibt.

DrDiettrich:
Wahrscheinlich wollen die Motor-Treiber garkeine double, schon weil es dafür zu viele unterschiedliche Formate gibt.

oh doch, die einzige Kommunizierung ist die I2c anders gehts nichts :frowning:

Wie gesagt:

union Data
{
   double asFloat;
   byte asBytes[sizeof(double)];
};

Dann geht sowas:

Data value;
value.asFloat = 45.5;

Wire.write(value.asBytes, sizeof(value));

TheTraveler:
oh doch, die einzige Kommunizierung ist die I2c anders gehts nichts :frowning:

Über I2C läßt sich beliebige Information übertragen, das ist kein schlagendes Argument.

Es wäre einfacher wenn Du uns verrätst, was für ein Chip über I2C angesprochen werden soll, und ein Link auf sein Datenblatt. Da steht dann drin, was der für Daten erwartet.