Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature may not be available in some browsers.
Inderdaad, hoe soepeler hoe sneller, of hoe sneller hoe soepelerLijkt allemaal soepel te verlopen.
toch liever meer, ik denk dat 24 seconden wel een minimum is, maar zal de beweging niet weer schokkerig worden? Ik test het graag uitis 12 seconden ok
Dat is ook de bedoeling. Vermits de reisweg minder groot is, is die ook in tijd veel korter, dus dat tempo mag met de andere servo's mee omlaag. (theoretische snelheid: elevation rate 6°/s over een boog van -5,5° tot +30°, van de lopen hé, niet van de servo, want door de ospstelling geeft de huidige travel van +-90° de gewenste elevatie van de lopen) De zwarte servo mag dus gerust een 6-tal seconden doen over die 90*maar dat geldt dan voor alle servo's, dus ook de zwarte..
volatile unsigned long timer; // all timer variables are unsigned long
volatile int inpulse = 1500, seqnr = 20;
volatile byte sync = 0;
int mpcount, pulse;
int Xtarget [8], Xpulse[8];
const int slowstep = 1;
const int Xtargetlow [] = {83, 83, 83, 83, 205, 205, 205, 205};
const int Xtargethigh [] = {467, 467, 467, 467, 410, 410, 410, 410};
bool start = false, RxchWas = false, toggle = true;
#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
for (uint8_t i=0; i<8; i++) {
Xtarget [i] = 308; // equivalent of 1500 micros
Xpulse [i] = 308;
pwm.setPWM(i, 0, Xpulse [i]);
}
delay(10);
}
void loop() {
while (sync == 0); // ISR sets sync to true when reading Rx pulse is complete, loop starts.
sync = 0; // stops loop after one run.
delay (6); // do an atomic copy, delayed to midframe to reduce jitter
cli();
pulse = inpulse;
mpcount = seqnr;
sei();
Serial.print ("mpcount = "); Serial.print (mpcount); Serial.print (" pulse = "); Serial.println (pulse);
// read next 8 incoming pulses, triggered by a syncpulse, map to extended range and save in array Xtarget []
if (mpcount >= 0 && mpcount < 8 && pulse >=1000) {
Xtarget [mpcount] = map (pulse, 1030, 1980, Xtargetlow [mpcount], Xtargethigh [mpcount]); // extending pulse to Xtarget
Serial.print ("Xpulse["); Serial.print (mpcount); Serial.print ("] = "); Serial.print (Xpulse[mpcount]);
Serial.print (" Xtarget["); Serial.print (mpcount); Serial.print ("] = "); Serial.println (Xtarget[mpcount]);
}
// update all servo outputs with or without changed targets, maximum step is slowstep setting
toggle = !toggle;
if (toggle) {
for (uint8_t j=0; j<8; j++) {
if ((Xtarget [j] - Xpulse [j]) >= slowstep) Xpulse [j] += slowstep;
else if ((Xtarget [j] - Xpulse [j]) <= -slowstep) Xpulse [j] -= slowstep;
else Xpulse [j] = Xtarget [j];
pwm.setPWM(j, 0, Xpulse [j]); // LOW>HIGH at 0, HIGH>LOW at pulselen
}
}
}
void read_pwm(){
if (RxchWas == 0) { // if pin 2 was false previously
timer = micros(); // start timer
RxchWas = 1;
}
else if (RxchWas == 1) { // if pin 2 was already true, read timer
inpulse = ((volatile int)micros() - timer);
RxchWas = 0;
sync = 1; // release loop stop
seqnr += 1;
if (inpulse<950) seqnr = -1; // reset seqnr for next incoming pulses to start with 0
}
}
na 2m40s laad ik de code zonder serials op, dus van 0 tot 2m40 is met de serials aktief, daarna zijn de serials disabledIk hoop dat dit versie met de serials is, anders zijn we weer een stap terug......
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]);
}
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 (1); // change to decrease servo speed.
}
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;
}
}
}
Hallo Max,Kun je die versie eens uitproberen? ik weet niet wat de snelheid zal zijn, maar die is nu met een simpele delay() te wijzigen.
mpcount = 0 pulse = 1036
mpcount = 1 pulse = 1132
mpcount = 2 pulse = 1256
mpcount = 3 pulse = 1360
mpcount = 4 pulse = 1460
mpcount = 5 pulse = 1520
mpcount = 6 pulse = 1664
mpcount = 7 pulse = 1792
mpcount = 0 pulse = 1036
mpcount = 1 pulse = 1132
mpcount = 2 pulse = 1256
mpcount = 3 pulse = 1356
mpcount = 4 pulse = 1460
mpcount = 5 pulse = 1524
mpcount = 6 pulse = 1660
mpcount = 7 pulse = 1800
mpcount = 0 pulse = 1040
mpcount = 1 pulse = 1132
mpcount = 2 pulse = 1256
mpcount = 3 pulse = 1360
mpcount = 4 pulse = 1468
mpcount = 5 pulse = 1520
mpcount = 6 pulse = 1656
mpcount = 7 pulse = 1792
mpcount = 0 pulse = 1040
mpcount = 1 pulse = 1132
mpcount = 2 pulse = 1252
mpcount = 3 pulse = 1364
mpcount = 4 pulse = 1460
mpcount = 5 pulse = 1520
mpcount = 6 pulse = 1664
mpcount = 7 pulse = 1792
mpcount = 0 pulse = 1040
mpcount = 1 pulse = 1140
mpcount = 2 pulse = 1248
mpcount = 3 pulse = 1360
mpcount = 4 pulse = 1460
mpcount = 5 pulse = 1524
mpcount = 6 pulse = 1660
mpcount = 7 pulse = 1788
Dat bevestigd een beetje mijn vermoeden dat de servo's "opstart" problemen krijgen als de stap in de pulswaarde te klein is. Bij een snellere ophoging van de polswaarden loopt de servo qua snelheid achter de feiten aan, de beweging blijft zonder schokken. Vergelijk het met een file in het verkeer, als het te druk wordt krijg je een "stop-en-go", men wacht iets te lang met optrekken na een stilstand waardoor de file uitrekt als een elastiek, maar daarna moet men al weer remmen en stoppen omdat de auto's te dicht op elkaar lopen. Maar vanaf een bepaalde snelheid loopt alles weer soepel.Bij een hogere delay wordt de traveltijd lange maar ook de schokkende beweging neemt toe.
Dat vind ik niet echt een bezwaar.Als je niet wilt dat jouw geschutstorens bij het in bedrijf stellen altijd eerst de zwaai naar een eindpunt moeten maken voordat ze naar een middenpositie kunnen draaien, zul je daar iets voor moeten verzinnen.
Uiteraard.integratie van de uitgelezen puls, waarvoor ik hoop op jou expertise beroep te kunnen doen.
Go for it!Zo kan ik zien of het bekijken van de vele tutorials mij enigszins inzicht hebben verschaft.![]()
Steppermotor op gepaste snelheid laten draaien gelukt ( 1 omwenteling per minuut = 60 seconden over 360°, of 48 seconden voor 290°).Go for it!
#include <Stepper.h>
int stepsPerRevolution=2048;
int motSpeed=1;
int myPotPin=A2;
int readVal;
int motDir=1;
int buttonPinSB=6;
int buttonPinBB=7;
int buttonSBRead;
int buttonBBRead;
int dt=250;
Stepper myStepper(stepsPerRevolution, 8,10,9,11);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myStepper.setSpeed(motSpeed);
pinMode(buttonPinSB, INPUT);
pinMode(buttonPinBB, INPUT);
}
void loop() {
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);
}
}
Ga je hier in eerste instantie zelf mee aan de slag?Nu nog dit integreren in de code ontwikkeld door @max z ,
Dank voor de constructieve opmerkingen, ik zal deze verwerken, maar de laatste opmerking begrijp ik niet goed, bedoel je dat ik dit moet er van maken?Ga je hier in eerste instantie zelf mee aan de slag?
Inderdaad, ik ga maar afzien van een variabele snelheid in functie van de verdraaiing van de pot.dus de pot wordt gebruikt als een 3-standen schakelaar?
Ik ga eens kijken, maar ik vrees toch een duwtje in de rug te kunnen gebruiken.Ga je hier in eerste instantie zelf mee aan de slag?
Correct.bedoel je dat ik dit moet er van maken?
pinMode(buttonPinSB, INPUT_PULLUP);
pinMode(buttonPinBB, INPUT_PULLUP);
Het gaat niet om snelheid, maar juist positie. In je huidige code moet zelf op het juiste moment stoppen door de pot naar neutraal te draaien, maar in de vorige code (van mij) bepaalde de pot waar de "target", dus de uiteindelijke draaihoek, was waar de draai moest stoppen.k ga maar afzien van een variabele snelheid in functie van de verdraaiing van de pot.
De void read_pwm() {...} kan blijven zoals die is, de diverse pulsen van de binnenkomende kanalen worden opgeslagen/ververst in de array Plist[ ].Waarschijnlijk volstaat het om ergens de waarde tussen [ en ] te vervangen door het gekozen kanaal,
cli(); // stop interrupt interference
pulse = Plist[0]; // get latest pulse for stepper 0
sei(); // release interrupt
if (pulse <=1300 && buttonSBRead0==1){
myStepper0.step(motDir*-1);
}
if (pulse >=1700 && buttonBBRead0==1){
myStepper0.step(motDir*1);
}
Zit daar in niet net het verschil tussen een servo en een stepper? Een servo weet in welke positie hij staat, en kan je dus een opdracht geven naar een bepaalde positie te gaan volgens de uitgelezen potwaarde. Een stepper voert het commando steeds uit vanaf de positie waar hij staat, en kan alleen het aantal stappen tellen dat hij moet doen, of in mijn geval aanzetten als hij moet, in de opgegeven richting, en stoppen als de voorwaarde niet meer voldaan is.Het gaat niet om snelheid, maar juist positie. In je huidige code moet zelf op het juiste moment stoppen door de pot naar neutraal te draaien, maar in de vorige code (van mij) bepaalde de pot waar de "target", dus de uiteindelijke draaihoek, was waar de draai moest stoppen.
Je geeft me lekker wat huiswerkDe void read_pwm() {...} kan blijven zoals die is, de diverse pulsen van de binnenkomende kanalen worden opgeslagen/ververst in de array Plist[ ].
Vervolgens pluk je de puls voor de betreffend servo er uit: ...
Die snelheidstest ga ik moeten uitstellen, ik heb momenteel maar 1 stepper. Ik wachtte om er bij te kopen, want ik heb intussen al een ganse doos componenten, die achteraf niet bruikbaar bleken te zijn. Indien de servo's voldoening hadden geschonken hadden deze mijn voorkeur genoten. Nu blijkt dat super traag en vloeiend bewegen moeilijk te combineren valt, en de test met de stepper positief was, is het moment aangebroken om de creditcard maar weer boven te halen.Als je meer dan 1 stepper met één arduino wilt besturen moet je dit allemaal herhalen voor de volgende stepper (niet de read_pwm routine, die heb je maar 1x nodig) Je moet alleen de steppers en de bijbehorende schakelaar-namen verschillende namen geven, zoals ik laat zien voor stepper 0.