antidender op Arduinopoort?

Hallo mensen.

Ik heb een morsesleutel aan een Arduino gehangen die per aanslag kijkt hoelang deze is aangeslagen.
Maar omdat zo'n sleutel natuurlijk geen omslagmoment heeft, dendert hij behoorlijk na.
Als ik nu het aantal milliseconden wil tellen dat hij aangeslagen is, maar hij ziet dat als 2x 50ms bv, ipv 1x 100, gaat er wat fout.

Hoe kan ik de poort zo antidenderen dat hij dit als 1 aanslag ziet?
Er loopt volgens mij geen stroom dus kan ik niet beredeneren wat voor condensator er over de contacten moet komen.

De sleutel trekt overigens de poort van Pullup naar Gnd.

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Zelf gebruik ik de Bounce2 library om het denderen te onderdrukken.
Werkt goed, kun je vinden in je library manager.

Na een toetsaanslag 20mS wachten werkt meestal ook goed.

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
buckfast_beekeeper

Golden Member

Er loopt toch een stroom. VCC/Rpullup.

Van Lambiek wordt goede geuze gemaakt.

Meestal is 100nF wel goed, met 50k pull-up is dat 5ms.

Wat ik in software meestal doe is als volgt een tellertje bijhouden:

ingang hoog: teller ophogen als hij nog niet aan het maximum zit (zeg 20, als je loop elke milliseconde draait)

ingang laag: teller verlagen als hij groter is dan 0

Teller < 5: status = 0

Teller > 15: status = 1

De status uitgang veranderd dus alleen als 3/4 van de recente samples de andere waarde heeft dan je status variabele. Dit geeft natuurlijk wel wat vertraging, maar die kun je korter maken door de loop sneller te draaien.

Je kunt wel de zoveelste library erbij trekken, maar daar leer je erg weinig van.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken

Inderdaad, de pulldownstroom is natuurlijk te beredeneren.
Ik kende het anti-dender principe en wist dat dat met een Ctje op te vangen was, maar nooit nagedacht over een R daarbij.

Dus de pullupweerstand icm een C.
Keiharde logica.

Dank voor de verduidelijking, SparkyGSX.

Ik heb ook wel lopen spelen met de delay icm de loopjes.
Ik ben daar eerst wat in vern*ukt doordat ik tussentijdse waardes op mijn serial monitor zette, die met een snelheid van 9600Kbs(?) een behoorlijke wissel trok op de loopjes.
Die hebik nu grayed out en nu is het finetunen.
Het loopje an sich is 5ms. De teller is vrij hoog, maar daar moet ik nog in kunnen tunen als ik de snelheid wil verhogen of verlagen.

Ik had al lopen spelen met een 10nF condensator, maar dat dekt de lading onvoldoende.

Op 15 februari 2019 23:00:48 schreef Arco:
Na een toetsaanslag 20mS wachten werkt meestal ook goed.

Vergis je niet...
Als een aanslag minimaal 25ms duurt, ofwel een punt, zal een letter "H" al snel 4 punten + 3 rustmomenten daartussen = 175ms duren.
Dan zit je al snel in de snelheid van een goede telegrafist. Mindere helden zoals ikzelf, met een behoorlijke foutmarge, vallen gemakkelijk buiten die waardes, waardoor er fouten en/of verkeerde karakters komen.

Ik sla nogal eens een karakter als bv een "N"(-.) aan, die dan als "S" (...) wordt geprojecteerd omdat de eerste streep als 2 punten wordt gezien

[Bericht gewijzigd door Fantomaz op 16 februari 2019 09:58:19 (30%)]

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Dit gebruik ik soms,hier toegepast op een rotary encoder,zonder interne pull-up.

Voel je vrij om de waarden aan te passen aan je noden.

[Bericht gewijzigd door Gij Kieken op 16 februari 2019 10:48:54 (23%)]

Dit lijkt wel wat op het verhaal van SparkyGSX.
Inderdaad met een interne pullup, maar ook weer met 100nF condensator.
De diode komt in dat verhaal niet voor maar ik kan me indenken dat zoiets ook wel in het IC zit (geprogrammeerd).

Daarbij weet ik niet zo 123 wat de interne Pullup weerstandswaarden zijn.
Jij hebt er 1 van 10K.
Als ik de waardes van de interne pullup weet, kan ik dit toch omgekeerd evenredig vergroten?
Dus bij 20K pullup een C van 50nF?

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Vergis je niet...
Als een aanslag minimaal 25ms duurt, ofwel een punt, zal een letter "H" al snel 4 punten + 3 rustmomenten daartussen = 175ms duren.

