Winkelfunktionen spucken falsche Werte aus?

Hey,

ich bastle mir gerade selber einen 3D Scanner zusammen und muss dafür die aufgenommenen Maße mit dem Aufnahmewinkel verrechnen, scheitere aber leider bei den Winkelfunktionen.

Beispiel: Ein rundes Objekt soll von vier Seiten mit jeweils 90° Abstand gescannt werden.
Zum berechnen der Koordinaten nutze ich nun folgende Zeilen:

var = 0

for(int i = 0; i < 4; i++) {


valx = val * cos(var);
valy = val * cos(var);

Serial.println(valx);
Serial.println(valy);

var = var + 1.570796327;                      // <- 90° als Bogenmaß
}

Es soll also jedes mal die X und Y Koordinate ausgespuckt werden und dann die Variable (var) für den Winkel um 90° (also 1.570796327 im Bogenmaß) hochgesetzt werden.

Eigentlich müsste ich jetzt für die 4 Schritte bei einer Entfernung von bspw. 50 mm folgende Ergebnisse bekommen:

valx = 50
Valy = 0

valx = 0
Valy = 50

valx = -50
Valy = 0

valx = 0
Valy = -50

Leider bekomme ich die Maße so ausgespuckt, als würde er 8-9 Messungen machen bis er einmal rum ist. Was mache ich falsch?

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Wie sind Deine Variablen deklariert? Gib uns lieber den kompletten Sketch.

Gruß Tommy

Dein Code macht was anderes als Du behauptest oder möchtest. Ein compilierbares Beispiel wäre hilfreich, und in Code Tags </>

Hier der gesamte Code. Bin noch ein Anfänger, also sorry wenn das alles nicht so professionell geschrieben ist.

int stepPin1 = 5;                             // Definition Schritte Motor 1
int dirPin1 = 4;                              // Definition Richtung Motor 1
int MS11 = 8;                                 // Definition Microstepping 1 Motor 1
int MS12 = 9;                                 // Definition Microstepping 2 Motor 1
int MS13 = 10;                                // Definition Microstepping 3 Motor 1
                                          
int stepPin2 = 7;                             // Definition Schritte Motor 2
int dirPin2 = 6;                              // Definition Richtung Motor 2
int MS21 = 11;                                // Definition Microstepping 1 Motor 2
int MS22 = 12;                                // Definition Microstepping 2 Motor 2
int MS23 = 13;                                // Definition Microstepping 3 Motor 2

int analogPin = A0;                           // Definition Sharp-Sensor    
int val = 0;                                  // Definition Ausgangsspannung
int valmw = 0;                                // Definition Ausgangsspannung Mittelwert
int valcalc = 0;                              // Definition Umgrechnete Distanz 

int valx = 0;                                 // Definition X-Wert
int valy = 0;                                 // Definition Y-Wert
int valz = 0;                                 // Definition Z-Wert

int var1 = 0;                                 // Definition Winkel-Schritt-Variable
int var2 = 0;                                 // Definition Höhenverstellungsvariable
//__________________________________________________________________________________________________________

void setup() {
  
    Serial.begin(9600);                       // Kommunikation mit dem seriellen Monitor starten
    pinMode(stepPin1,OUTPUT);                 // Pins Motor 1 deifinieren
    pinMode(dirPin1,OUTPUT);
    pinMode(MS11,OUTPUT);
    pinMode(MS12,OUTPUT);
    pinMode(MS13,OUTPUT);
    digitalWrite(MS11,LOW);
    digitalWrite(MS12,LOW);
    digitalWrite(MS13,LOW);

    pinMode(stepPin2,OUTPUT);                 // Pins Motor 2 deifinieren
    pinMode(dirPin2,OUTPUT);
    pinMode(MS21,OUTPUT);
    pinMode(MS22,OUTPUT);
    pinMode(MS23,OUTPUT);
    digitalWrite(MS21,LOW);
    digitalWrite(MS22,LOW);
    digitalWrite(MS23,LOW);
}
//__________________________________________________________________________________________________________

