Författare Ämne: Arduino - Fördröjt frånslag  (läst 524 gånger)

Utloggad sintra

  • Stammis
  • ****
  • Antal inlägg: 1.289
Arduino - Fördröjt frånslag
« skrivet: tor 06 aug 2020, 19:40:45 »
En funktion som kan tyckas mycket enkel är ett "fördröjt frånslag" (Off-delay) av en utgång efter aktivering av en ingång.
Det är det väl också om man använder funktionen "delay" i loopen.
Problemet, som jag förstått det, är att man då stannar hela loopen i angiven tid. Detta vill jag inte ha.

Alltså, mitt behov är att man med en, två (eller flera) återfjädrande tryckknappar ska kunna styra varsin utgång och aktivera densamma. Utgången ska sedan förbli aktiv till dess tiden runnit ut för respektive utgång, tiden kan vara olika för olika utgångar.

Tanken är att man ska kunna "starta" olika "aktiviteter" på anläggningen med hjälp av utplacerade tryckknappar.
En knapp kanske "startar" en gubbe som svetsar på en bil i 10 sek, en annan knapp låter brandbilarnas blåljus blinka i 20 sek, en tredje knapp låter gruvspelet snurra i 15 sek osv. osv. så länge in- och utgångar räcker till förstås.

Alla "aktiviteter" ska alltså kunna fungera fritt utan att påverkas av varandra.

Någon som har lämplig kod att delge?
 

Inloggad lgrfbs

  • Stammis
  • ****
  • Antal inlägg: 1.396
  • Gävleborg
    • Mitt CV
SV: Arduino - Fördröjt frånslag
« Svar #1 skrivet: tor 06 aug 2020, 20:06:35 »
Jag skulle programmera med variabler och evig loop.

OBS detta är grymt förenklat och syntaxen är tagen rakt ur huvudet och passar nödvändigtvis inte mot ett verkligt programmeringsspråk.

Kodstycke: [Välj]
//Nollar alla variabler
EventA=0
EventB=0
EventC=0
EventD=0

OutPutA=Off
OutPutB=Off
OutPutC=Off
OutPutD=Off


10
// 10000 system ticks.
if buttonA=true then EventA=10000
if buttonB=true then EventB=10000
if buttonC=true then EventC=10000
if buttonD=true then EventD=10000

//Sätter utgången till "på" eller "av"
if EventA>0 then OutPutA=On else OutPutA=Off
if EventB>0 then OutPutB=On else OutPutA=Off
if EventC>0 then OutPutC=On else OutPutA=Off
if EventD>0 then OutPutD=On else OutPutA=Off

//Räknar ner -1 för varje system ticks ända tills noll är nått.
if EventA>0 then EventA=EventA-1
if EventB>0 then EventB=EventB-1
if EventC>0 then EventC=EventC-1
if EventD>0 then EventD=EventD-1
Goto 10

Man kan även använda interups och underprogram/funktioner för att nå liknade resultat, men det har jag inte koll på.
Diod=lyser inte, Lysdiod=lyser.  Jemtrallarna, Shapeways , Kör: R2 HO - DCC & XpressNET (LocoNet) - Rocrail - DR5000 - LokReg

Utloggad rcmodeler

  • Användare
  • ***
  • Antal inlägg: 145
SV: Arduino - Fördröjt frånslag
« Svar #2 skrivet: tor 06 aug 2020, 20:34:38 »
Om du startar Arduino IDE och klickar på "Fil - Exempel - 02.Digital - BlinkWithoutDelay" så har du en enkel princip.

Utloggad paj2

  • Veteran
  • *****
  • Antal inlägg: 5.118
    • http://www.mj-rallaren.se/index.htm
SV: Arduino - Fördröjt frånslag
« Svar #3 skrivet: tor 06 aug 2020, 20:37:37 »
Interrupts på det sätt som förekommer i realtids operativsystem där man vid interrupt går direkt till en subrutin går inte att  åstadkomma enkelt på samma sätt i Arduino. Vissa trix och då rätt komplicerat går att få till liknande.

Ett vanligt enkelt sätt för att kringgå att ett sekvensiellt program "stannar" vid en delay är att byta ut delay mot en funktion "millis"  som oberoende av programmet i övrigt har en tickande tidsfunktion. "Millis" kan då ses som ett "underprogram"  som håller igång en tidsfunktion utan att störas av andra delar av programmet.
Exempel......  Ett blinkande ljus vid en övergång med samtidig kontroll av bommar.

Ett "fördröjt frånslag" kan då styras med "millis" medan programmet i övrigt tuffar på.

Finns flera bra exempel på millisfunktion på Arduinos hemsida.
Som rcmodeler skriver är programmet "BlinkWithoutDelay" ett bra exempel


Bästa MJ-hälsningar
Per-Åke
Moduler 2RH0 /N-skala /Traincontroller /MGP /RTFM
Min hemsida
Min Youtube kanal

Utloggad kronans

  • Användare
  • ***
  • Antal inlägg: 237
SV: Arduino - Fördröjt frånslag
« Svar #4 skrivet: fre 07 aug 2020, 07:47:21 »
Inte provat detta projekt men det ser intressant ut.

https://github.com/Reactduino/Reactduino

/Christer

Utloggad sintra

  • Stammis
  • ****
  • Antal inlägg: 1.289
