Go Down

Topic: Verlichting voor een skelter (Read 285 times) previous topic - next topic

MAS3

Ik kan de meeste opcodes die daar staan wel lezen.
Alleen BIT was mij onbekend.
Die heb ik eens opgepikt toen ik wat zat te rommelen met de commodore 64 (die ik nog steeds heb).
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

nicoverduin

Mijn KIM staat ook nog op zolder. Moet hem alleen nog een keer in plexiglas zetten :)
BIT is in feite vergelijkbaar met de AND functie. En het is inderdaad de zelfde processor 6502.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl

Rene4312

Dank iedereen voor de reacties.

Ik blijf echter toch nog een vraag houden over het ontdenderen. Punt 1 is natuurlijk: Wat is denderen.
In mijn opinie is dat als je een druktoets of een schakelaar indrukt dat de contacten elkaar verschillende keren kunnen raken voordat ze in een stabiele toestand staan.

Je moet dus wachten (liefst zonder delay, dat klinkt raar) voordat je actie onderneemt omdat die actie anders meerdere keren kan plaatsvinden, de schakelaar moet weer stabiel zijn.

Maar als je ingang 1 keer hoog wordt, dan weet je toch zeker dat de schakelaar ingedrukt is geweest?
En dan nu mijn vraag: Waarom zou je hem nog een keer controleren?

Op dit moment ontgaat de logica hiervan mij een beetje. Als ik dit in mijn Uno stop:


Code: [Select]

int done = 0;

void setup() {
  pinMode(13, OUTPUT);     
  pinMode(2, INPUT_PULLUP);     
}

void loop(){
   if (digitalRead(2) == LOW) {
     delay(25);
     if (done == 0) {
       digitalWrite(13, !digitalRead(13));
       done =1;
     }
   }
   else {
      done = 0;
   }
}


En ik stop een stukje stroomdraad in de ground en een stukje op pin 2 en ik raak de draden aan dan werkt dit prima. Eén keer aanraken en de LED gaat aan, nog een keer en de LED gaat uit. Verlaag je de delay naar 0 dan blijft het een gok hoe de led naar één keer (dender dender) reageert. Een delay van 50 geeft een zeer stabiel beeld met de draadjes en een schakelaar zal beter contact maken dan ik met 2 draadjes.

Dus: Waarom voor de tweede keer je button inlezen en vergelijken met de eerste keer?

Alvast bedankt voor de reacties!

René.

cartoonist

Er zijn verschillende typen drukknop schakelaars:
(momentary) moment schakelaar indrukken is de ene toestand (meestal aan ) en niet ingedrukt is de andere toestand (meestal open)
(toggle) een keer indrukken de schakelaar is gesloten, nog een keer indrukken en de schakelaar is geopend.
(impuls) een speciaal type wat een impuls (van min-of-meer gedefinieerde lengte) geeft bij indrukken.

Hoe je in de software de schakelaar gaat uitlezen hangt dus sterk af van het type schakelaar/drukknop.

Zoals ik uit je verhaal begrijp gebruik je een simpele type moment schakelaar.
Zoals MAS3 enige discussies terug ook al eens haarfijntjes opmerkte is het bij dit type schakelaar haast onmogelijk om korter in te drukken dan enige tienden van een seconde. Dus voor het weet denkt je programma dat je de toets twee keer hebt ingedrukt.
Je moet dus eigenlijk een routine hebben die de toets(en) steeds leest en pas als de/een toets weer is losgelaten de daaraan gekoppelde opdracht uitvoert. In deze routine moet een debounce zitten die de kortstondige willekeurige veranderingen in de eerste 25 of 50 millis negeert.
You do not need a new P.C., you need a new O.S.  Linux is free, safe, fast and reliable.

Rene4312

Dat snap ik, maar waarom wordt de toets na de wachtcyclus nog een keer ingelezen?

En naar mijn idee moet je programma niet pas reageren als de drukknop weer losgelaten wordt, maar als het programma zeker weet dat het denderen voorbij is.

Ik zal wel een denkfout maken maar ik heb hem nog niet ontdekt.

René.

cartoonist

