Timelapse Arduino 2.0 Speed setup Schrittmotor EIN und Ausschalten

Hallo
ich habe mir aus 2 StepperMotoren 28BYJ-48 mit Antrieb Modulplatine
ULN2003
eine 2 Achsen Timelapse Vorrichtung gebaut und konnte diese im letzten
Urlaub auch schon ausgiebig testen.

Wer nicht weiß was das ist hier ein schneller Link.
Youtube-Video Youtube-Video "DIY GoPro Pan/Tilt Time-Lapse Rig Part 2"

Ich möchte das ganze jetzt ein wenig erweitern und zwar das man die
Geschwindigkeit über ein Poti einstellen kann. Allerdings muss ich
zugeben das ich das Programm nicht selbst geschrieben habe sondern ein
netter User von hier hat es mir zu Verfügung gestellt.

Naja meine Idee war das ganz einfach über ein analogRead machen und dann
bei der Geschwindigkeit einfügen das funktioniert allerdings nicht

Jemand eine Idee ?

struct toyStepper_t{ 
  byte bluePin; byte pinkPin; byte yellowPin; byte orangePin; 
  unsigned long stepDelay; bool clockwise; byte curState; 
  unsigned int steps2go; unsigned long lastStepMicros;
};

toyStepper_t stepper[2]={
 {2,3,4,5, 200L*10, true, 0, 0, 0 },
 {8,9,10,11, 400L*10, true, 0, 0, 0 },
};


const int Taster=7; //Ein AusTaster
const int LEDPin=13;//Standby LED
const int sens=A0; //poti an A0

int valsens=0;
int Tasterstellung = LOW;  

const int NUMSTEPPERS= sizeof(stepper)/sizeof(toyStepper_t);
const byte lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

void updateStepper(byte index, long nowMicros)
{
  if (stepper[index].steps2go==0) return;
  if (nowMicros-stepper[index].lastStepMicros >=  stepper[index].stepDelay)
  {
    stepper[index].lastStepMicros= nowMicros;
    stepper[index].steps2go--;
    if (stepper[index].clockwise)
    {
      if (stepper[index].curState>0) stepper[index].curState--; else stepper[index].curState=7;
    }
    else
    {
      if (stepper[index].curState<7) stepper[index].curState++; else stepper[index].curState=0;
    }
    setOutput(index, stepper[index].curState);
  }
}

void setup() {
  //declare the motor pins as outputs
  for (int i=0; i<NUMSTEPPERS; i++)
  {
    pinMode(stepper[i].bluePin, OUTPUT);
    pinMode(stepper[i].pinkPin, OUTPUT);
    pinMode(stepper[i].yellowPin, OUTPUT);
    pinMode(stepper[i].orangePin, OUTPUT);
    setOutput(i, stepper[i].curState);
  }    

   pinMode(Taster,INPUT); // Taster INPUT
   pinMode(LEDPin,OUTPUT); //LED output
   pinMode(sens,INPUT); //Poti input

  Serial.begin(9600);
  Serial.println("Stepper demo");
}

const unsigned int stepsPerRevolution= 1600;

void loop(){
  
  Tasterstellung=digitalRead(Taster);
  valsens=analogRead(sens);
  
  long now=micros();

   if (Tasterstellung==HIGH){
    digitalWrite(LEDPin,LOW);
 
  for (int i=0; i<NUMSTEPPERS; i++) 
  {
    updateStepper(i, now);
    if (stepper[i].steps2go==0)
    {
      stepper[i].clockwise= !stepper[i].clockwise;
      stepper[i].steps2go= stepsPerRevolution;
    }
  }

   }
   else{
    digitalWrite(LEDPin,HIGH); }
}

void setOutput(byte index, byte state)
{
  digitalWrite(stepper[index].bluePin, bitRead(lookup[state], 0));
  digitalWrite(stepper[index].pinkPin, bitRead(lookup[state], 1));
  digitalWrite(stepper[index].yellowPin, bitRead(lookup[state], 2));
  digitalWrite(stepper[index].orangePin, bitRead(lookup[state], 3));
}

[/code*]

Wenn du das jetzt noch in Code-Tags (Schaltfläche </>) setzen würdest, ist es auch besser zu lesen.

tb1405:
Sorry ist mein erster Beitrag hier...
Kann man das nachträglich noch ändern ?

Ja, einfach [code*] davor und [/code*] dahinter setzen. Aber ohne den Stern *.

Dankeschön dann sollte es jetzt passen
zufällig auch eine Idee für mein Problem :smiley:

Ja, so passt es.

Aber bist du dir sicher, dass dieser Sketch funktioniert.

Ich kann ihn nicht kompilieren, da er mehrere Fehler hat, das muss ich erst rausfinden.

