Zwei Programme vereinen

Hallo zusammen

Ich habe ein Problem, denn ich versuche zwei Programme in eines zu vereinen. Eines ist, um einen Motor Anzusteuern und das Andere, um einen Winkel zu messen. Einzeln gehen sie, aber ich muss beide Sachen gleichzeitig machen können. In meinem Versuch wird nur noch der Winkel eingelesen, der Motor bewegt sich aber nicht mehr. Das erste Programme ist für den Winkel, dann für den Motor und dann zwei kombinierte Versionen, welche eben nicht funktionieren.
Ich wäre wirklich sehr dankbar für Hilfe.
Code für den Winkel:

#include<Wire.h>


const int MPU_addr=0x68;

int16_t axis_X,axis_Y,axis_Z;


int minVal=265;

int maxVal=402;


double x;

double y;

double z;

 



void setup(){

  Wire.begin();

  Wire.beginTransmission(MPU_addr);

  Wire.write(0x6B);

  Wire.write(0);

  Wire.endTransmission(true);

  Serial.begin(9600);

}

void loop(){

  Wire.beginTransmission(MPU_addr);

  Wire.write(0x3B);

  Wire.endTransmission(false);

  Wire.requestFrom(MPU_addr,14,true);

  axis_X=Wire.read()<<8|Wire.read();

  axis_Y=Wire.read()<<8|Wire.read();

  axis_Z=Wire.read()<<8|Wire.read();

    int xAng = map(axis_X,minVal,maxVal,-90,90);

    int yAng = map(axis_Y,minVal,maxVal,-90,90);

    int zAng = map(axis_Z,minVal,maxVal,-90,90);


       x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);

       y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);

       z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);


     Serial.print("Angle of inclination in X axis = ");

     Serial.print(y);

     Serial.println((char)176);

     Serial.println("-------------------------------------------");

     delay(250);

Code für den Motor:

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);

int pos = 3600;

void setup()
{  
  stepper.setMaxSpeed(3000);
  stepper.setAcceleration(1000);
}

void loop()
{
  if (stepper.distanceToGo() == 0)
  {
    delay(500);
    pos = -pos;
    stepper.moveTo(pos);\
  }
  stepper.run();
}

Diese beiden gilt es eben zu kombinieren.
Hier noch meine gescheiterten Versuche:
Hier habe ich alles hineinkopiert:

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);

int pos = 3600;

#include<Wire.h>


const int MPU_addr=0x68;

int16_t axis_X,axis_Y,axis_Z;


int minVal=265;

int maxVal=402;


double x;

double y;

double z;
void setup() {
  stepper.setMaxSpeed(3000);
  stepper.setAcceleration(1000);

  
  Wire.begin();

  Wire.beginTransmission(MPU_addr);

  Wire.write(0x6B);

  Wire.write(0);

  Wire.endTransmission(true);

  Serial.begin(9600);

}

void loop() {
if (stepper.distanceToGo() == 0)
  {
    delay(500);
    pos = -pos;
    stepper.moveTo(pos);\
  }
  stepper.run();

Wire.beginTransmission(MPU_addr);

  Wire.write(0x3B);

  Wire.endTransmission(false);

  Wire.requestFrom(MPU_addr,14,true);

  axis_X=Wire.read()<<8|Wire.read();

  axis_Y=Wire.read()<<8|Wire.read();

  axis_Z=Wire.read()<<8|Wire.read();

    int xAng = map(axis_X,minVal,maxVal,-90,90);

    int yAng = map(axis_Y,minVal,maxVal,-90,90);

    int zAng = map(axis_Z,minVal,maxVal,-90,90);


       x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);

       y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);

       z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);


     Serial.print("Angle of inclination in X axis = ");

     Serial.print(y);

     Serial.println((char)176);




     Serial.println("-------------------------------------------");

     delay(250);
}

Hier habe ich es noch mit subroutines versucht:

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);

int pos = 3600;

#include<Wire.h>
const int MPU_addr=0x68;
int16_t axis_X,axis_Y,axis_Z;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;

void setup() {
  stepper.setMaxSpeed(3000);
  stepper.setAcceleration(1000);

   Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
motorMethod();
winkelMethod();
}

void motorMethod(){
  if (stepper.distanceToGo() == 0)
  {
    delay(500);
    pos = -pos;
    stepper.moveTo(pos);\
  }
  stepper.run();
}

