Hoe kan ik een geschutstoren 290 graden laten draaien

Discussie in 'Model elektronica' gestart door Herby63, 4 sep 2021.

  1. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Wat voor steppers gebruik je?
    Ik dacht dat je prefereerde om het zelf te kunnen.......

    Dat zal op een soortgelijk manier moeten gaan als bij een servo, target zetten en dan stapje voor stapje daar naartoe werken. Maar je hebt wel gelijk, je moet een ijkpunt hebben. Dus ofwel het punt waarop de toren staat als je de arduino inschakelt, ofwel een procedure om eerst een eindschakelaar op te zoeken, en dat als ijkpunt te nemen.
    Maar het wordt inderdaad wel wat ingewikkelder.
     
    Laatst bewerkt: 30 aug 2022
  2. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Dat is ook zo, Max, het was een grapje, Ik waardeer ten zeerste de begeleiding die ik geniet, maar als ik begrijp wat ik moet doen, probeer ik het graag eens zelf.

    De stepper die in de Elegoo super starter kit zit, een ROHS 28BYJ-48, courant verkrijgbaar bij onze vertrouwde Chinese webshop.
    Na enig opzoekwerk lijkt mij dat één van de kleinste op de markt te zijn, toch wat inbouwhoogte betreft, en de vrije hoogte onder de achterste geschutstoren is eerder beperkt, met de aandrijflijn er onder.
     
  3. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Toevallig heb ik die ook liggen :), in een overgenomen boedel van iemand die er de brui aan gaf...ook veel onnodig spul :(
    Er is wat onduidelijkheid op het web over het aantal stappen van de motor zelf, en de gebruikte vertraging. Iemand haalde 'm uit elkaar en zag een vertraging van 1:16, en een motor met 32 (halve?) stappen, in totaal dus 512 stappen aan de uitgaande as.
    Heb jij misschien het "StepperOneRevolution" voorbeeld uit de Arduino website gedraaid om dat te verifiëren?
     
    Laatst bewerkt: 30 aug 2022
  4. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Help :)
    Als ik de code voor de stepper integreer in de code uit post 208, krijg ik een foutmelding op de eerste lijn van de void setup
    attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0 dat read_pwm was not declared in this scope.
    Ik heb nochtans niets verwijderd, en controle met de naakte code uit post 208, geeft geen foutmelding.
    Dit heb ik er voorlopig van gemaakt ( nog geen puls geïntegreerd, enkel de 2 codes samengevoegd).
    Code:
    #include <Stepper.h>
    const int stepsPerRevolution=2048;
    int motSpeed=1;
    
    const int myPotPin=A2;
    int readVal;
    const int motDir=1;
    const int buttonPinSB=6;
    const int buttonPinBB=7;
    bool buttonSBRead;
    bool buttonBBRead;
    const int dt=250;
    Stepper myStepper(stepsPerRevolution, 8,10,9,11);
    
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse, seqnr = 20;
    volatile int Plist[16];
    int pulse, target;
    uint8_t mpcount;
    int Outpulse[16]; // size equals maximum nr of servo's on Adafruit PCA9685 breakout
    const int slowstep = 1, servomax = 8; // number of servos in use
    const int targetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
    const int targethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
    
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    
    // called this way, it uses the default address 0x40
    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
    
    void setup() {
     
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      pwm.begin();
    
      pwm.setOscillatorFrequency(27000000);
      pwm.setPWMFreq(50); // 50Hz, frame length 20 millis
    
      // starting output pulse value, equivalent of 1500 micros
      for (uint8_t i=0; i<servomax; i++) {
        Outpulse [i] = 308;
        pwm.setPWM(i, 0, Outpulse [i]);
      }
      {
        myStepper.setSpeed(motSpeed);
        pinMode(buttonPinSB, INPUT_PULLUP);
        pinMode(buttonPinBB, INPUT_PULLUP);
      }
    
      delay(10);
    }
    
    void loop() {
    
      for (mpcount = 0; mpcount < servomax; mpcount ++) {
       
        cli(); // stop interrupt interference
        pulse = Plist[mpcount]; // get latest pulse
        sei(); // release interrupt
       
        //Serial.print ("mpcount = "); Serial.print (mpcount); Serial.print ("     pulse = "); Serial.println (pulse);
    
        target = map (pulse, 1030, 1980, targetlow [mpcount], targethigh [mpcount]); // extending pulse to target
       
        // retrieve previous Outpulse and calculate new value for Outpulse
        if ((target - Outpulse [mpcount]) >= slowstep) Outpulse [mpcount] += slowstep;
        else if ((target - Outpulse [mpcount]) <= -slowstep) Outpulse [mpcount] -= slowstep;
        else Outpulse [mpcount] = target;
    
        // send Outpulse
        pwm.setPWM(mpcount, 0, Outpulse [mpcount]); // LOW>HIGH at 0, HIGH>LOW at pulselen
      }
      delay (10); // change to decrease servo speed.
     
      buttonSBRead=digitalRead(buttonPinSB);
      buttonBBRead=digitalRead(buttonPinBB);
    
      //delay(dt);
      readVal=analogRead (myPotPin);  // uitlezen van de waarde van de potentiometer met min = 70 en max = 1010
      //Serial.print ("Potval = ");
      //Serial.print (readVal);
      //Serial.print("   SBbutton = ");
      //Serial.print(buttonSBRead);
      //Serial.print("   BBbutton = ");
      //Serial.println(buttonBBRead);
      //delay(dt);
    
      if (readVal <=300 && buttonSBRead==1){
        myStepper.step(motDir*-1);
    }
      if (readVal >=530 && buttonBBRead==1){
        myStepper.step(motDir*1);
    }
    
    void read_pwm(){
      if (PIND & 0b00000100) { // if pin 2 is high
        timer = micros(); // start timer
      }
      else { // else pin 2 is low
        inpulse = ((volatile int)micros() - timer); // read timer
       
        if (inpulse<950)  seqnr = -1; // reset seqnr for next incoming pulses to start with 0
        else {
          seqnr += 1;
          if (seqnr < 16) Plist[seqnr] = inpulse;
        }
      }
    }
     
  5. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Dat gebeurt omdat de structuur niet meer klopt, en de code "denkt" dan dat read_pwm een variabele is, die niet gedeclareerd is.
    Dit gaat zo echt niet werken, je moet eerst de hele inhoud van de loop in mijn code weggooien, en de twee stukjes die ik aangaf er in plaatsen. Dan kun je vrijwel alles in de setup weggooien, op het declareren van de interrupt routine na, de pinMode van pin 2 als input (de interrupt waar de ontvanger op aangesloten wordt). Dan voeg je de pinModes van jouw code toe, en de Motspeed setup.
    Boven de setup gooi je al mijn declaraties weg, behalve alle "volatiles", dat zijn de variabelen die in de interrupt routine voorkomen. Daarna moet je alle variabelen die je in de loop gebruikt declareren. Vervolgens declareer je daar ook de "Stepper" library.
    dan nog eens verifiëren en dan kunnen we kijken wat er nog mist.
     
    Herby63 vindt dit leuk.
  6. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Vergeten, deze code moet er ook nog bij in de loop:
    Code:
      buttonSBRead0=digitalRead(buttonPinSB0);
      buttonBBRead0=digitalRead(buttonPinBB0);
    En alle variabelen die specifiek zijn voor een stepper krijgen een 0, waaronder ook dus mystepper0
     
  7. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Mag ik die 0 vervangen door een naam? Bij de Bismarck hadden de 4 geschutstorens een naam: Anton, Bruno, Caesar en Dora. Het zou gemakkelijk zijn om alle code voor een bepaalde geschutstoren aan te duiden met de naam van de bijhorende toren.
     
  8. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Dat had ik al voorzien :)
    maar tot nu toe bak ik er niet veel van. Ik probeer nog een laatste maal, fingers crossed :)
     
  9. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Ja, dat kan ook, maar de elementen van array Plist [ ] zullen met cijfers 0 - 3 aangeduid moeten blijven, dus het lijkt mij overzichtelijker als je de andere variabelen ook dezelfde referentie houden.
     
  10. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Aha, OK, ik ga het proberen
     
  11. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Ik heb meermaals geprobeerd, ..., en gefaald.
    ik zie me verplicht de handdoek in de ring te gooien, :(
    Ik heb waarschijnlijk iets te veel verwijderd, want de stepper begint onmiddellijk te draaien in richting -1, reageert wel op de eindswitch, maar luistert niet naar de potmeter op de zender.
    Met een code van een paar weken geleden heb ik gecontroleerd of de puls wel op de UNO toekomt, en deze test was positief.
    Maar als ik "pulse" naar de serial monitor uitprint krijg ik alleen maar waarde 0, vandaar dat de stepper in tegenwijzerzin draait.
    Waar ga ik de mist in?
    Omdat ik steeds de foutcode "pulse is not declared in this scope" krijg heb ik bovenaan "int pulse;" toegevoegd, wat waarschijnlijk niet nodig is, maar ik zie door de code de bomen niet meer. :hammer:
    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse, seqnr = 20;
    volatile int Plist[16];
    int pulse;
    
    #include <Stepper.h>
    const int stepsPerRevolution=2048;
    int motSpeed=1;
    const int motDir=1;
    const int buttonPinSB0=6;
    const int buttonPinBB0=7;
    bool buttonSB0Read;
    bool buttonBB0Read;
    const int dt=250;
    Stepper myStepper0(stepsPerRevolution, 8,10,9,11);
    
    void setup() {
      // put your setup code here, to run once:
     
      Serial.begin(9600);
      myStepper0.setSpeed(motSpeed);
    
      pinMode(buttonPinSB0, INPUT_PULLUP);
      pinMode(buttonPinBB0, INPUT_PULLUP);
    
    }
    
    void loop() {
      buttonSB0Read=digitalRead(buttonPinSB0);
      buttonBB0Read=digitalRead(buttonPinBB0);
    
        cli(); // stop interrupt interference
        pulse = Plist[0]; // get latest pulse for stepper 0
        sei(); // release interrupt
     Serial.println (pulse);
       if (pulse <=1300 && buttonSB0Read==1){
          myStepper0.step(motDir*-1);
        }
        if (pulse >=1700 && buttonBB0Read==1){
          myStepper0.step(motDir*1);
    
    }
    }
    void read_pwm(){
      if (PIND & 0b00000100) { // if pin 2 is high
        timer = micros(); // start timer
      }
      else { // else pin 2 is low
        inpulse = ((volatile int)micros() - timer); // read timer
        
        if (inpulse<950)  seqnr = -1; // reset seqnr for next incoming pulses to start with 0
        else {
          seqnr += 1;
          if (seqnr < 16) Plist[seqnr] = inpulse;
        }
      }
    }
     
  12. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Dat is in ieder geval correct.
    Ik moet bekennen dat ik ook de code opgesteld had volgens mijn eigen instructies, en dat mijn stepper geen enkel teken van leven geeft, geen van de leds brandt, niets :(

    Wel is de declaratie van mystepper0 bij jou een beetje vreemd, ik heb de stepper aangesloten volgens DEZE pagina (unipolar stepper circuit), en de aansluitingen gedefinieerd op volgorde
    Code:
    Stepper myStepper0(stepsPerRevolution, 8,9,10,11);
    zoals ook in de voorbeeld code te zien is.

    Maar zoals gezegd, zonder resultaat.
     
  13. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    In jouw setup ontbreekt trouwens wel de interrupt attach:
    Code:
      attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
  14. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Volgens Toptechboy.com - Paul McWorther is de pinvolgorde 8,10,9,11. Helpt dat? Bij een 28BYJ-48 werkt dat in ieder geval bij mij.
     
  15. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Toegevoegd in void setup en ... Eureka, het werkt, de stepper staat stil met pot in neutraalstand, draait de ene richting op als de pot ver genoeg verdraaid wordt, stopt als de bijhorende eindswitch ingedrukt wordt en reageert gelijkaardig als de pot in de andere richting gedraaid wordt. :thumbsup:

    De nodige steppers zijn besteld, en worden uiterlijk 29 september verwacht.
    In afwachting ga ik de code voor de servo's voor het heffen en dalen van de lopen omzetten op een NANO, ga ik de code voor de steppers x2 uitwerken en ook omzetten voor een andere NANO, en deze aanpassen voor de laatste 2 steppers voor het baksen van de torens en deze op een derde NANO zetten.

    Zijn de steppers dan nog niet binnen, dan is het modelbouwtijd, of kan ik experimenteren met Fusion 360 om de fysieke overbrenging van de steppers op de geschutstorens te realiseren, rekening houdend met de 3 draadjes van de servo in de toren, die zo veel mogelijk in het center van de draaibeweging naar beneden moeten komen, en met het positioneren en bevestigen van de eindswitches.
    Nog meer dan genoeg werk dus, vooral omdat ook Fusion 360 niet mijn specialiteit is. Dus ook hier zijn aanbevelingen welkom. :)
     
    Bruno van Hoek vindt dit leuk.
  16. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Ik ben dus even aan het kijken om 2 steppers op 1 Arduino aan te sluiten, en mijn oog valt op het volgende: de aansluitpinnen:
    8,9,10 en 11, waar wordt geparametreerd waar deze voor dienen? en kan ik dat aanpassen als ik bijvoorbeeld een stepper op 10, 11, 12 en 13 wil zetten om pinnen vrij te maken voor de 2e stepper met zijn eindswitches?
    Ik vermoed dat dit in Stepper.h zit, want het wordt niet in de overige code gedefinieerd.

    Is het dan wel mogelijk om 2 steppers op 1 Arduino te zetten?
     
  17. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Dat lijkt me wel, proberen maar....
    je moet dan natuurlijk wel dezelfde "kruising" van IN2 en IN3 op de stepper-driver print aanhouden als dat nu voor jou werkt.
    Bij mij nog steeds niets, ook niet na het verwisselen, maar mooi dat het bij jou werkt :thumbsup::thumbsup:
    Over en sluiten nu maar, vrijdag weer verder.
     
  18. Herby63

    Herby63

    Lid geworden:
    6 aug 2009
    Berichten:
    4.400
    Locatie:
    Brugge
    Na wat opzoekwerk op 'tinternet, veel onzin gelezen, en 1 nuttige opmerking, heb ik gewoon mijn stoute schoenen aangetrokken en onderstaande code gemaakt, en het werkt inderdaad.
    Code opgeladen.
    Eerst de stepper en de switches op pins 8 tot 13 aangesloten, en die reageert op pot 1 van de multipot module.
    Dan switches en stepper aangesloten op pins A0, A1, 3, 4, 5 en 6, en dan reageert de stepper op de 2e pot van de multipot module.
    :goal ik ga het nog leren :) met veel tijd en boterhammen :rofl:

    Code:
    volatile unsigned long timer; // all timer variables are unsigned long
    volatile int inpulse, seqnr = 20;
    volatile int Plist[16];
    int pulse0;
      int pulse1;
    
    #include <Stepper.h>
    const int stepsPerRevolution=2048;
    int motSpeed=1;
    const int motDir=1;
    const int buttonPinSB0=8;
    const int buttonPinBB0=9;
      const int buttonPinSB1=A0;
      const int buttonPinBB1=A1;
    bool buttonSB0Read;
    bool buttonBB0Read;
      bool buttonSB1Read;
      bool buttonBB1Read;
    const int dt=250;
    Stepper myStepper0(stepsPerRevolution, 10,12,11,13);
      Stepper myStepper1(stepsPerRevolution, 3,5,4,6);
    
    void setup() {
      // put your setup code here, to run once:
     attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
      pinMode(2, INPUT);
     
      Serial.begin(9600);
     
      myStepper0.setSpeed(motSpeed);
        myStepper1.setSpeed(motSpeed);
    
      pinMode(buttonPinSB0, INPUT_PULLUP);
      pinMode(buttonPinBB0, INPUT_PULLUP);
        pinMode(buttonPinSB0, INPUT_PULLUP);
        pinMode(buttonPinBB0, INPUT_PULLUP);
    }
    
    void loop() {
      buttonSB0Read=digitalRead(buttonPinSB0);
      buttonBB0Read=digitalRead(buttonPinBB0);
        buttonSB1Read=digitalRead(buttonPinSB1);
        buttonBB1Read=digitalRead(buttonPinBB1);
    
        cli(); // stop interrupt interference
        pulse0 = Plist[0]; // get latest pulse for stepper 0
          pulse1 = Plist[1]; // get latest pulse for stepper 0
        sei(); // release interrupt
      Serial.print (pulse0);
      Serial.print ("   ");
        Serial.println (pulse1);
       if (pulse0 <=1300 && buttonSB0Read==1){
          myStepper0.step(motDir*-1);
        }
        if (pulse0 >=1700 && buttonBB0Read==1){
          myStepper0.step(motDir*1);
    
    }
     if (pulse1 <=1300 && buttonSB1Read==1){
          myStepper1.step(motDir*-1);
        }
        if (pulse1 >=1700 && buttonBB1Read==1){
          myStepper1.step(motDir*1);
    
    }
    }
    void read_pwm(){
      if (PIND & 0b00000100) { // if pin 2 is high
        timer = micros(); // start timer
      }
      else { // else pin 2 is low
        inpulse = ((volatile int)micros() - timer); // read timer
        
        if (inpulse<950)  seqnr = -1; // reset seqnr for next incoming pulses to start with 0
        else {
          seqnr += 1;
          if (seqnr < 16) Plist[seqnr] = inpulse;
        }
      }
    }
     
  19. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Helemaal goed!!
    Ik zou persoonlijk voor een beter overzicht (naar mijn mening tenminste) het hele stuk in de loop eronder nog een keer met copy/paste geplaatst hebben, en dan daarin alle 0 in 1 veranderd hebben. met name de interrupt call (cli() - sei()) zou dan korter voor de verwerking van de betreffende puls plaats vinden.
    En een soortgelijke actie in de setup uiteraard (maar niet de interrupt attach regels natuurlijk)

    Een andere vereenvoudiging (maar wederom persoonlijke voorkeur): je kunt de variabelen button...read helemaal weglaten door deze in de twee if {} regels te wijzigen in digitalRead (buttonPin....) == 1, en je kunt zelfs ==1 weglaten omdat de vergelijking dat ook zonder ==1 als True beschouwd. het wordt dan bijvoorbeeld
    Code:
    if (pulse0 >=1700 && digitalRead(buttonPinBB0)){
     
  20. Bruno van Hoek

    Bruno van Hoek Vriend van modelbouwforum.nl PH-SAM Forum veteraan

    Lid geworden:
    23 aug 2002
    Berichten:
    11.182
    Locatie:
    Almere, MVA (ex-Daedalus Amsterdam)/ PH-SAM/F23D
    @ Herby63: Is er een reden dat je Nano's wilt gebruiken inplaats van de kleinere Pro-Mini?
    Programmeren > draadjes aansolderen > het geheel in krimpkous sealen en klaar....
     

Deel Deze Pagina