void loop() {

  digitalWrite(dirPin1,HIGH);                                                     // Motordrehrichtung 1 bestimmen
  digitalWrite(dirPin2,HIGH);                                                     // Motordrehrichtung 2 bestimmen
                  
  for(int i = 0; i < 4; i++) {                                                    // Schleife für Messungen 
         
             analogReadResolution(12);
             float valmw = 0.0;

             for(int i = 0; i < 10; i++) {                                         // Schleife für Mittelwertbildung
             
                 val = analogRead(analogPin);                                      // Ausgangsspannung messen                                
                 valmw = valmw + val;                                              // Mittelwert bilden
                 delay(100);
                 }
                 
             valmw = valmw / 10;                                                   // Mittelwertbildung
             valcalc = (158971.715090493 / (7.43320968736754 + (valmw))) - 7.44;   // Distanz ausrechnen
             valx = valcalc * cos(var1);                                           // X-Wert definieren Tiefe
             valy = valcalc * sin(var1);                                           // Y-Wert definieren Breite
             valz = var2;                                                          // Z-Wert definieren

            
             
             Serial.println(valcalc);                                            // Enfernung ausgeben
             Serial.println("X");
             Serial.println(valx);                                                 // X-Wert ausgeben 
             Serial.println("Y");
             Serial.println(valy);                                                 // Y-Wert ausgeben
             Serial.println("Z");
             Serial.println(valz);                                                 // Z-Wert ausgeben         
            

          
             for(int i = 0; i < 50; i++) {                                         // Schleife für Drehtellerrotation

                      digitalWrite(stepPin1,HIGH); 
                      delayMicroseconds(500); 
                      digitalWrite(stepPin1,LOW); 
                      delayMicroseconds(500);
                      delay(50);
                      
             }
 var1 = var1 + 1.570796327;              //(PI/180*90)                                           //Erhöhen der Variable 1                                                                                 
  }
  
  for(int i = 0; i < 50; i++) {                                                    // Schleife für Höhenverstellung
       
            digitalWrite(stepPin2,HIGH); 
            delayMicroseconds(500); 
            digitalWrite(stepPin2,LOW); 
            delayMicroseconds(500);
            }
            
  var2 = var2 + 2;                                                                  //Erhöhen de Variable 2
  
}

Hey Nikels,

habs mal überflogen. Kann es sein, dass du für den y Wert den sin brauchst? Sonst sind ja beide Werte gleich.

Hab mal die Variablen deklariert und bei mir gibt es die gewünschten Ergebnisse (bis auf ein blödes Minus vor manchen Nullwerten):

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  float var = 0;
  double val = 50;

  for (int i = 0; i < 4; i++)
  {;
    double valx = val * cos(var);
    double valy = val * sin(var);

    Serial.println(valx);
    Serial.println(valy);
    delay(2000);

    var = var + 1.570796327;                      // <- 90° als Bogenmaß
  }
}

Gruß Olli

Kommentare wie 'plus 1' sind herrlich sinnlos - DAS sehen selbst wir schon am Sketch.
Viel schöner wäre - WAS macht var1 und WAS var2 - warum sind Diese durchnummeriert?
analogReadResolution(12);
Das hätte ich bei Uno/Nano noch nicht gesehen - somit wirst Du wohl 'Was Anderes' benutzen - WAS?

valmw ... Mittelwert - soweit ja klar - warum nicht valMittelwert nennen? (wobei mw ja noch geht).

Was Dir die Berechnungen der trigonometrischen Funktionen zurück geben, hast Du noch nicht erwähnt - nur, daß Du mit anderen Ergebnissen gerechnet hast.
In wie fern unterscheiden Sich Soll von Ist?

MfG

@TO: Wenn Du alles mit int rechnest, brauchst Du Dich nicht zu wundern, wenn Mist raus kommt.
Probiers mal mit float.

Gruß Tommy

Und um mit dem Bogenmaß umzugehen ist es praktischer und lesbarer wenn man sich ein Makro schreibt um das umzurechnen

Ich arbeite noch mit "+1" weil ich wie gesagt noch ein Anfänger bin.
Variable 1 bestimmt den Winkel des Drehtellers und Variable 2 die Höhe des Sensors.
Und "valmw" statt "valMittelwert" ? Naja ich bin eben faul ^^

Aber es funktioniert jetzt alles. Ich hatte mich noch nicht mit float und double auseinander gesetzt und wusste nicht, dass das so einen großen Unterschied machen kann. Ich hab mir beides jetzt mal angeguckt erkenne den Unterschied nicht ganz. Es sorgen doch beide einfach für eine genauere Ausgabe oder nicht?

Danke schon mal für die Antworten :slight_smile:

Hi

Je verwendetem µC macht Das schon einen Unterschied - auf Uno/Nano sind Beide aber identisch.
Du verschweigst ja weiter, was für einen Arduino als Rechenknecht eingespannt hast.
Was spricht gegen sprechende Variablen-Namen?
WinkelDrehteller ist irgendwie wesentlich umgänglicher, als var1.
Oder HöheObjekt sagt direkt was ganz Anderes aus als var2.

Gewöhne Dir 'schönen' Code an - selbst Du wirst Dich in Deinem eigenen Code in einigen Wochen nur sehr mühsam zurecht finden - Da sind erklärende Kommentare (WAS soll diese Zeile eigentlich??) und sprechende namen Gold wert.

Schön, daß Es jetzt läuft :slight_smile: Hört man gerne!

MfG

MfG

nikels:
Es sorgen doch beide einfach für eine genauere Ausgabe oder nicht?

Dass Nachkommastellen abgeschnitten werden kann man zwar auch "ungenau" nennen. Praktisch macht es aber einen größeren Unterschied