Dat maakt  in principe  geen verschil denk ik.
Je verplaatst alleen de opdracht om uit te voeren naar voren. Je zult toch moeten wachten met de volgende opdracht uit te voeren als je zeker weet dat de toets enige tijd is losgelaten en daarna weer opnieuw ingedrukt.
Dus je moet de drukknoppen steeds maar uit blijven lezen om bij te houden wat er gebeurt.
You do not need a new P.C., you need a new O.S.  Linux is free, safe, fast and reliable.

Rene4312

En zo bedoel ik het ook niet. Wat ik bedoel is:

Wat voor nut heeft het rood omrande gedeelte in de flowchart van Nico (zie de bijlage). Je ziet dit overal op de site terugkomen bij het ontdendert inlezen van schakelaars, maar mij ontgaat er het nut (nog) van.

René

cartoonist

Wat heeft het voor zin om te discussieren over wat de beste manier is om vooruit te komen als het er om gaat om van A naar B te komen. Hetzelfde geldt voor ontdenderen.

Een heel andere manier van ontdenderen is om schakelaars heel snel uit te lezen en als ze aan staan een teller bij te houden en die met '1' te verhogen , als de schakelaar dendert en weer even open is dat trek je  '1' af van de som ( die niet kleiner dan 0 kan worden). Als je een gedefinieerd aantal malen de teller verhoogt hebt tot b.v. 10 of voor mijn part 100, dan pas kent het programma de waarde 'AAN' toe aan de schakelaar. Bij het uitzetten trek je dan iedere keer '1' af van het totaal totdat je de waarde 0 bereikt hebt en aan het programma doorgeeft dat de schakelaar weer 'UIT' is.

Wat maakt het uit hoe je ontdendert, het gaat om het resultaat.

Nico doet het op zijn manier, ieder vogeltje zingt zoals het gebekt is.
You do not need a new P.C., you need a new O.S.  Linux is free, safe, fast and reliable.

MAS3

#23
Dec 13, 2014, 01:10 am Last Edit: Dec 13, 2014, 01:13 am by MAS3
Dat wachten op weer loslaten is hier inderdaad niet van toepassing omdat je moet knipperen zolang de toets werd ingedrukt, en ermee moet stoppen als ie niet langer is ingedrukt.
Er zijn wel toepassingen waar je wel pas reageert wanneer de toets is losgelaten.
Die test die je hebt gedaan, met dat draadje, is een voorbeeld daarvan (eerste keer aan, tweede keer uit, dan moet je sowieso registreren dat het contact een keer verbroken is geweest).

Dender is inderdaad meerdere malen een contact zien door een niet stabiel of slijtend contact (mijn muis hier begint na 13 jaar te slijten...), terwijl er echt maar 1 keer een bediening bedoeld was.

Overigens doet deze ontdendering ook nog mee tegen stoorpulsen die eventueel gezien zouden kunnen worden als een bediening van de schakelaar.

Je moet de schakelaar dus net zo vaak lezen totdat je een stabiele toestand bereikt hebt.
Als je 'm eerst ziet, en snel daarna niet meer, dan wijs je die eerste keer dus af.
Even later kijk je dan weer naar de schakelaar en als je bij die eerste keer wel was begonnen met het indrukken van de schakelaar, dan heb je 'm bij de derde keer kijken waarschijnlijk al wel stabiel ingedrukt.
Dat verifieer je dan bij de vierde keer kijken, omdat je dan per keer maar 2 keer hoeft te controleren en minder moet onthouden.

1 keer een contact zien wil helemaal niet zeggen dat de schakelaar werd ingedrukt, das nou juist de essentie van ontdenderen.
Wanneer je zegt dat je bij een test met vertraging iets wel goed aan de gang krijgt, maar zonder vertraging een hoop gedoe, dan maak je inderdaad een denkfout.
Want de vertraging (delay() ) zorgt er voor dat je een keer een contact (of stoorplus...) ziet.
Daarna kijk je gewoon een hele tijd (wel 0.025 seconden, maar das een zee van tijd voor je controller) niet of je 'm ziet, en dan kun je dus ook niet op dat gefriemel met het draadje reageren.

