[vb6]Seriële input debouncen

Pagina: 1
Acties:

  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Ik heb hier een schakelaar aan de input van een seriele port hangen (op de CD pin).

Binnen vb6 heb ik een mscomm control en de events controleer ik op de volgende manier:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Private Sub MSComm1_OnComm()
    
    Select Case MSComm1.CommEvent
    
        ' Handle each event or error by placing
        ' code below each case statement
        ' Errors
        Case comEventBreak  ' A Break was received.
        Case comEventCDTO   ' CD (RLSD) Timeout.
        Case comEventCTSTO  ' CTS Timeout.
        Case comEventDSRTO  ' DSR Timeout.
        Case comEventFrame  ' Framing Error
        Case comEventOverrun    ' Data Lost.
        Case comEventRxOver ' Receive buffer overflow.
        Case comEventRxParity   ' Parity Error.
        Case comEventTxFull ' Transmit buffer full.
        Case comEventDCB    ' Unexpected error retrieving DCB]

        ' Events
        Case comEvCD    ' Change in the CD line.
            If MSComm1.CDHolding Then CD.SignalOn
            If Not MSComm1.CDHolding Then CD.SignalOff
       
     End Select

End Sub


Het contact van de schakelaar dendert een beetje bij het omzetten en ziet daarom de case comEvCD soms wel 5 keer, en voert hem dus ook 5 keer uit.

Is er een manier dat als er een event wordt gedetecteerd even te wachten alvorens de event te bepalen en de select case uit te voeren?

Een Sleep(500) in de case bijvoorbeeld werkt niet, omdat hij gewoon heel die case 5x uitvoert...

/edit:

Natuurlijk kan ik het doen met een flip-flop of debouncer, maar ik wil graag weten of het in software ook kan.

[ Voor 12% gewijzigd door LiquidSmoke op 17-03-2007 13:07 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-12 20:19

Gerco

Professional Newbie

Sla de tijd op op het moment van schakelen (lastTime = Timer) en controleer of er al een bepaalde tijd voorbij gegaan sinds de vorige event in je event handler:
Visual Basic 6:
1
If lastTime - Timer < bounceTime Then Exit Sub


Op die manier schakel je op de eerste event, maar kun je gedurende de volgende 500ms (oid) de bounces negeren. Afhankelijk van hoe lang het contact dendert, stel je die 500 ms bij naar de kleinste, werkende waarde.

[ Voor 32% gewijzigd door Gerco op 17-03-2007 13:25 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Damn, dat is wel slim ja, gewoon kijken of de event in de laatste 500ms getriggered is zoja exit...

Kan wel wat met VB6 maar sommige dingen zijn niet aan mij besteed :)

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Gewoon elke bounce de tijd opslaan en kijken of er al genoeg tijd is verstreken, dan je spul uitvoeren. Op die manier schakel je als de schakelaar een X tijd ingedrukt is.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Ik zat er ff mee te spelen en had deze sub gemaakt:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Private Sub Command1_Click()

Dim bouncetime As Integer

bouncetime = 5
lasttime = Timer


If lasttime - Timer < bouncetime Then
    Label1.Caption = lasttime - Timer
    Exit Sub
End If

MsgBox ("hoi")

End Sub


Maar de uitkomst is altijd 0?

net alsof er niet genoeg tijd verstrijkt om de timer op te hogen.

[ Voor 9% gewijzigd door LiquidSmoke op 17-03-2007 18:42 ]


  • Erikbobo
  • Registratie: Oktober 2001
  • Laatst online: 30-11 21:04
code:
1
2
3
4
lasttime = Timer


If lasttime - Timer

Lijkt me nogal wiedes dat dat altijd 0 is...

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-12 20:19

Gerco

Professional Newbie

De resolutie van die timer is ongeveer 1/18e van een seconde. Als dat niet genoeg is, moet je de Win32 API QueryPerformanceCounter gebruiken.

@hierboven: *proest*, dat ik dat niet gezien heb :) De timer moet je natuurlijk wel zetten *na* het processen van de event.

[ Voor 31% gewijzigd door Gerco op 17-03-2007 18:48 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Das waar ook :Y)

Heb nog nooit eerder met een timer gewerkt...

Waar precies laat ik die lasttime - timer dan? onderaan de event is ie toch weg als ik de volgende keer weer het event tegen kom?

Je zou zeggen dat telkens als de case uitgevoerd is hij die waarde weg moet zetten om hem later weer op te halen....

