Uj uj uj... någon känner sig påhoppad!
Jag anser att koden visar en oerfaren programmör - men tydligen tolkar TS det som att det betyder "dåligt människa". Jag har helt riktigt AS och regeln är: tolka inte mina ord! De betyder exakt vad som står, inget annat! Jag står för min värdering, jag ämnar inte be om ursäkta för att ha min åsikt och det finns inget påhopp i det!
Efter två sidor med tips om hur man kan avstutsa väljer TS att inte använda någon information om detta alls - och varför då fråga? Jag kan inte se att projektet faktisk behöver avstutsning - men en ytterligare utbyggnad kanske kan behöva detta och det är ju bra att kunde tekniken.
Alla råd innebär en integration av knappsignalen i någon form, vara sig det är i mjukvara eller hårdvara. Och alla verkar vara ganska överens om att olika brytare/reläer har olika debounce-tider, detta betyder att ett filter bör antingen ställas till worst-case eller vara ställbart.
Med en delay() funktion kan man skapa detta, tyvärr kan det kosta onödig processortid - men har den inte bråttom är det lugnt. En sak som man ska ha klart för sig är att om man:
Läser portpinne, utför en delay() och sedan läser portpinne igen och då har två olika avläsningar måste man ha ytterligare en delay() för att säkerställ att avläsningen inte upprepas för snabbt.
I detta fall är delay'en 5ms, inte mycket tid, varken i debounce eller människotid - men för en PIC på 8MHz blir det ändå 10.000 instruktioner som kastas bort i onödan. Med dessa 10.000 instruktioner hade den lätt klarat av att serva en timer-interrupt, kollat porter efter knapptryckningar, debouncad dom och givit klara och tydliga signaler ifrån sig - och ändå ha massor av tid över. Och allt bara på en bråkdel av den 5ms vänttid som en delay() låser programexekveringen. Det finns en anledning till att man kan använda timers till att ge interrupt...
Har man krav på kända tider kommer en timer-interrupt in nästan som ett krav, då får man kända tider mellan samplingarna och jag har testat en hel del och kommit fram till att om en "total avkänning" ska kännas rätt och man ska fånga snabba knapptryckningar behöver denna totala avkänning ta maximalt 100ms. Bra tider är mellan 50ms och 100ms.
Vill man alltså ha 3 lika avläsningar ska tiden mellan varje avläsning vara maximalt 100ms/3 = ~33ms. Och precis som v-g skriver gör det saken enklare att ha "håll inne knappen i 3 sekunder för..." osv.
Mina tester har även visat att 2 avläsningar efter varandra med mellan 33ms och 50ms mellan räcker helt fint till att undvika störningar om det inte är synnerligt svåra fall (långa ledningar osv.) - där man ändå måste skydda med ingångsfilter osv.
Det viktiga är att man enbart avläser porten
en enda gång per interrupt! Ska man använda avläsningen i "rå form" fler gångar får man mellanspara avläsningen i minnet men i essens är det viktiga att ha en sekvens i form av:
Kod: Markera allt
Minnen:
'Now' är en (eller fler) variabel/variabler som fungerar som mellanregister. Behöver inte sparas mellan varje interrupt.
'Previous' och 'Used' är samma storlek variabler och de MÅSTE sparas mellan varje interrupt. Jag brukar ange dom i ISR'n och deklarera dom som 'static'.
Now = port(); // Läsa knapp-porten, en eller fler. Sparas i variabeln Now.
if((Now == Previous) && (Now & ~Used))
{
Used = Now; // Spara att knapptryckningen redan är använd.
// Gör vad som ska göras när en knapptryckning avkänns. Gör dock inte detta i en interruptrutin om inte det är en mycket snabb grej!
// Jag brukar skriva till en variabel som main-loopen kan avkänna och nolla när den har använd knapptryckningen. Är det lite större projekt har jag ibland gjort en FIFO för knapptryckningar.
Ganska ofta använder jag "n-key rollover"-funktionen för att kunde säkerställa att knapptryckningar i snabb följd inte ställer till det för varandra.
}
Previous = Now; // Spara denna avläsning som "förra"
if(!Previous) Used = 0x00; // Om knapparna är släppta nollställs 'Used'
Man kan behöva justera koden lite om man har '1' som inaktiva nivåer, behöver maska ut specifika bitar osv.
Och det enda jag skrev om oerfaren var att jag såg det och att erfarenheten kommer med tiden. Erfarenhet är in mina ögon inte att ha gjort en sak många gångar, det är att lära av sina fel! Och ja, jag har lärt väldigt mycket av mina fel, helt enkelt för att jag har gjort så många! Jag är oerfaren på en del områden, jag har t.ex. bara kört moppe en enda gång (för 36 år sedan), motorcykel en enda gång (som förare), det var dock en RR-trimmad Suzuki 750 på Anderstorp. Jag har testat en cross-hoj (500cm³) en enda gång - och jag kunde inte hålla gång i skiten...
Jag är inte sämre människa för det - men likaväl oerfaren på vissa områden - och det helt utan att skämmas för det.