Dan neem je de tijd korter. 5mS of zo...

Toetsaanslag -> 5mS wachten -> nogmaals testen of toets ingedrukt is...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com
LetterHenk

Golden Member

Op 16 februari 2019 11:43:23 schreef Fantomaz:
Daarbij weet ik niet zo 123 wat de interne Pullup weerstandswaarden zijn.
Jij hebt er 1 van 10K.
Als ik de waardes van de interne pullup weet, kan ik dit toch omgekeerd evenredig vergroten?
Dus bij 20K pullup een C van 50nF?

Dit staat op arduino.cc

The value of this pullup depends on the microcontroller used. On most AVR-based boards, the value is guaranteed to be between 20kΩ and 50kΩ. On the Arduino Due, it is between 50kΩ and 150kΩ. For the exact value, consult the datasheet of the microcontroller on your board.

Action expresses priorities LH

De pull-ups bestaan uit een mosfet met hele hoge Rdson. Erg precies is de waarde daardoor nooit.
De pull-up stroom wordt ook meestal in uA uitgedrukt, niet in kOhms...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Ofwel kun je rekenen en tellen tot je de cijfertjes dubbel ziet,
ofwel het heft in eigen handen nemen en experimenteren.
Voor mijn toepassing is 100n geschikt probeer met 10n ...
Wil je er echt van afzien doe het dan in software.
Onderstaand een voorbeeldje zonder bibliotekeken.

code:


/*
   Purpose: Een knop software matig anti denderen
            Je kunt zowel pull-up als pull-down gebruiken
            -pull-down weerstand 10k tussen In-pin en gnd
             knop tussen In-pin en +5V
            -pull-up weerstand 10k tussen In-pin en +5V
             knop tussen In-pin en gnd
   Author:  GijKieken
   Date:    16/02/2019
*/

const byte LED = 6;        // Led aan pin 6
const byte KNOP = 3;       // Knop aan pin 3
boolean vorigeKnop = LOW;  // Variabele vorige knop status
boolean huidigeKnop = LOW; // Variabele huidige knop status
boolean ledAan = false;    // De huidige status van de led (on/off)