stepper[2] ist ein Array vom Typ toyStepper_t. Dort einfach beim Initialisieren der Variablenwerte eine andere Variable zu verrechnen funktioniert schon mal nicht wenn man diese Variable (valsens) erst später im Code deklariert.

Und beim Initialisieren werden keine Platzhalter, sondern Werte zugewiesen, d.h. es würde dort einmalig mit genau dem Wert gerechnet, der in valsens zu diesem Zeitpunkt drin steht. Spätere Änderungen an valsens haben auf die Werte in stepper[] keinen Einfluss mehr.

Wenn Du aber genau das möchtest (und das vermute ich, sonst machts ja keinen Sinn), dann musst Du innerhalb des loops nach lesen von valsens den entsprechenden Wert in der Strukturvariablen ändern.

HotSystems:
Ich kann ihn nicht kompilieren, da er mehrere Fehler hat, das muss ich erst rausfinden.

Da kann ich helfen. So kompiliert das Programm und ändert den Wert je nach Potistellung. Auf dem seriellen Monitor kann man die Veränderungen mitlesen:

struct toyStepper_t {
  byte bluePin; byte pinkPin; byte yellowPin; byte orangePin;
  unsigned long stepDelay; bool clockwise; byte curState;
  unsigned int steps2go; unsigned long lastStepMicros;
};
toyStepper_t stepper[2] = {

  {2, 3, 4, 5, 1000L * 10, true, 0, 0, 0 }, //Motor 1 Tilt 50-120° drehen
  {8, 9, 10, 11, 3000L * 14, true, 0, 0, 0 }, //Motor 2 PAN (360° drehen)
  //Hier wollte ich enfach das *10 durch valsens ersetzen das will er aber nicht.....
};

const int Taster = 7; // Ein AusTaster
const int LEDPin = 13; //Standby LED
const int sens = A0; //poti an A0

int valsens = 0;
int Tasterstellung = LOW;
const int NUMSTEPPERS = sizeof(stepper) / sizeof(toyStepper_t);
const byte lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
unsigned long altMillisPrint, now;

void updateStepper(byte index, long nowMicros)
{
  if (stepper[index].steps2go == 0) return;
  if (nowMicros - stepper[index].lastStepMicros >= stepper[index].stepDelay)
  {
    stepper[index].lastStepMicros = nowMicros;
    stepper[index].steps2go--;
    if (stepper[index].clockwise)
    {
      if (stepper[index].curState > 0) stepper[index].curState--; else stepper[index].curState = 7;
    }
    else
    {
      if (stepper[index].curState < 7) stepper[index].curState++; else stepper[index].curState = 0;
    }
    setOutput(index, stepper[index].curState);
  }
}


void setup() {
  //declare the motor pins as outputs
  for (int i = 0; i < NUMSTEPPERS; i++)
  {
    pinMode(stepper[i].bluePin, OUTPUT);
    pinMode(stepper[i].pinkPin, OUTPUT);
    pinMode(stepper[i].yellowPin, OUTPUT);
    pinMode(stepper[i].orangePin, OUTPUT);
    setOutput(i, stepper[i].curState);
  }
  pinMode(Taster, INPUT); // Taster INPUT
  pinMode(LEDPin, OUTPUT); //LED output
  pinMode(sens, INPUT); //Poti input

  Serial.begin(9600);
  Serial.println("Stepper demo");
}

const unsigned int stepsPerRevolution = 2200;

void loop() {
  Tasterstellung = digitalRead(Taster);
  valsens = analogRead(sens);
  stepper[1].stepDelay = 1000L * valsens;
  now = micros();

  if (Tasterstellung == HIGH) {
    digitalWrite(LEDPin, LOW);
    for (int i = 0; i < NUMSTEPPERS; i++)
    {
      updateStepper(i, now);
      if (stepper[i].steps2go == 0)
      {
        stepper[i].clockwise = !stepper[i].clockwise;
        stepper[i].steps2go = stepsPerRevolution;
      }
    }
  }
  else {
    digitalWrite(LEDPin, HIGH);
  }
  if (now - altMillisPrint >= 500) {
    Serial.print("valsens: ");
    Serial.print(valsens);
    Serial.print("  stepper[1].stepDelay: ");
    Serial.println(stepper[1].stepDelay);
  }
}

void setOutput(byte index, byte state)
{
  digitalWrite(stepper[index].bluePin, bitRead(lookup[state], 1));
  digitalWrite(stepper[index].pinkPin, bitRead(lookup[state], 0));
  digitalWrite(stepper[index].yellowPin, bitRead(lookup[state], 3));
  digitalWrite(stepper[index].orangePin, bitRead(lookup[state], 2));
}

Ob der Sketch aber funktioniert, vermag ich nicht zu sagen.

agmue:
Da kann ich helfen. So kompiliert das Programm und ändert den Wert je nach Potistellung. Auf dem seriellen Monitor kann man die Veränderungen mitlesen:

