Servoansteuerung exponentiell

Hallo, mein erster Post. Ich bin noch ganz am Anfang was das programmieren angeht. Speziell get es bei mir um das Ansteuern von 2 Servos über meinen Selbstgemachten Steuerknüppel. Dieser funktioniert über einen 2 Aches Hallsensor. Der code den ich verwende ist dieser hier:

Das funktioniert auch soweit, aber ich benötige eine exponentielle Funktion der Servos. Sie sollen bei Steuerknüppelbewegungen von ca, 50% nur in etwa 25% Ausschlag haben, und auf den restlichen 50% Knüppelweg dann auf Vollauschlag laufen. Wie kann ich das bewerkstelligen?

Vielen Dank
Torsten

ich kann den textcode leider nicht einfügen?

In der IDE rechte Maustaste "Für Forum kopieren", anschließend hier einfügen (Paste).

#include <Servo.h>

//**** servo 1 settings
Servo servo1; 
const int servo1PotPin =A5;
const int servo1Pin = 7;// Must use PWM enabled pin
int servo1Value;
int servoangle;
//**** servo 1 settings END

//**** servo 2 settings
Servo servo2; 
const int servo2PotPin =A3;
const int servo2Pin = 5;// Must use PWM enabled pin
int servo2Value;
//**** servo 1 settings END

void setup() {
  //Robojax.com multiple servo
  servo1.attach(servo1Pin); 
  servo2.attach(servo2Pin);   
}

void loop() {
  //Robojax.com multiple servo
  servo1Value = analogRead(servo1PotPin); 
  servo1Value = map(servo1Value, 0, 1023, 180, 0);
  servo1.write(servo1Value);

  servo2Value = analogRead(servo2PotPin); 
  servo2Value = map(servo2Value, 0, 1023, 0, 180);
  servo2.write(servo2Value);

  delay(5);
 //Robojax.com multiple servo  
}// loop end

Exponentiell oder quadratisch?

negatives Expo

f (0) = 0
f (1) = 1
f (0.5) = 0.25

sieht mir sehr nach y=x*x aus.

Die Frage wäre eher, wie man das mit Ganzzahl-Arithmetik hinkriegt.

expo

so in etwa

Hallo,
Du könntest mit Excell eine Tabelle erstellen, dann ein Diagramm dazu anlegen , Dann Kannst Du dir eine Trendlinie mit Funktion ermitteln lassen. Die Funktion baust Du dann in Deinem Sketch ein.
Berechnung als float , sonst kommt da nichts gescheites bei raus. Letztlich könnte das so aussehen. 512 auf der x Achse= Mittelstellung =90 Grad für den Servo.

0 0
128 50
256 66
384 80
512 90
640 100
768 110
896 130
1024 180

Die Herausforderung bleibt jetzt das in einem Arduino zu machen, da da nur 6 Stellen gerechnet werden, ich denke das geht aber.
Heinz

Hallo,
hab das gerade mal probiert, denke ist genau genug für den Fall. Mit obigen Werten getestet. Du musst halt letztlich mal sehen ob dir die Kurve zusagt.
getestet auf einem UNO


int x;
int y;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  for (int x = 0; x <= 1024; x += 32) {

    y = funktion(x);
    Serial.print(x); Serial.print("\t");
    Serial.println(y);

  }
}

void loop() {

}

int funktion(int x) {

  y = 4.84864E-7 * pow(float(x), 3) - 7.42638E-4 * pow(float(x), 2) +
      0.42447 * float(x) + 1.5959; 
  return y;
}

sieht dann so aus

y=+-x²

Sag ich doch :stuck_out_tongue:
6 signifikante Dezimalstellen sind für Berechnungen mit Potiwerten (Auflösung 0,1%) supergenau.
Vorher 512 subtrahieren, Vorzeichen merken, x², skalieren, 90 (bzw.1500µs) addieren ... geht auch in Ganzzahl, wenn man beim Multiplizieren und Skalieren aufpasst.

Hallo Rentner, cool, Danke. Kannst du mir auch noch sagen wie ich das in meinen obigen code einbauen muss? Ich hab da echt keinen Plan von.

Hallo,
Du liesst den analogwert ein , rechnest Ihn um , gibst Ihn aus. in Etwa so.

x= analogRead(pin);
y=funktion(x);
servo.write(y);

Hallo, Danke. Aber das sind böhmische Dörfer für mich. Ich hab versucht das in meinen code einzubauen, aber da kommen ganz viele Fehlermeldungen. :rofl:

Hallo,

@Rentner
Darf ich fragen wie man auf die Faktoren in dem Polynom kommt?

Nochwas. Der Endwert beträgt jedoch 1023. Nicht 1024.

Hallo,
probiere mal das, ich habs nicht komplett getestet.

@Doc_Arduino mit einer Tabellen calc
Werte aus 9 in die Tabelle eintragen ,in etwa das was gewünscht ist , In LibereOffice heisst das Trendlinie einfügen , dann im Dialog die Funktion auswählen (Polynomisch) Gleichung mit anzeigen, fertig :wink: Super gut geeignet um intergalaktische Faktoren von Messwerten in eine Näherungsgleichung zu bringen. :wink:

#include <Servo.h>

//**** servo 1 settings
Servo servo1; 
const int servo1PotPin =A5;
const int servo1Pin = 7;// Must use PWM enabled pin
int servo1Value;
int servoangle;
//**** servo 1 settings END

//**** servo 2 settings
Servo servo2; 
const int servo2PotPin =A3;
const int servo2Pin = 5;// Must use PWM enabled pin
int servo2Value;
//**** servo 1 settings END

void setup() {
  //Robojax.com multiple servo
  servo1.attach(servo1Pin); 
  servo2.attach(servo2Pin);   
}

void loop() {
  //Robojax.com multiple servo
  servo1Value = analogRead(servo1PotPin); 
  
  servo1.write(funktion(servo1Value));

  servo2Value = analogRead(servo2PotPin); 
  
  servo2.write(funktion(servo2Value));

  delay(5);
 //Robojax.com multiple servo  
}// loop end

int funktion(int x) {

int y = 4.84864E-7 * pow(float(x), 3) - 7.42638E-4 * pow(float(x), 2) +
      0.42447 * float(x) + 1.5959; 
  return y;
}

Wow, Hammer, das sieht schon sehr gut aus. Es fehlt jetzt etwas am gesamten Weg- Und an welchen Werten muss ich jetzt "drehen", um das feinzutunen?

Hallo,
habe die Excell Tabelle etwas geändert, ohne gehts nun mal nicht , kann aber ja nicht viel fehlen
dann versuch mal die Gleichung.

y = 6.02177E-7 * pow(float(x), 3) - 9.24043E-4 * pow(float(x), 2) +
      0.49111 * float(x) -0.08192; 
1 0
128 50
256 75
384 85
512 90
640 95
768 105
896 130
1022 180

ansonsten musst Du Dir mal die Werte des analogRead anzeigen lassen , was denn da die Grenzen tatsächlich sind und die dann in die Excell Tabelle eintragen.
Heinz

Danke, muss ich mal ausprobieren.

Es ist ein bisschen umständlich, aber Werte in ein Array eintragen und dann interpolieren ist auch nicht ganz ohne Aufwand zu bekommen. Am einfachsten ist es immer wenn man eine Gerade durchziehen kann, und y=ax+b rechnen kann, aber das geht ja nicht immer. :sob:
Gruß Heinz