/*
   Antidender functie
   Geef de vorige status van de knop door en je
   krijgt de huidige ont-denderde knop status terug
*/
boolean antidender(boolean vorige) {
  boolean huidige = digitalRead(KNOP);  // Lees de knop status
  if (vorige != huidige) {              // Zijn ze verschillend?
    delay(5);                           // Wacht 5ms
    huidige = digitalRead(KNOP);        // Lees nog eens
    return huidige;                     // Geef de huidige status door
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(LED, OUTPUT); // Zet LED als uitgang
  pinMode(KNOP, INPUT); // Zet KNOP als ingang(niet echt nodig)
}

void loop() {
  // put your main code here, to run repeatedly:
  huidigeKnop = antidender(vorigeKnop); // Lees de antidender staat
  if (vorigeKnop == LOW && huidigeKnop == HIGH) { // Heb je gedrukt?
    ledAan = ! ledAan;                  // Klap de staat om
  }
  vorigeKnop = huidigeKnop;             // Reset de knop waarde
  digitalWrite(LED, ledAan);            // Verander de led staat
}

Op 16 februari 2019 12:00:38 schreef Arco:
[...]
Dan neem je de tijd korter. 5mS of zo...

Toetsaanslag -> 5mS wachten -> nogmaals testen of toets ingedrukt is...

Dat is ook wat ik nu heb. 5mS per cyclus.
Toch is dat te kort om vrij te zijn van denderen.
Van PICbasic weet ik nog dat 10mS genoeg was.
Ik zou inderdaad nog een statement ertussen kunnen zetten die wederom vraagt of de poort naar null is getrokken.
Maar stel dat dat dan niet het geval is?
Wat doet dat met mijn tellerwaarde?

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

Hoe weet je dat 5ms niet genoeg is? Een seinsleutel moet toch wel stabiel zijn in zo'n zee van tijd, zou ik denken. Je Arduino kan het trouwens ook meten. Je kunt immers zelf zien in de software hoe vaak en hoe lang ie nog wisselt totdat ie stabiel een kant op staat.

"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein

Op 16 februari 2019 19:30:59 schreef Fantomaz:
[...]

Dat is ook wat ik nu heb. 5mS per cyclus.
Toch is dat te kort om vrij te zijn van denderen.
Van PICbasic weet ik nog dat 10mS genoeg was.
Ik zou inderdaad nog een statement ertussen kunnen zetten die wederom vraagt of de poort naar null is getrokken.
Maar stel dat dat dan niet het geval is?
Wat doet dat met mijn tellerwaarde?

Wat belet je om te experimenteren,maak er 10ms van of whatever totdat het resultaat bevredigend is.

Sparky z'n methode is wel heel mooi: Hij is symmetrisch. Een oplossing met een condensator is dat niet omdat het ontladen door de schakelaar gaat (R= bijna nul), het opladen door de pullup (R = ongeveer 50k).

Of je onder de arduino software makkelijk een timer interrupt maakt weet ik niet. (opgezocht: jawel). Dan zou ik in de timerinterrupt iets doen als:

code:


static char pinctr;
volatile char pinstate;
#define MAXCNT 20
#define HYST 5

void timer_interrupt (void)
{
  if (digitalRead (KEY)) {
     if (pinctr < MAXCNT) {
       pinctr++;
       if (pinctr > ((MAXCNT/2)+HYST)) pinstate = 1;
  } else {
     if (pinctr > 0) {
       pinctr--;
       if (pinctr < ((MAXCNT/2)-HYST)) pinstate = 0;
  } 
}

De boel aanslingeren zou iets zijn als:

code:


void setup ()
{
  Timer1.initialize (1000); // 1000 us = 1 ms. 
  Timer1.attachinterrupt (timer_interrupt);
}

Dat is een "write-and-forget" stukje code. Vervolgens kan je gewoon de ge-de-bounce-de "pinstate" gebruiken.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Ik vraag ook iedere mS af omdat dat het meest flexibel is. Je kunt dan meteen ook testen of de toets lang of kort ingedrukt was.
(ook handig om gewone toetsen een 'repeat' functie te geven, zoals een PC keyboard)

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Gewoon elke tien msec kijken wat de status van de ingang van de seinsleutel is.
Als de seinsleutel minder dan 10msec dendert, dan ben je van alle problemen af.
Stel je gaat van laag naar hoog en de sleutel dendert 10 msec. Als je kijkt net tijdens de denderperiode, dan weet je niet of hij hoog of laag is, maar dat is ook niet boeiend. De volgende keer dat er gekeken wordt is de status van de seinsleutel hoog. Het 10msec-patroon kan dus van laag naar hoog 0-0-1 of 0-1-1 zijn. De fout is dus 10msec.
Het patroon van hoog naar laag kan 1-0-0 of 1-1-0 zijn. Ook hier kan een fout van 10 msec optreden.
Werkt dit niet, dan wordt het tijd voor een nieuwe seinsleutel.

Bezoek mijn neefjes' site: www.tinuselectronics.nl

Ik lees tussen de regels dat ie wil oefenen met seinen door de arduino morse -> letters te laten doen. Dan is een betrouwbare "hoe lang duurde deze punt-of-streep" heel belangrijk. Mogelijk is de bedoeling ook nog iets van: feedback geven of de punten en streepjes allemaal netjes kort en lang genoeg zijn.... Dan zijn samples "iedere 10ms" niet goed genoeg.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

Het programma heeft een cyclus waarbij hij ofwel wacht op een aanslag en intussen kijkt hoelang die tijd tussen de aanslag en de voorgaande aanslag is.

Bij het aanslaan wordt er een flag hoog gemaakt, zodat het programma herkent dat er eerder een aanslag is geweest.
Als er dan een tweede aanslag is, wordt de tijd bekeken en beoordeeld of de tijd kort is, zodat dit binnen een karakter valt, of dat deze wat langer is, zodat het als een andere letter wordt herkend.
In dat laatste geval wordt de letter geprojecteerd.
Is de rusttijd nog langer, dan wordt er een spatie aan toegevoegd.

Ik monitorde de aanslagen in tijd, en die tijd werd weergegeven op mijn serial monitor, samen met het karakter.
Het gebeurde me tevaak dat een aanslag (volgens mij) denderde omdat hij een aanslag als twee aanslagen zag.
Ik heb wel een paar voorwaardes ertussen gezet.
Ligt tijd tussen waardes a en b is het een punt.
Ligt tijd tussen waardes c en d is het een streep.

Buiten die kaders is het een error.
Wat ik met die error doe is nog even puzzelen. Misschien dat ik een sterretje oid weergeef.
Anyway... Ik kan de tijd zometeen instellen. Door de cyclustijd aan te passen.
Daarnaast kan ik de marge rondom de punt, streep of rustmomenten verruimen als leermiddel.

Zover ben ik nu overigens nog niet.
Ik blijf met die dender zitten.

Elektronisch stond ik er niet bij stil dat ik met een condensator alleen het "maak" moment kan dempen. Het loslaat moment speelt ook mee.

Terug naar het programma...
Als ik aansla, zijn er een paar cyclussen waar niets mee wordt gedaan.
Daarna pas worden ze geteld en afhankelijk van de lengte gezien als punt of als fout. (een streep wordt meestal dusdanig lang aangeslagen, dat dat niet fout gaat).
Door de dender valt het eerste stukje af omdat het te kort is.
Het tweede deel van die dender (er vanuit gaande dat het gezien wordt als 2 aanslagen) is vaak te kort, waardoor hij wordt genegeerd.

Met dat ik dit schrijf realiseer ik me dat ik binnen die denderperiode, moet voorkomen dat het program dit als een rust ziet.
Een rust kan pas ingaan als er 3 cycli voorbij zijn... (15mS)
Dit straks even proberen.

En dan natuurlijk ook bij het rustmoment...

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)

kijk ook eens naar de artikels op https://hackaday.com/?s=debounce

Meer specifiek staat daar als hardware debounce met 2 R en een C link
En een beetje verder met een logic NOT poort om ook de hysteresis correct te hebben.

In software kan je een soort van schuifregister gebruiken dat je in je loop opvult door de seinsleutel uit te lezen.
Die bitjes stroom kan je dan vergelijken zodat er voldoende 1'en of 0'en na elkaar moeten zijn voor een press of release.
embed-with-elliot-debounce-your-noisy-buttons-part-ii

Je zou ook meteen in je bitjes stroom een dit of dah kunnen detecteren.

Softwarematig is zoiets vrij simpel: je hoeft alleen te kijken of de toetsaanslag binnen de parameters valt.
Als er iets binnenkomt met te korte puls of pauze gewoon negeren/weggooien en opnieuw gaan tellen...

Arco - "Simplicity is a prerequisite for reliability" - hard en software ontwikkeling: www.arcovox.com

Hallo mensen,
Ik wil dit even oprakelen omdat er al veel nuttigs over is gezegd en ik dit project weer even uit de ijskast heb gehaald.

Ik hoop dat de moderatoren hier geen problemen mee hebben.

Wat ik me namelijk afvroeg, is of ik antidender kan zien met een serial monitor.
Er is al geopperd dat ik de betreffende poort kan monitoren om te zien of er overwegend ééntjes zijn, of juist nulletjes, die het respectievelijk een 1 of een 0 maken.

Als ik dit nu in een ongeremd loopje laat optellen in een counter waarbij elke stap 2x hoger is dan de voorgaande, dan moet ik toch een reeks ééntjes en nulletjes gedisplayed kunnen zien?

Dus een byte waarbij elke positie laat zien of het een 1 of een 0 was...

OF is er een andere manier om denderen zichtbaar te maken?
Het is wel handig om het te zien zodat je daarop kunt anticiperen.

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)
Sine

Moderator

Je kunt een teller clocken met de puls uit een drukker of schakelaar.

Of gewoon met een scope single shot triggeren en je ziet wat het doet.

Hallo Sine,

Je plaatje... Is dat 2mS per divisie of een beeld van 2mS?

Als het 2mS per divisie is, kost het denderen dus al 6mS.
Dat is best wel veel.
En nu is dit de dender na verbreken van het contact, zie ik.
Is dat met een condensator op te vangen?

Ik heb wel leuke schema's gevonden die het afschakelen wat strakker laten verlopen, maar het inschakelen is al een stuk minder.
(of net andersom natuurlijk)

https://www.circuitsonline.net/forum/file/29783

In de comments van dit plaatje, wat ook van CO kwam, zei men dat de diode pas relevant was als de schakelaar meer dan 10x per seconde werd aangeslagen.
Dat is nu net wat er bij morse gebeurt natuurlijk.
Dus moet ik een debouncer hebben die snel inschakelt, maar ook weer snel kan afschakelen.

Ik moet hier weer vaker komen... Wat kun je zo'n forum als deze gaan missen. :-)