Als je dus toevallig een keer iets voorbij ziet komen op die ingang, dan wil dat lang niet altijd zeggen dat er op een knop gedrukt werd.
Daarom kijk je dan beter nog een keer, het is net als kijken in de spiegel van de auto (hoewel het me wel duidelijk is dat daar ook lang niet iedereen 2 keer kijkt, maar das een andere discussie).
Als ie twee keer achter elkaar ingedrukt was, dan zal dat vast wel kloppen.

Je gaf ook aan dat je het raar vond klinken dat je kunt wachten zonder niets te doen.
Het is niet zo heel vreemd dat je dat verward, zeker als je een delay() functie ter beschikking hebt.

Daarom zal ik een beetje proberen uit te leggen wat je ook kunt doen:
Je Arduino doet heel vaak een rondje door het programma, een simpele sketch word vele duizenden malen per seconden herhaald.
Wanneer je een globale variabele aanmaakt, dan word die overal in de sketch (na aanmaken van die variabele) beschikbaar, en de inhoud word niet bij elk rondje gereset.
Je kunt dan een keer kijken of je de knop ziet, registreren dat dat zo was, en vervolgens een paar rondjes later vaststellen dat de schakelaar gestabiliseerd is.
Dan moet je dus het aantal rondjes tellen waarin je hebt gezien dat de schakelaar gedrukt was.
Op deze manier maak je ook een ontdendering, maar je programma word verder normaal doorlopen.
Zo kun je meerdere dingen quasi gelijktijdig afhandelen, ook als je op een stabiliserend ingangssignaal zit te wachten.
Deze werkwijze is dus zonder gebruik te maken van de systeemklok (dat gedoe met millis() en previousState enzo), en daarmee bedien ik je hopelijk in jouw vraag of het niet iets simpeler kan.

Maar dan moet je een dergelijke aanpak wel consequent toepassen.
Dus ook bij het knipperen van de LEDs moet je dan geen delay() meer gebruiken, anders doe je dat werk voor niets.

Zoals Nico al haarfijn aangaf, is het helemaal niet altijd nodig om deze technieken toe te passen, en heeft iedereen bij zijn eerste sketches de delay() functie gebruikt.
En als jij die delay functie nodig hebt om de schakelaar goed te laten werken, is dat prima.
Alleen moet je het dan geen ontdenderen noemen, want dat is dan niet wat je doet.
En het verkeerde gebruik van die term kan je in een later project opbreken.


Alweer te laat, morgen weer werken.
Dus nu duik ik weer gauw het bed in.

[edit]
Wat cartoonist net zei, doe je dan dus in mijn verhaal hier boven.
Alleen ben ik van mening dat je de teller op nul moet zetten als er ff een jniet ingedrukte schakelaar gezien werd.
Anders kun je bij een heel (wel extreem) slechte schakelaar toch je gewenste eindwaarde halen.
[/edit]
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

nicoverduin

En zo bedoel ik het ook niet. Wat ik bedoel is:

Wat voor nut heeft het rood omrande gedeelte in de flowchart van Nico (zie de bijlage). Je ziet dit overal op de site terugkomen bij het ontdendert inlezen van schakelaars, maar mij ontgaat er het nut (nog) van.

René
Hoi Rene,
Er zit wel enig verschil in jouw oplossing en de mijne, Ligt ook een beetje waar je het voor nodig hebt. In mijn oplossing wil ik net als jij een stabiele situatie van de druk knop. In jouw oplossing (zoals deze nu is) moet ik de knop losgelaten hebben voordat hij weer actief kan worden. Voor een repeat mogelijkheid moeten er weer software aanpassingen komen.
Verder is er niets mis met jouw keuze. Zo zie je maar hoe je beïnvloed wordt door het verleden :smiley-mr-green:
Verder (en ook dat is persoonlijk) probeer ik voor mezelf de discipline aan te houden om gelaagd te ontwikkelen (Liever een functie meer ook al is dat duurder). Dus fysieke laag een applicatie laag. Geen MVC (Model-View-Controller). Dat gaat me bij de Arduino ff te ver.
Bij jou zou ik dus een losse lees routine en een losse schrijf routine maken. Maar dat zijn keuzes.
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl

cartoonist

Over flowcharts:

Ze kunnen  van dienst zijn voor uitgebreide software projecten waar meerdere programmeurs aan werken.