void winkelMethod(){
  Wire.beginTransmission(MPU_addr);

  Wire.write(0x3B);

  Wire.endTransmission(false);

  Wire.requestFrom(MPU_addr,14,true);

  axis_X=Wire.read()<<8|Wire.read();

  axis_Y=Wire.read()<<8|Wire.read();

  axis_Z=Wire.read()<<8|Wire.read();

    int xAng = map(axis_X,minVal,maxVal,-90,90);

    int yAng = map(axis_Y,minVal,maxVal,-90,90);

    int zAng = map(axis_Z,minVal,maxVal,-90,90);


       x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);

       y= (RAD_TO_DEG * (atan2(-xAng, -zAng)+PI));

       z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);


     Serial.print("Angle of inclination in X axis = ");

     Serial.print(y);

     Serial.println((char)176);
     
     Serial.println("-------------------------------------------");

     delay(250);}

winkel_messen1.ino (1.34 KB)

Mit_Library.ino (357 Bytes)

Library_und_Method.ino (1.7 KB)

Library_Winkel1.ino (1.58 KB)

Stelle bitte Deine Sketche lesbar ins Forum. Benutze dazu Codetags (</> oben links). Benutzte Libs bitte über einen Link bekannt machen.

Anhänge werden meist nicht gelesen.

Gruß Tommy

Hier habe ich es noch mit subroutines versucht:

Und da noch die Delays eliminieren.
Denn die stehen der Parallelverarbeitung entgegen.

Tipp:
Blinkwitthoutdelay

michael03024:
Ich habe ein Problem ...

Hat sich das inzwischen erledigt oder brauchst Du noch Hilfe?

Gruß

Gregor

Ich wäre um jede Hilfe froh...

michael03024:
Ich wäre um jede Hilfe froh...

Dann werde ich mir mal Deine Dateien vorknöpfen.

Combie sieht wohl ein Problem mit delay(). delay()s vermeidest Du am besten, indem Du einen „endlichen Automaten“ (FSM oder „finite state machine“) programmierst. Was mir dazu eingefallen ist findest Du hier und hier.

Gruß

Gregor

Ups, ich rede Stuss. Was für die Lösung Deines delay()-Problems am besten ist, kommt darauf an, was Du erreichen möchtest. Blockierende delay()s kann man vermeiden, wenn man sich den Startzeitpunkt eines Vorgangs merkt und in loop() immer wieder guckt, ob seither schon genug Zeit verstrichen ist.

Hallo nochmal,

die Sketche sind angenehm kurz.

Fang am besten damit an, einen neuen Sketch anzulegen. Die Variablen, die am jeweiligen Anfang stehen, kannst Du im neuen Sketch zusammenfassen. Doppelte Namen scheinen nicht vorzukommen. Gleiches gilt für die setup()-Teile. Ich sehe nicht, wo da Konflikte auftauchen sollten.

Dann hast Du „nur“ noch die beiden loop()-Teile, die zusammengefasst werden müssen. Das schaue ich mir an, wenn ich noch eine geraucht habe :slight_smile: Du kannst solange mal die ganzen Leerzeilen im Winkel-Sketch (der mit #include<wire.h> anfängt) löschen.

Gruß

Gregor

PS: Die beiden #include-Zeilen kannst Du natürlich auch in den Ziel-Sketch einfügen.

Hallo schowida!

Die loop()-Teile sehen ebenfalls problemlos aus. Wie ich das sehe, kannst Du den einen loop()-Teil mit dem anderen zusammen in den Ziel-Sketch schreiben.

Die delay()s sind wohl nur dazu da, dass der serielle Monitor nicht geflutet wird. Lass die einfach mal weg.

Wenn beim Kompilieren des Ziel-Sketches Fehler gemeldet werden, gib bitte die ganze Ausgabe an (und den aktuellen Stand des Ziel-Sketches). Wenn keine Fehler auftreten und alles so läuft, wie Du möchtest, bedankst Du Dich und gibst mir ein Fleißbildchen :slight_smile:

Gruß

Gregor

Kann es sein, dass die Zeile

  Wire.endTransmission(false);

den Vorgang blockiert? Der Motor läuft, bis ich diese Zeile in das Sketch einfüge. Danach bewegt er sich nicht mehr. Weiss vielleicht jemand wie man das umgehen kann?

Solange es nur einen Master gibt, gibt es keine Notwendigkeit dort ein false zu setzen.
Lass das doch einfach weg.

Statt:
Wire.endTransmission(false);

Einfach nur:
Wire.endTransmission();

Tipp 1:
Wire.endTransmission() hat einen Rückgabewert.

Tipp 2:
Den kann man auch auswerten.
(vielleicht hilft dir das ja....)

Stimmt. Wenn ich das False weglasse, wird trotzdem der richtige Winkel ausgegeben, jedoch blockiert der Befehl "Wire.endTransmission();" den Motor immer noch. Und ich möchte den Winkel einlesen, während sich der Motor bewegt.

Dir ist aber schon klar, dass keiner den jetzigen Zustand deines Programms sieht?

Es wäre hilfreich, wenn Du den aktuellen Stand des Sketches zeigen würdest. Allzu lang ist er ja nicht.

Gruß

Gregor

Das ist mein Sketch:

#include <AccelStepper.h>
#include<Wire.h>
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);
const int MPU_addr=0x68;
int16_t axis_X,axis_Y,axis_Z;
int pos = 3600;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;



