Sida 1 av 2
Multipla switchar - hur hantera?
Postat: 28 juli 2009, 13:47:47
av sica06
Hej,
Jag kör en timer-rutin som följer samma princip som
denna för att debounca min MCU.
En overflow-timer pollar en pinne ungefär var 16:e ms, när x antal timers ger samma svar på pinnen så anses debounce klar.
Jag har nu tänkt koppla flera switchar till MCU:n och undrar hur detta går till. Det jag främst undrar är hur man löser problemet att flera switchar kan tryckas in samtidigt och att risken därför är att man missar tryckningar - hur lösa?
Har letat på nätet och i databladet men har inte fått någon generell idé på hur detta löses.
Uppskattar generella tips och länkar
(kör en AVR-P28 och ATmega88)
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 13:53:17
av eqlazer
Kan inte riktigt förstå vad du ser som problem, antagligen tänker vi väl olika hur man löser det.
Vad är det som skulle vara olika med endast en knapp jämfört flera? Varför skulle du missa tryckningar när du har _en_ rutin som kollar knapparna?
Mystisk pseudokod för ett sätt att lösa det
Kod: Markera allt
timer isr{
läs in knapp 1
om nedtryckt
öka nedtryckta sample (för debounce)
annars
nolla samples
läs in knapp 2
...
}
huvudprogram{
om (knapp 1 samples > 5){
//knapp 1 har varit nedtryckt tillräckligt länge
...
}
}
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 15:03:38
av sica06
mm, givetvis har du rätt, vet inte vad jag tänkte på...
Ber om ursäkt för det.
Undrar däremot en annan sak som jag inte riktigt får ihop.
På sidan som jag länkade till i första inlägget så menar författaren att han brukar kräva 10 loopar á 35 ms. Detta skulle alltså innebära en debounce-period på 350 ms, vilket ju är konstigt dels pga att studsar sällan vara mycket längre än 10ms samt att 350 ms sannolikt innebär att man missar en tryckning. Vad missar jag?
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 15:08:26
av Glenn
eller så läser man av hela (eller delar av) porten samtidigt, och har nån paus för debounce (inte så snyggt men men..) och processar sedan datat man fick ut.
Finns väl ingen anledning att läsa av dom en och en egentligen ?
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 15:22:41
av sodjan
> att 350 ms sannolikt innebär att man missar en tryckning.
Om du har behov av att trycka snabbare än 3 ggr/sek (och har knappar
som fixar det) så är det väl bara att köra med en kortare tid ?
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 16:40:06
av sica06
>Om du har behov av att trycka snabbare än 3 ggr/sek (och har knappar
som fixar det) så är det väl bara att köra med en kortare tid ?
Jag menar snarare att man inte håller knappen intryckt så länge. Ja, givetvis kan man köra med en kortare tid. Det jag tyckte var konstigt var att så långt som 350 ms rekommenderades när det, som jag har förstått det, snarare brukar röra sig kring 10 ms.
Men då var det kanske inget mer med det då.

Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 21:01:49
av Icecap
Jag använder en timer interrupt till att kolla brytare, jag har _aldrig_ debounce på då det helt enkelt inte behövs!
En hastighet på mellan 10-100Hz är alldeles lagom, oftast använder jag 10Hz då jag även använder denna frekvens till en del annat, sedan implementerar jag en n-key-rollover rutin (google känner igen den) och sparar resultatet. Detta har jag även gjort med en 8*8 matris utan problem.
Ibland bygger jag även en buffer till knapptryckningar men det är inte ofta, det beror på hur lång tid det kan ta innan knapptryckningen.
Re: Multipla switchar - hur hantera?
Postat: 28 juli 2009, 21:08:45
av Mindmapper
"Now, since we have a delay of about 35ms we can poll the button every 35ms and if for 10 polls its state is the same, we accept it as the new valid button state."
Var lång tid tycker jag också!
Nu beror det på vad det är för typ av knapp. Stora rejäla knappar i industrin tenderar man att trycka på längre än små knappar i tangentbord. Jag gjorde en gång en undersökning på hur lång tid knappar normalt hölls nertryckt. Ingen vetenskaplig undersökning men ändå en del intressant. Membranknappar håller man normalt in längre kom jag fram till. Den knapp jag minns bäst var en knapp som matade in ett ämne i en ugn. Trycket var typ normal industristandard. Där skillde det väldigt mycket beroende på operatör och vilken mod operatören var i. Som kortast just under 100ms och som längst ca 20s. De flesta tryckningar låg runt 200-350ms. Normalt också att man trycker ner en knapp längre tid om händelsen som ska utlösas dröjer innan något händer.
Kontaktstudsar brukar i de flesta fall ha avklingat mellan 10-20ms. Naturligtvis är det starkt beroende på kvaliten på knappen. Men de mest extrema studsarknapparna bör ha avklingat innan 50ms.
Personligen tycker jag att mer än 100ms är bortkastad tid, har man bråttom kan man nöja sig med 50ms. Men det är starkt beroende av typ och tillämpning.
Sen kan man också ifrågasätta att polla knappar på det sätt som görs i exemplet.
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 10:22:36
av sica06
- "Använder en timer interrupt... En hastighet på mellan 10-100Hz är alldeles lagom, oftast använder jag 10Hz då jag även använder denna frekvens till en del annat, sedan implementerar jag en n-key-rollover rutin (google känner igen den) och sparar resultatet. "
Är inte detta exakt det jag/
han gör? Använder timer-interrupt, kollar pinnarna, sparar resultatet till nästa runda.
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 10:46:24
av Icecap
OK, jag var nog inte tydlig nog:
Jag sparar INTE och räknar upp! Är knappen intryckt (läsas som det alltså) då _är_ den det och en knapptryckning rapporteras direkt. N-key-rollover-delen hindrar sedan att den rapporteras igen och igen, samtidig ger den, när det finns fler knappar, möjlighet att nästa knapptryckning kan läsas även om man inte har släppt den förra.
Jag har bara en enda gång haft en knapp att skulle vara på under 2 interrupt och det var för att den satt i ett mycket störfyllt miljö och den hade en vital funktion så att en felaktig avläsning kunde kosta en hel del pengar.
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 11:24:09
av mri
För att debounca en knapp är metoden att kräva N samples av samma värde fel... Det är en enkel metod men feltänk!
Metoden gör ju att knapptryckningen registreras i värsta fall först efter att knappen studsat färdigt plus en viss fördröjningstid förlöpt.
Korrekt metod är ju att registrera det *första* avvinakde samplet som knapptryck (eller release) och sedan *inte* beakta samplen under tiden knappen potentiellt studsar. Då blir responstiden maximalt lika lång som tiden mellan samplen.
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 12:36:46
av sica06
> Korrekt metod är ju att registrera det *första* avvinakde samplet som knapptryck (eller release) och sedan *inte* beakta samplen under tiden knappen potentiellt studsar.
Ja, det fungerar säkert bra. Du menar att när en knapp går LOW (trycks in) så räknas x antal samples (så pass länge att bounce kan antas vara över), efter detta gör man en eller ett par samples för att kolla om pinnen återigen är HIGH (släppt) (för att försäkra sig mot "falskt larm") och om den är det så anser man knapptryckningen bekräftad?
Som det är nu kollar jag varje pinne för sig, men som någon nämnde kunde man en hel PINx på en gång och dra slutsatser från den. Rent kodmässigt vet jag dock inte hur jag ska göra om jag vill göra detta. Jag menar, om knapptryckningar sker exakt samtidigt och båda "håller" hela debounce-tiden ut så är det inga probs. Men om två tryckningar överlappar varandra så förstår jag inte hur jag ska gå till väga.
Någon som kan visa med lite kod, om det är möjligt?
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 12:58:45
av Icecap
En sak är mycket viktig: om vi antar att det sitter 8 brytare på en port får denna port bara läsas en gång varje interrupt!!!
Behöver man att "omläsa" sparar man det lästa värde och använder detta, på det sätt kommer stutsande inte att påverka med 2 olika värden, en vid varje avläsning.
EDIT: lite C-kod, utgår ifrån att en port ska kollas och att det är 8 brytare som gäller.
typedef unsigned char byte;
Timer ISR: // Called with a rate of 10-100Hz
byte Current, Intermediate;
static byte Previous; // Need to keep it untill next time
Current = KeyPort; // Reads the key-port into "Current"
// Here any less than 8 keys should be bitwise eliminated, also if inverting needs to be done this is the time and place
Intermediate = Current & ~Previous; // Mask out all changes from last time
Intermediate &= Current; // Now Intermediate has all new keys set
Previous = Current; // Remember to next time
Sedan är det frågan för hur man vill handskas med flera knappar på samma gång, använder man en Key-buffer är det bara att kolla vilka bits som är '1' och peta den knapp i buffern:
if(Intermediate & 0x01) Add_Key_Buffer(Knapp_1);
if(Intermediate & 0x02) Add_Key_Buffer(Knapp_2);
if(Intermediate & 0x04) Add_Key_Buffer(Knapp_3);
if(Intermediate & 0x08) Add_Key_Buffer(Knapp_4);
if(Intermediate & 0x10) Add_Key_Buffer(Knapp_5);
if(Intermediate & 0x20) Add_Key_Buffer(Knapp_6);
if(Intermediate & 0x40) Add_Key_Buffer(Knapp_7);
if(Intermediate & 0x80) Add_Key_Buffer(Knapp_8);
Annars kan man även spola dessa tryckningar om man vill:
switch(Intermediate)
{
case 0x01:
case 0x02:
case 0x04:
case 0x08:
case 0z10:
case 0x20:
case 0x40:
case 0x80:
Key_Pressed = Intermediate;
break;
}
Key_Pressed är då den variabel som kollas för knapptryckningar och när det är reagerat på den nollas den.
Man kan även göra så att man tillåter fler knappar på samma gång och eftersom man läser och reagerar på dom kan man släcka dom bitmässigt. Utgår ifrån Key_Pressed.
if(Key_Pressed & 0x01)
{
Key_Pressed &= ~0x01; // Clean out this key
... // Do whatever there is to do
}
if(Key_Pressed & 0x02)
{
Key_Pressed &= ~0x02; // Clean out this key
... // Do whatever there is to do
}
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 13:07:50
av mri
Du menar att när en knapp går LOW (trycks in) så räknas x antal samples (så pass länge att bounce kan antas vara över), efter detta gör man en eller ett par samples för att kolla om pinnen återigen är HIGH (släppt) (för att försäkra sig mot "falskt larm") och om den är det så anser man knapptryckningen bekräftad?
Nja, det beror ju på vad man är intresserad av...
Skall programmet reagera när man trycker in knappen, eller när man släpper upp den?
Vad jag menar är att man skall vidarebefordra informationen till sitt program vid första samplet där en förändring har detekterats, inte efter att man samplat N gånger samma värde.
Som det är nu kollar jag varje pinne för sig, men som någon nämnde kunde man en hel PINx på en gång och dra slutsatser från den. Rent kodmässigt vet jag dock inte hur jag ska göra om jag vill göra detta. Jag menar, om knapptryckningar sker exakt samtidigt och båda "håller" hela debounce-tiden ut så är det inga probs. Men om två tryckningar överlappar varandra så förstår jag inte hur jag ska gå till väga.
Någon som kan visa med lite kod, om det är möjligt?
Skall du kolla flera knappar måste du förståss ha separata räknare och status variabler (och vad du nu behöver för andra variabler) för varje knapp. Gör en structur (struct) och sätt dom i nån tabell (array) så det blir lätt att hantera...
Re: Multipla switchar - hur hantera?
Postat: 29 juli 2009, 13:14:46
av bearing
Läs porten och XOR:a med förra avläsningen (som sparats). Är värdet skiljt från noll vet du om någon knappt tryckts. De bitar som är ettor är knappar som ändrats.