Voor mij betekenen flowcharts iets uit een ver verleden, zo rond 1980. Tijdens mijn studie programmeerde ik o.a. in assembler en Algol. Een programma schrijven betekende eerst met pen, papier en flowchart je programma maken. Daarna iedere regel van max 80 karakters op een aparte ponskaart intypen en als dit klaar was werd de stapel ponskaarten s'nachts in een batch per modem naar het Rekencentrum Delft gestuurd waarna je een dag later je output uit de printer in handen kreeg. Had je ergens een fout, al was het maar een punt of komma verkeerd staan dan kon je pas de volgende avond een nieuwe poging wagen. Op die manier kon het wel een week of langer duren voor je een relatief simpele opdracht voor elkaar had.

Om met een arduino in handen terug te vallen op flowcharts, voor een simpele project als dit, een skelterprogrammaatje met 4 drukknoppen ofzo, komt op mij over als met een kanon op een mug schieten.

Ik programmeer wat ik in mijn hoofd heb en kom dan met een oplossong b.v. zoals deze:

Code: [Select]

void loop(){
  if (digitalRead(pinA)==0) {                                // als drukknop A ingedrukt
       if (somA < maxSom) somA = (somA + 1);   // tel 1 op totdat som == max
       if (somA == maxSom) routineA();                // als max bereikt ga naar routine voor knopA
      }
  else {                                                             // als drukknop A niet ingedrukt
       if (somA > 0)      somA = (somA - 1);          // trek 1 af totdat som == 0
       if (somA ==0) routineA();                            // als 0 dan eventueel naar routine voor aktie
      }
   
  if (digitalRead(pinB)==0) {                                // als drukknop B ingedrukt
       if (somB < maxSom) somB = (somB + 1);   // tel 1 op totdat som == max
       if (somB == maxSom) routineB();                //
      }
  else {                                                             // als drukknop B niet ingedrukt
       if (somB > 0)      somB = (somB - 1);          // trek 1 af totdat som == 0
       if (somB ==0) routineB();                            //
      }
     
  if (digitalRead(pinC)==0) {                                // als drukknop C ingedrukt
       if (somC < maxSom) somC = (somC + 1);   // tel 1 op totdat som == max
       if (somC == maxSom) routineC();                //
      }
  else {                                                             // als drukknop C niet ingedrukt
       if (somC > 0)      somC = (somC - 1);          // trek 1 af totdat som == 0
       if (somC ==0) routineC();                            //
      }
     
  if (digitalRead(pinD)==0) {                                // als drukknop D ingedrukt
       if (somD < maxSom) somD = (somD + 1);   // tel 1 op totdat som == max
       if (somD == maxSom) routineD();                //
      }
  else {                                                             // als drukknop D niet ingedrukt
       if (somD > 0)     somD = (somD - 1);           // trek 1 af totdat som == 0
       if (somD ==0) routineD();                            //
      }
}

Deze loop wordt ca. 25000 keer per seconde doorlopen dus als maxSom 1000 betekent dat een debouncetijd van ca. 25 millis. Alle verdere akties worden in de routines voor de verschillende drukknoppen afgehandeld. (zonder gebruik van delay().

Dit is mijn idee om met dit programma te beginnen, flowcharts gebruik ik daar niet bij.
You do not need a new P.C., you need a new O.S.  Linux is free, safe, fast and reliable.

nicoverduin

Toch jammer dat je de essentie van het verhaal vergeten bent...... Eerst denken en dan doen... Want anders moest je weer een dag wachten.... Nu gaat men eerst doen en dan gokken en dan vragen. Dat jij na 35 jaar inmiddels weet hoe het moet betekent dat niet voor iedereen.......
Met vriendelijke groet / kindest regards
Nico Verduin
www.verelec.nl

Jantje

Toch jammer dat je de essentie van het verhaal vergeten bent...... Eerst denken en dan doen... Want anders moest je weer een dag wachten.... Nu gaat men eerst doen en dan gokken en dan vragen. Dat jij na 35 jaar inmiddels weet hoe het moet betekent dat niet voor iedereen.......
Dat dacht ik nu ook :-)
Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Go Up