Variabele delay
27 berichten
• Pagina 1 van 3 • 1, 2, 3
Variabele delay
Beste forummers,
Ik heb acht ledjes in een ringopstelling. Via een schuifregister laat ik het lichtje "rondjes lopen. De richting en snelheid is afhankelijk van de stand van een potmeter. Voluit rechts draait het licht op maximale snelheid rechtsom. Draai ik de potmeter naar links, gaat het lichtje steeds langzamer rond. In het midden wisselt de draairichting. Verder naar links betekent sneller linksom draaien.
Het programmaatje draait prima, echter, de berekening van de draaisnelheid wordt in een delay verwerkt waardoor het programma bij langere delays niet snel op de potmeter reageert.
Is er een manier om de stand van de potmeter tussentijds af te lezen en de delay daarop aan te passen?
Mvg., Hans
p.s, Wellicht knullig geprogrammeerd?
Bijgevoegd de code:
Ik heb acht ledjes in een ringopstelling. Via een schuifregister laat ik het lichtje "rondjes lopen. De richting en snelheid is afhankelijk van de stand van een potmeter. Voluit rechts draait het licht op maximale snelheid rechtsom. Draai ik de potmeter naar links, gaat het lichtje steeds langzamer rond. In het midden wisselt de draairichting. Verder naar links betekent sneller linksom draaien.
Het programmaatje draait prima, echter, de berekening van de draaisnelheid wordt in een delay verwerkt waardoor het programma bij langere delays niet snel op de potmeter reageert.
Is er een manier om de stand van de potmeter tussentijds af te lezen en de delay daarop aan te passen?
Mvg., Hans
p.s, Wellicht knullig geprogrammeerd?
Bijgevoegd de code:
- Code: Alles selecteren
byte teller = 1 ; // algemeen te gebruiken teller
byte vlag ; // links of rechts draaien
int sensor = A0; // Init A0
int sensorValue = 0; // input potmeter
int vertraging ; // komt in de delay() te staan
int led =1 ; // bevat schuifwaarde
void setup() {
teller = 1;
while (teller != 9) { // Initialiseer poorten 1 tm 8 als output
pinMode(teller,OUTPUT);
teller ++;
} // einde van de while
}
void loop()
{
sensorValue = analogRead(sensor); // Inlezen potmeter
sensorValue = sensorValue -512; // schalen van de waarde
if (sensorValue <0){
sensorValue = abs (sensorValue) ; // keert teken om indien negatief.
vlag = 0 ; // set draaivlag links, moet alleen gecheckt worden :)
}
else { vlag = 1 ; } // anders zet draaivlag rechts
vertraging = 1026 - 2 * sensorValue ; // vertragingsloop is nu van 2mS tot 1S
if (vlag == 0) {
teller = 0;
while ( teller != 8){
digitalWrite (teller+1,bitRead (led,teller)); // Schrijft alle bits van led naar de uitgangen
teller ++ ; }
delay (vertraging); // berekende vertraging, hoe verder de potmeter naar de uiterste standen gaat, hoe sneller de leds lopen
led = led << 1; // schuif 1 stap naar links
bitWrite (led,0,bitRead (led,8)); // schuif bit 8 naar positie o
bitWrite (led,8,0); // reset bit 8
}
else {
teller = 0;
while ( teller != 8){
digitalWrite (teller+1,bitRead (led,teller)); // zie boven
teller ++ ; }
delay (vertraging);
bitWrite (led,8,bitRead (led,0)); led = led >> 1; // schuift 1 stap naar rechts
}
} // eind van de loop
Advertisement
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: Variabele delay
een timer en millis() gebruiken.
Voorbeeld:
cpp code
in de setup():
cpp code
in de loop()
cpp code
Zo kan delay vervallen. Wat je doet is kijken of je voorbij de vertragingstijd bent. Zodra dat het geval is shuif je een bit op. Is dat niet het geval dan leest hij direct weer de potmeter.
Voorbeeld:
cpp code
unsigned long timer = 0; // 32 bits timer
in de setup():
cpp code
timer = millis();
in de loop()
cpp code
if ((millis() - timer) > vertraging){
//
// schuif een stap naar rechts
//
.......
//
// zet de timer weer voor de volgende keer
//
timer = millis();
}
Zo kan delay vervallen. Wat je doet is kijken of je voorbij de vertragingstijd bent. Zodra dat het geval is shuif je een bit op. Is dat niet het geval dan leest hij direct weer de potmeter.
Re: Variabele delay
dat kan met een timer, maar dan moet je wel je programma behoorlijk omdenken.
zorg ervoor dat de loop altijd draait, ofwel nooit een delay of een afhankelijkheid in zetten.
maak van je loop een functie.
telkens als de tijd voorbij is (zie nico) dan spring naar je functie. uiteraard moet je dan wel de delays verwijderen uit je functie.
dus op regel 3 van nico komt iets in de trant van functie()
en onder de loop void functie() met daar je programma.
trouwens prima vraagstelling compleet met programma.
zorg ervoor dat de loop altijd draait, ofwel nooit een delay of een afhankelijkheid in zetten.
maak van je loop een functie.
telkens als de tijd voorbij is (zie nico) dan spring naar je functie. uiteraard moet je dan wel de delays verwijderen uit je functie.
dus op regel 3 van nico komt iets in de trant van functie()
en onder de loop void functie() met daar je programma.
trouwens prima vraagstelling compleet met programma.
paul deelen
shooter@home.nl
shooter@home.nl
Re: Variabele delay
Ik denk dat ik heb snap. Volgens mij gaat dat goed werken, waarvoor mijn dank.
Als ik het echter goed heb, kan er na 2^32 milliseconden een probleem ontstaan doordat de 32 bits overschreden gaat worden. Klopt dat? En zo ja, kan ik op de een of ander manier de millis() resetten?
Duurt denk ik een beetje lag om dat te testen......
Of praat ik wartaal??
Gr., Hans
Aha, laat maar, ik heb het al gezien. Ook millis() gebruikt een unsigned long. Dus bij een overflow gaat deze terug naar 0, en dus ook de timer.
Eerst denken en nakijken, dan pas vragen. Sorry!
Als ik het echter goed heb, kan er na 2^32 milliseconden een probleem ontstaan doordat de 32 bits overschreden gaat worden. Klopt dat? En zo ja, kan ik op de een of ander manier de millis() resetten?
Duurt denk ik een beetje lag om dat te testen......
Of praat ik wartaal??
Gr., Hans
Aha, laat maar, ik heb het al gezien. Ook millis() gebruikt een unsigned long. Dus bij een overflow gaat deze terug naar 0, en dus ook de timer.
Eerst denken en nakijken, dan pas vragen. Sorry!
Re: Variabele delay
Wat ik in die situatie 's doe; in de loop zet ik een vaste delay van 1mS en laat de loop een aantal malen (afhankelijk van de snelheid) een deel van de loop overslaan.
- Code: Alles selecteren
unsigned int param_vertraging = 0 // Hier komt de vertraging 's waarde in
unsigned int timer_vertraging = 0 // Vertraging 's Timer
void setup() {
param_vertraging = 500 // Startten met een vertraging van 500mS
}
void loop() {
delay(1);
timer_vertraging++;
if (timer_vertraging > param_vertraging) {
timer_vertraging = 0;
// Code wat uitgevoerd moet worden
// ...
}
}
- nicoverduin
- Berichten: 5043
- Geregistreerd: 13 Mei 2013, 20:57
- Woonplaats: Heemskerk
Re: Variabele delay
Tja het werkt, maar als je ooit een programma krijgt waarbij je alle pinnen van de Arduino nodig hebt of er moet direct gereageerd worden dan leer je deze manier gauw genoeg af.....
En zoals al eerder is aangeven, het is niet nodig. Daarnaast, als je echte timing nodig hebt wat nog een beetje betrouwbaar is dan gaat de afwijking groter worden naarmate je meer code hebt.... Immers die kosten ook tijd en tegelijkertijd pak je nog eens een milliseconde.
Het mooie van de aangegeven manier een heleboel (relatief) (on)afhankelijke delen code naast elkaar kan laten draaien (is natuurlijk niet zo maar...). Je schrijft gewoon een stukje code dat op enig moment iets moet doen. Je geeft het een timer en klaar. Dat stukje code wordt alleen actief als het nodig is.
Het kan nog anders maar dan ga je al heel erg richting een realtime OS en dat is een beetje veel van het goede voor de Arduino. Dit is een mooi compromis.
En zoals al eerder is aangeven, het is niet nodig. Daarnaast, als je echte timing nodig hebt wat nog een beetje betrouwbaar is dan gaat de afwijking groter worden naarmate je meer code hebt.... Immers die kosten ook tijd en tegelijkertijd pak je nog eens een milliseconde.
Het mooie van de aangegeven manier een heleboel (relatief) (on)afhankelijke delen code naast elkaar kan laten draaien (is natuurlijk niet zo maar...). Je schrijft gewoon een stukje code dat op enig moment iets moet doen. Je geeft het een timer en klaar. Dat stukje code wordt alleen actief als het nodig is.
Het kan nog anders maar dan ga je al heel erg richting een realtime OS en dat is een beetje veel van het goede voor de Arduino. Dit is een mooi compromis.
Re: Variabele delay
toch mcnes is het een heel goede vraag hoor.
zijn veel discussies over.
zijn veel discussies over.
paul deelen
shooter@home.nl
shooter@home.nl
Re: Variabele delay
Alleen de millis gaat naar een dag of 50 in overflow (0) dat kan ook weer, tot niet gewenste timing problemen lijden. Of je moet dit gaan ondervangen.
Trouwens, voor de millis methoden staat hier een mooi voorbeeld: http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Trouwens, voor de millis methoden staat hier een mooi voorbeeld: http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Re: Variabele delay
Met dank, het werkt fraai. Ik houd er niet van als er loze loops of dergelijke in zitten waarin niets gebeurt. Zonde van de (processor)tijd. Moest vroeger op alle manieren tijd winnen op de "trage" Z80 en 6502 processoren....
Kon nu het programma nog verder inkorten door het schuiven van het register in een if else loop te vangen, met daaroverheen de timerloop. Houd van lean programmeren.
Inderdaad gaat na 49 dagen een hik optreden omdat de millis() dan naar 0 gaat. Voor nu nog geen probleem want na vanavond gaat hij weer uit
Ik ben weer geholpen. Kan weer verder knoeien....
Thx!
Mvg., Hans
p.s., met de timer = millis() in de setup loop ging iets niet goed. De timer bleef op 0. Ik heb nu een startsignaal gemaakt aan het begin van de void loop() en dan doet hij het wel.
p.s., dit is het nu geworden. Wat veel commentaar, maar dat vind ik zelf erg makkelijk.
Kon nu het programma nog verder inkorten door het schuiven van het register in een if else loop te vangen, met daaroverheen de timerloop. Houd van lean programmeren.
Inderdaad gaat na 49 dagen een hik optreden omdat de millis() dan naar 0 gaat. Voor nu nog geen probleem want na vanavond gaat hij weer uit
Ik ben weer geholpen. Kan weer verder knoeien....
Thx!
Mvg., Hans
p.s., met de timer = millis() in de setup loop ging iets niet goed. De timer bleef op 0. Ik heb nu een startsignaal gemaakt aan het begin van de void loop() en dan doet hij het wel.
p.s., dit is het nu geworden. Wat veel commentaar, maar dat vind ik zelf erg makkelijk.
- Code: Alles selecteren
// byte strt = 1 ; // moet een startwaarde creeeren voor in de loop --> eruit gegooid, gaat toch ook zonder
byte teller = 1 ; // algemeen te gebruiken teller
byte vlag ; // links of rechts draaien
int sensor = A0; // Init A0
int sensorValue = 0; // input potmeter
int vertraging ; // komt in de delay() te staan
int led =1 ; // bevat schuifwaarde
unsigned long timer; // waarde voor de millis()
void setup() {
teller = 6;
while (teller != 14) { // Initialiseer poorten 1 tm 8 als output
pinMode(teller,OUTPUT);
teller ++;
} // einde van de while
}
void loop()
{
// if (strt == 1) { timer = millis();} // eruit gegooid, gaat toch ook zonder
// strt = 2; // Verwijderd, werkt toch?
sensorValue = analogRead(sensor); // Inlezen potmeter
sensorValue = sensorValue -512; // schalen van de waarde
if (sensorValue <0){
sensorValue = abs (sensorValue) ; // keert teken om indien negatief.
vlag = 0 ; // set draaivlag links, moet alleen gecheckt worden :)
}
else { vlag = 1 ; } // anders zet draaivlag rechts
vertraging = 1026 - 2 * sensorValue ; // vertragingsloop is nu van 2mS tot 1S
// Volgende deel is om de bits naar de pins te sturen. Hier van pin 6 tot en met 13
teller = 6;
while ( teller != 14){
digitalWrite (teller,bitRead (led,teller-6)); // Schrijft alle bits van led naar de uitgangen
teller ++ ; }
// Hier start het testen op de vertragingstijd met behulp van millis()
if (millis()- timer > vertraging) { // vertragingsloop met behulp van de timer
// Hier schuift het register, naar links als de vlag nul is, naar rechts als de vlag 1 is. Alleen als de wachttijd overschreven wordt.
if (vlag == 0) {
led = led << 1; // schuif 1 stap naar links
bitWrite (led,0,bitRead (led,8)); // schuif bit 8 naar positie o
bitWrite (led,8,0); // reset bit 8
}
else {
bitWrite (led,8,bitRead (led,0)); led = led >> 1; // schuift 1 stap naar rechts
}
timer = millis(); // reset de timer
} // einde van de vertragingsloop
} // eind van de loop
Laatst gewijzigd door McNes op 24 Dec 2014, 00:34, in totaal 2 keer gewijzigd.
27 berichten
• Pagina 1 van 3 • 1, 2, 3
Wie is er online?
Gebruikers in dit forum: apkulefo, arahokol, olonoowkej, patmivaolot en 22 gasten