[ Voor 14% gewijzigd door LiquidSmoke op 17-03-2007 18:50 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
LiquidSmoke schreef op zaterdag 17 maart 2007 @ 18:48:
Heb nog nooit eerder met een timer gewerkt...
Dat heeft er weinig mee te maken. Het gaat om de logica die erachter zit.
Je zou zeggen dat telkens als de case uitgevoerd is hij die waarde weg moet zetten om hem later weer op te halen....
Maak Lasttime static

Visual Basic:
1
2
3
4
5
6
7
8
Static LastTime as Single

Dim TimeVal as Single: TimeVal = Timer

If TimeVal - LastTime > Interval Then
    ' Do stuff here
    LastTime = TimeVal
End If


Mag je alleen nog de wrap around bug eruit halen :P

Lijkt me sterk trouwens dat dat verhaal in een button click functie hoort magoed

[ Voor 6% gewijzigd door farlane op 17-03-2007 19:37 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
button click was ff om mee te spelen, zit hier bij gf thuis, heb mijn hardware en source niet bij de hand.

Ff geprobeerd en inderdaad, met static overleeft ie het :)

Werkt als een trein nu iig... Zal het vanaovn eens in mijn select case inbouwen...

Nog veel te leren over VB6 zo te zien...

[ Voor 47% gewijzigd door LiquidSmoke op 18-03-2007 13:11 ]


  • Paul
  • Registratie: September 2000
  • Laatst online: 11:50
Je kunt het ook in hardware doen :P Heb je een schakelaar naar GND met een pull-up? Gewoon een condensatortje zetten over de schakelaar (dus tussen gnd en je com-poort-pin). De RC-waarde is de ontdender-tijd.

Met een 1 µF elco en een 47k pull-up heb je dus 47 ms als ik de theorie zelf goed heb gesnapt :P

"Your life is yours alone. Rise up and live it." - Richard Rahl
Rhàshan - Aditu Sunlock


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Paul Nieuwkamp schreef op zondag 18 maart 2007 @ 13:33:
Je kunt het ook in hardware doen :P Heb je een schakelaar naar GND met een pull-up? Gewoon een condensatortje zetten over de schakelaar (dus tussen gnd en je com-poort-pin). De RC-waarde is de ontdender-tijd.

Met een 1 µF elco en een 47k pull-up heb je dus 47 ms als ik de theorie zelf goed heb gesnapt :P
Moet normaal gesproken altijd gedaan worden inderdaad ivm met ruis/pieken etc die niet automagisch een knop druk mogen worden :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Dat zou kunnen inderdaad.

Maar mocht ik alleen een puls willen gebruiken dan krijg je toch 2 events, hier kan ik denk ik wel omheen met software (holding en not holding), maar moet dit gewoon ff proberen van de week.

Die wrap around bug is wel iets vervelends, vooral omdat de applicatie meerdere dagen aanstaat en het totaal random is dat het in en uitgeschakeld kan worden...

Bijvoorbeeld 10000 - 1000 = 9000 en is groter dan de interval van 6 (die waarde werkt voor mij goed).

Eigenlijk om 12u snachts de static laten updaten met een nieuwe waarde denk ik...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
LiquidSmoke schreef op maandag 19 maart 2007 @ 08:49:
Eigenlijk om 12u snachts de static laten updaten met een nieuwe waarde denk ik...
Nah, als dat gebeurd is de nieuwe waarde kleiner dan de oude

Visual Basic:
1
2
3
if TimeVal < LastTime Then
Else
EndIf

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Na dat werkt ook niet...

De puls/contact komt van een relais...

Vervangen door een opto/solid state relais en dan ben ik er ook vanaf :Y) maar dat is voor een andere categorie.

Het gaat me erom toch dit sooort problemen in software op te lossen.

Je moet je dan echt wat meer verdiepen en dat is juist wat ik wil, om hoekjes leren denken...

  • WormLord
  • Registratie: September 2003
  • Laatst online: 01-12 13:49

WormLord

Devver

Kun je niet werken met een timer event? Dus dat je bij het eerste event in een static boolean zet dat het event net is aangeroepen en een timer event aanmaakt om die boolean weer om te zetten?

Even wat pseudocode om te proberen het wat duidelijker te maken:
code:
1
2
3
4
5
6
7
8
static boolean JustCalled = false

if not JustCalled then
    do some stuff here

    JustCalled = true
    call {JustCalled = false} after x microseconds
end

  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Dat is een hele slimme, en ook bruikbaar...

Dan heb je geen wrap around bug meer iig en kan ik pulsen gebruiken... gewoon een teller aanroepen die de boolean terugzet...

Ik zal het eens proberen te vertalen naar mijn projectje...

[ Voor 6% gewijzigd door LiquidSmoke op 19-03-2007 10:53 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
Waarom niet ? Je moet alleen de verstreken tijd anders berekenen:
Visual Basic:
1
MaxTimeVal - LastTime + TimeVal

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • LiquidSmoke
  • Registratie: Maart 2001
  • Laatst online: 30-11 09:11
Dat zou idd kunnen...

Heb het nu met het idee van wormlord geprobeerd, en dat werkt perfect :)

Handigheidje is dat ik niet aan die interval gebonden ben, maar aan een boolean die ik ook weer kan verzetten via een andere weg mocht nodig zijn...
Pagina: 1