void setup() {
stepper.setMaxSpeed(3000);
stepper.setAcceleration(1000);
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
 

}

void loop() {
  

if (stepper.distanceToGo() == 0)
  {pos = -pos;
   stepper.moveTo(pos);}
stepper.run();
  
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);
/*  Wire.endTransmission();
    Wire.requestFrom(MPU_addr,14,true);
    axis_X=Wire.read()<<8|Wire.read();
    axis_Y=Wire.read()<<8|Wire.read();
    axis_Z=Wire.read()<<8|Wire.read();
    int xAng = map(axis_X,minVal,maxVal,-90,90);
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);
       x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
       y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
       z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI); */


}

Das, was jetzt noch als Kommentar angemerkt ist, soll auch noch rein. Jedoch fährt der Motor nicht mehr, sobald die Zeile Wire.endTransmission() eingegeben wird. Wenn man das Sketch so auf den Arduino lädt, fährt der Motor, aber der Winkel wird logischerweise nicht eingelesen, weil ja der ganze Teil im Kommentar noch fehlt. Dieser Teil ist nämlich für den Winkel.

Ich sehe weiterhin keine Prüfung ob Wire.endTransmission(xxxxxx); erfolgreich war.
Scheint dir aus irgendeinem Grund nicht wichtig zu sein.
Selbst im Setup fehlt das.

Also nochmal(aber diesmal zum mitmeißeln):

Tipp 1:
Wire.endTransmission() hat einen Rückgabewert.

Tipp 2:
Den kann man auch auswerten.
(vielleicht hilft dir das ja....)

Ich kann natürlich nicht dafür garantieren, dass dich das zum Erfolg führt...
Aber ich kann dir garantieren, dass das ignorieren von Fehlermeldungen generell etwas bedenklich ist.

Vielen Dank für deine Hilfe, jedoch sehe ich nicht ganz, was du meinst. Ich bin ziemlich neu auf dem Gebiet.
Das hier ist das Programm für die Winkelmessung:

#include<Wire.h>
const int MPU_addr=0x68;
int16_t axis_X,axis_Y,axis_Z;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;

void setup(){

  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Serial.begin(9600);

}

void loop(){

  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);
  Wire.endTransmission();
  Wire.requestFrom(MPU_addr,14,true);
  axis_X=Wire.read()<<8|Wire.read();
  axis_Y=Wire.read()<<8|Wire.read();
  axis_Z=Wire.read()<<8|Wire.read();
    int xAng = map(axis_X,minVal,maxVal,-90,90);
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);
       x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
       y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
       z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

}

Dieses alleine funktioniert einwandfrei. Wo würdest du hier jetzt denn etwas ändern? So sehe ich auch keine Fehlermeldung.

Vielen Dank für deine Hilfe, jedoch sehe ich nicht ganz, was du meinst. Ich bin ziemlich neu auf dem Gebiet.

Du schaust in die Arduino Wire Doku.
Noch nie gemacht?
Dann wirds aber Zeit!

Hi nochmal!

Ich kenne die AccelStepper-Bibliothek nicht und die Doku dazu kann ich auf die Schnelle nicht finden. Du schreibst, dass sich der Motor nicht bewegt, wenn der auskommentierte Teil aktiv ist. Bewegt sich der Motor wirklich gar nicht, oder macht der nur einen Schritt und bleibt dann stehen?

Könntest Du ein Datenblatt zu dem MPU-Ding verlinken, das Du benutzt?

Gruß

Gregor

Das wäre das Datenblatt: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf

Wenn ich einstelle, dass er pro Loop-Durchgang einen Schritt machen soll, dann macht er nur einen Schritt ja...

michael03024:
Wenn ich einstelle, dass er pro Loop-Durchgang einen Schritt machen soll, dann macht er nur einen Schritt ja...

Macht er immer einen einzelnen Schritt? Auch, wenn der auskommentierte Teil drin ist? Egal, bei welcher Einstellung (außer 0, nä :-)?

Gruß

Gregor