Ok, danke.
Zwischenzeitlich habe ich es auch kompilieren können und war mir nicht sicher, wo ich den "analogRead" nebst Übergabe einsetze. Da felt mir dann doch noch ein bissel Erfahrung mit den Steppern.

HotSystems:
... wo ich den "analogRead" nebst Übergabe einsetze.

Ich auch nicht, da ich mich um die Funktion des Sketches mal nicht gekümmert habe. Eigentlich wollte ich schreiben, was in #6 nun schon steht: "dann musst Du innerhalb des loops nach lesen von valsens den entsprechenden Wert in der Strukturvariablen ändern." Genau das habe ich gemacht, aber eben auch nur das.

Der TO kann uns ja berichten, wie es so läuft, werde mir jetzt mal das Video ansehen.

Hi
Also ich bin gerade nicht mehr Zuhause aber komme gegen 19:30 wd heim dann probiere ich es mal aus.
Ja Code hatte ein Fehler behebe den Fehler und probiere mal alles aus
Auf jeden Fall schon einmal tausend dank hätte nich erwartet das dass hier so schnell geht :stuck_out_tongue:

tb1405:
Der erste Motor lässt sich jetzt regeln der 2. will nicht so richtig

Was bedeutet das? Der zweite besegt sich, aber reagiert nicht auf das Poti? Dann macht der Sketch, was er soll:

stepper[1].stepDelay = 1000L * valsens;

Soll das Poti beide Motoren beeinflussen? Dann zusätzlich stepper[2].stepDelay = 3000L * valsens;

agmue:
Was bedeutet das? Der zweite besegt sich, aber reagiert nicht auf das Poti? Dann macht der Sketch, was er soll:

stepper[1].stepDelay = 1000L * valsens;

Soll das Poti beide Motoren beeinflussen? Dann zusätzlich stepper[2].stepDelay = 3000L * valsens;

genau aber iwie funktioniert das so nicht..
Jetzt hätte ich noch eine Frage ich mag das jetzt noch so machen das die Motoren per Tasterdruck anfangen zu steppen und auch weiter machen wenn ich den Taster wieder los lass und erst wieder ausgehen sobald ich erneut drücke
also das erste HIGH schaltet die Motoren ein
das 2. HIGH schaltet die Motoren aus.
Aber wie befehle ich den Motoren zu stoppen.
ich möchte es mit einem Merker machen hab schon angefangen will aber nicht so richtig

void loop() {
  Tasterstellung = digitalRead(Taster);
  valsens = analogRead(sens);
  stepper[1].stepDelay = 2000L * valsens/5;
  stepper[2].stepDelay = 3000L * valsens/5;
  now = micros();

  if ((Tasterstellung == HIGH)&&(merker==0))  {
    merker=1;
    digitalWrite(LEDPin, LOW);
    for (int i = 0; i < NUMSTEPPERS; i++)
    {
      updateStepper(i, now);
      if (stepper[i].steps2go == 0)
      {
        stepper[i].clockwise = !stepper[i].clockwise;
        stepper[i].steps2go = stepsPerRevolution;
      }
    }
  }
    if ((Tasterstellung == LOW)&&(merker==1)) 
    {   
      merker=2;
    }
     if ((Tasterstellung == HIGH)&&(merker==2)) 
    {   
      merker=3;
    }
 
  if (now - altMillisPrint >= 500) {
    Serial.print("valsens: ");
    Serial.print(valsens/10);
    Serial.print("  stepper[1].stepDelay: ");
    Serial.println(stepper[1].stepDelay);
  }
}
 [/code*]

ok leider zu früh gefreut musste festellen der motor 2 hat trotz einfügen von dem

stepper[2].stepDelay = 3000L * valsens;
keine einfluss durch den Poti der dreht sich konstant weiter

