Multipla switchar - hur hantera?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Multipla switchar - hur hantera?

Inlägg 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)
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Re: Multipla switchar - hur hantera?

Inlägg 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
		...
	}
}
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Multipla switchar - hur hantera?

Inlägg av sica06 »

mm, givetvis har du rätt, vet inte vad jag tänkte på... :doh:
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?
Användarvisningsbild
Glenn
Inlägg: 36667
Blev medlem: 24 februari 2006, 12:01:56
Ort: Norr om Sthlm
Kontakt:

Re: Multipla switchar - hur hantera?

Inlägg 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 ?
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Multipla switchar - hur hantera?

Inlägg 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 ?
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Multipla switchar - hur hantera?

Inlägg 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å. :)
Användarvisningsbild
Icecap
Inlägg: 26636
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Multipla switchar - hur hantera?

Inlägg 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.
Mindmapper
Inlägg: 7104
Blev medlem: 31 augusti 2006, 16:42:43
Ort: Jamtland

Re: Multipla switchar - hur hantera?

Inlägg 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.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Multipla switchar - hur hantera?

Inlägg 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.
Användarvisningsbild
Icecap
Inlägg: 26636
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Multipla switchar - hur hantera?

Inlägg 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.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Multipla switchar - hur hantera?

Inlägg 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.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Multipla switchar - hur hantera?

Inlägg 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?
Användarvisningsbild
Icecap
Inlägg: 26636
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Multipla switchar - hur hantera?

Inlägg 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
}
Senast redigerad av Icecap 29 juli 2009, 13:14:44, redigerad totalt 1 gång.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Multipla switchar - hur hantera?

Inlägg 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...
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Multipla switchar - hur hantera?

Inlägg 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.
Skriv svar