SV: Arduino - Fördröjt frånslag
« Svar #5 skrivet: sön 09 aug 2020, 14:19:03 »
Det där med "Blink without delay" har jag förstås redan tittat på.
"Millis" är säkerligen den lösning jag söker efter, men min värmeslagströtta hjärna orkar inte förstå hur jag ska få den att sluta blinka, bara tända en gång och sedan slockna.

Googlade runt lite och hittade sidan "Baldengineer", med många exempel.
bland annat ett med precis vad jag söker:

//Global Variables
const byte BUTTON=2; // our button pin
const byte LED=13; // LED (built-in on Uno)
 
unsigned long buttonPushedMillis; // when button was released
unsigned long ledTurnedOnAt; // when led was turned on
unsigned long turnOnDelay = 2500; // wait to turn on LED
unsigned long turnOffDelay = 5000; // turn off LED after this time
bool ledReady = false; // flag for when button is let go
bool ledState = false; // for LED is on or not.
 
void setup() {
 pinMode(BUTTON, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 digitalWrite(LED, LOW);
}
 
void loop() {
 // get the time at the start of this loop()
 unsigned long currentMillis = millis();
 
 // check the button
 if (digitalRead(BUTTON) == LOW) {
  // update the time when button was pushed
  buttonPushedMillis = currentMillis;
  ledReady = true;
 }
 
 // make sure this code isn't checked until after button has been let go
 if (ledReady) {
   //this is typical millis code here:
   if ((unsigned long)(currentMillis - buttonPushedMillis) >= turnOnDelay) {
     // okay, enough time has passed since the button was let go.
     digitalWrite(LED, HIGH);
     // setup our next "state"
     ledState = true;
     // save when the LED turned on
     ledTurnedOnAt = currentMillis;
     // wait for next button press
     ledReady = false;
   }
 }
 
 // see if we are watching for the time to turn off LED
 if (ledState) {
   // okay, led on, check for now long
   if ((unsigned long)(currentMillis - ledTurnedOnAt) >= turnOffDelay) {
     ledState = false;
     digitalWrite(LED, LOW);
   }
 }
}

Kruxet är bara att inget alls händer i min Arduino, med den koden.
Jag har testat med att "skjuta in" en enkel rad på olika ställen mitt i koden som bara tänder LED när jag aktiverar ingången, och det funkar.
Men någon fördröjning enligt exemplet får jag inte, det händer alltså ingenting.


Utloggad sintra

  • Stammis
  • ****
  • Antal inlägg: 1.289
SV: Arduino - Fördröjt frånslag
« Svar #6 skrivet: sön 09 aug 2020, 14:46:20 »
Så får jag väl svara mig själv nu då, har blivit lite svalare i hjärnbarken.
Jag tog bort den "PULLUP" som fanns i koden för ingången.
Nu funkar den koden.  :D


Utloggad Sven-E

  • Användare
  • ***
  • Antal inlägg: 225
SV: Arduino - Fördröjt frånslag
« Svar #7 skrivet: tor 20 aug 2020, 10:14:57 »
En funktion som kan tyckas mycket enkel är ett "fördröjt frånslag" (Off-delay) av en utgång efter aktivering av en ingång.
Det är det väl också om man använder funktionen "delay" i loopen.
Problemet, som jag förstått det, är att man då stannar hela loopen i angiven tid. Detta vill jag inte ha.

Alltså, mitt behov är att man med en, två (eller flera) återfjädrande tryckknappar ska kunna styra varsin utgång och aktivera densamma. Utgången ska sedan förbli aktiv till dess tiden runnit ut för respektive utgång, tiden kan vara olika för olika utgångar.

Tanken är att man ska kunna "starta" olika "aktiviteter" på anläggningen med hjälp av utplacerade tryckknappar.
En knapp kanske "startar" en gubbe som svetsar på en bil i 10 sek, en annan knapp låter brandbilarnas blåljus blinka i 20 sek, en tredje knapp låter gruvspelet snurra i 15 sek osv. osv. så länge in- och utgångar räcker till förstås.

Alla "aktiviteter" ska alltså kunna fungera fritt utan att påverkas av varandra.

Någon som har lämplig kod att delge?

Det finns en bra artikelserie på https://learn.adafruit.com/multi-tasking-the-arduino-part-1/overview som beskriver hur man går från ett program som använder delay() till att använda timer med millis() och sedan stoppa in det hela i en klass så man kan ha flera saker som snurrar samtidigt. Det hela förklaras pedagogiskt steg för steg.

Jag har själv använt den här metoden (som kallas for Cooperative Multitasking i datavärlden) för att kontrollera ett par signaler som slår om till rött när ett tåg passerar och sen visar varsamhet och kör efter en stund. Jag kunde också peta in kod för att slå signallamporna (led) på och av långsamt så de beter sej som gamla glödlampor.
Se https://github.com/SvenRosvall/SignalControl

  / Sven

Utloggad paj2

  • Veteran
  • *****
  • Antal inlägg: 5.118
    • http://www.mj-rallaren.se/index.htm
SV: Arduino - Fördröjt frånslag
« Svar #8 skrivet: tor 20 aug 2020, 11:01:37 »
Bra artikel om Arduino "multitasking"  :up:

Jag har använt "millis" flera tillämpningar och ändå vissa begränsningar
men dessa artiklar ger bra tips hur man kan gå vidare.
Bästa MJ-hälsningar
Per-Åke
Moduler 2RH0 /N-skala /Traincontroller /MGP /RTFM
Min hemsida
Min Youtube kanal