Hoe kan ik een geschutstoren 290 graden laten draaien

Wat voor steppers gebruik je?
Je geeft me lekker wat huiswerk :)
Ik dacht dat je prefereerde om het zelf te kunnen.......

ik hoor het graag als je een andere mening toegedaan bent en een stepper zo veel stappen kan doen draaien in functie van de potuitslag.

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:
Ik dacht dat je prefereerde om het zelf te kunnen....
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.

Wat voor steppers gebruik je?
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.
 
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:
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;
    }
  }
}
 
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.
 
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
 
alle variabelen die specifiek zijn voor een stepper krijgen een 0, waaronder ook dus mystepper0
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.
 
Mag ik die 0 vervangen door een naam? Bij de Bismarck hadden de 4 geschutstorens een naam: Anton, Bruno, Caesar en Dora.
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.
 
Dit gaat zo echt niet werken, ...

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;
    }
  }
}
 
Omdat ik steeds de foutcode "pulse is not declared in this scope" krijg heb ik bovenaan "int pulse;" toegevoegd, wat waarschijnlijk niet nodig is,
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.
 
In jouw setup ontbreekt trouwens wel de interrupt attach:
Code:
  attachInterrupt(0, read_pwm, CHANGE); // Pin 2 = interrupt 0
  pinMode(2, INPUT);
 
In jouw setup ontbreekt trouwens wel de interrupt attach:
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. :)
 
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?
 
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.
 
Dat lijkt me wel, proberen maar....
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;
    }
  }
}
 
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)){
 
@ 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....
 
Back
Top