Sorry, ein Feld fängt mit dem Index 0 an zu zählen, also wohl besser stepper[0] und stepper[1] :-[

Jaaa jetzt klappt es.
Auf den Treiberboards sind auch LED´s jetzt erkennt man es schön das sie synchron leuchten :slight_smile:

Freut mich!

Wenn Du ein Foto von der Mechanik hier reinstellen würdest, fände ich das nett.

bin noch am basteln muss mal ein gutes Gehäuse auftreiben und ich möchte noch ein LCD ein bauen was dann die Geschwindigkeit anzeigt aber dazu brauche erst noch ein iic wandler :slight_smile:

http://www.bilder-upload.eu/show.php?file=7da215-1461097990.jpg

Ich habe das mal Probiert mit dem Taster ein und wieder ausschalten aber es will einfach nicht das Programm bringt mir folgenden Fehler
'setOutput' was not declared in this scope

Ich habe es mit einem merker probiert aber sobald ich die Pins auf Low deklarieren möxhte bringt er den Fehler.
jemand eine Idee

struct toyStepper_t {
  byte bluePin; byte pinkPin; byte yellowPin; byte orangePin;
  unsigned long stepDelay; bool clockwise; byte curState;
  unsigned int steps2go; unsigned long lastStepMicros;
};
toyStepper_t stepper[2] = {

  {2, 3, 4, 5, 1000L * 10, true, 0, 0, 0 }, //Motor 1 Tilt 50-120° drehen
  {8, 9, 10, 11, 1000L * 10, true, 0, 0, 0 }, //Motor 2 PAN (360° drehen)
  //Hier wollte ich enfach das *10 durch valsens ersetzen das will er aber nicht.....
};

const int Taster = 7; // Ein AusTaster
const int LEDPin = 13; //Standby LED
const int sens = A0; //poti an A0
int merker =0;
int valsens = 0;
int Tasterstellung = LOW;
const int NUMSTEPPERS = sizeof(stepper) / sizeof(toyStepper_t);
const byte lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};
unsigned long altMillisPrint, now;

void updateStepper(byte index, long nowMicros)
{
  if (stepper[index].steps2go == 0) return;
  if (nowMicros - stepper[index].lastStepMicros >= stepper[index].stepDelay)
  {
    stepper[index].lastStepMicros = nowMicros;
    stepper[index].steps2go--;
    if (stepper[index].clockwise)
    {
      if (stepper[index].curState > 0) stepper[index].curState--; else stepper[index].curState = 7;
    }
    else
    {
      if (stepper[index].curState < 7) stepper[index].curState++; else stepper[index].curState = 0;
    }
    setOutput(index, stepper[index].curState);
  }
}


void setup() {
  //declare the motor pins as outputs
  for (int i = 0; i < NUMSTEPPERS; i++)
  {
    pinMode(stepper[i].bluePin, OUTPUT);
    pinMode(stepper[i].pinkPin, OUTPUT);
    pinMode(stepper[i].yellowPin, OUTPUT);
    pinMode(stepper[i].orangePin, OUTPUT);
    setOutput(i, stepper[i].curState);
  }
  pinMode(Taster, INPUT); // Taster INPUT
  pinMode(LEDPin, OUTPUT); //LED output
  pinMode(sens, INPUT); //Poti input

  Serial.begin(9600);
  Serial.println("Stepper demo");
}

const unsigned int stepsPerRevolution = 2200;

void loop() {
  Tasterstellung = digitalRead(Taster);
  valsens = analogRead(sens);
  stepper[0].stepDelay = 1000L * valsens/10; //Motor 1 Tilt 50-120° drehen
  stepper[1].stepDelay = 1000L * valsens/10; //Motor 2 PAN (360° drehen)
  now = micros();

  if ((Tasterstellung == HIGH)&&(merker==0)) {
    merker=1;
    digitalWrite(LEDPin, LOW);
    for (int i = 0; i < NUMSTEPPERS; i++)
    {
      updateStepper(i, now);
      if (stepper[i].steps2go == 0)
      {
        stepper[i].clockwise = !stepper[i].clockwise;
        stepper[i].steps2go = stepsPerRevolution;
      }
    }
  }
  if((Tasterstellung == LOW)&&(merker==1)) {
    merker=2;
    
  }
  if ((Tasterstellung == HIGH)&&(merker==2)){
    merker=3;
    digitalWrite(LEDPin,HIGH);
    digitalWrite(stepper[i].bluePin, LOW);
    digitalWrite(stepper[i].pinkPin, LOW);
    digitalWrite(stepper[i].yellowPin, LOW);
    digitalWrite(stepper[i].orangePin, LOW);
  }
  if ((Tasterstellung ==LOW)&&(merker==3)){
    merker=0;
  }
    
  }
  if (now - altMillisPrint >= 500) {
    Serial.print("valsens: ");
    Serial.print(valsens);
    Serial.print("  stepper[1].stepDelay: ");
    Serial.println(stepper[1].stepDelay);
  }
}

void setOutput(byte index, byte state)
{
  digitalWrite(stepper[index].bluePin, bitRead(lookup[state], 1));
  digitalWrite(stepper[index].pinkPin, bitRead(lookup[state], 0));
  digitalWrite(stepper[index].yellowPin, bitRead(lookup[state], 3));
  digitalWrite(stepper[index].orangePin, bitRead(lookup[state], 2));
}

kann es sein das er durch das digitalWrite irgendwie den Bezug von dem OUTPUT verliert?
Bin am verzweifeln :confused:

Schreib mal eine eigene Funktionsdeklaration an den Anfang:

void setOutput(byte index, byte state);

Das hilft gegen 'setOutput' was not declared in this scope

'i' was not declared in this scope

... ist dann etwas leichter zu lösen :wink: