Sida 1 av 2
Toggle funktion för LED
Postat: 22 februari 2014, 01:31:24
av wiktorahlander
Hej! vill få en led att tändas / släckas med endast en knapp.
Om jag gör som jag lärt mig med typ PLCer osv fungerar de bara ibland. varför?
RC3 = LED
RA3 = Knapp (ger 0 vid tryck)
flag = "minne"
Kod: Markera allt
flag=0;
RC3=0;
while(1){
if(RA3==0 && flag==0){
RC3=1;
flag=1;
}
if(RA3==0 && flag==1){
RC3=0;
flag=0;
}
}
Den där koden borde i min värld växla LEDen på och av, vilket den iof gör 30% av gångerna.
Använder en PIC16F690 och PICkit2
EDIT: ändrade ett fel i koden.
Re: Toggle funktion för LED
Postat: 22 februari 2014, 01:35:13
av Magnus_K
Rent spontant så känns det som om det hade varit bra med en delay i varje if-sats för att förhindra debouncing.
Sen om detta är det exakta koden så har du nog glömt ett "=" i början av den andra if-satsen, vilket kan ställa till det lite.
Sen som sagt, jag är också nybörjare. Du får förhoppnigsvis bättre svar.
EDIT: Kanske inte hindra debouncing, snarare förhindra bouncing!
Re: Toggle funktion för LED
Postat: 22 februari 2014, 01:42:25
av wiktorahlander
Det är inte den exakta koden, ser nu att jag glömt ett = men i koden jag skrivit till pic:en så är de rätt.
__delay_ms(1); funktionen gjorde bara att LED lyste hela tiden?
Sen undrar jag om delay gör så att timern slutar räkna. Kommer ha en timer som gör en fördröjning på nån minut senare, går det att få den att köras parallellt med det andra eller?
För om jag gör en delay i en knapptryckning så blir det ju även delay för uppräkningen av variabeln för min timer? eller är jag ute å åker tuktuk nu?
Re: Toggle funktion för LED
Postat: 22 februari 2014, 11:13:53
av Icecap
__delay_ms() kör INTE med en timer! Det är en ren for-to-next som genererar en kodsnutt som tar en viss tid att fullföra.
Lösningen för dig är att göra en funktion:
Kod: Markera allt
#define true 1
#define false 0
#define Key RA3
#define LED RC3
unsigned char Previous;
while(true)
{
if(!Key && !Previous)
{
// Key has been pressed
Previous = true; // Mark as "Got it!"
if(LED) Led = false;
else LED = true;
}
else Previous = false;
}
Men denna lösning gör att brytaren måste vara utan studs, något som är mycket svårt (omöjligt) med mekaniska brytare. Detta kan antingen lösas vid att avkoppla själva brytaren med någon kondensator eller vid att göra mjukvaran så att den klarar biffen.
Jag föredrar att lösa detta i mjukvara och då är lösningen att läsa fler gångar och när två (eller fler) avläsningar med ett visst tidintervall mellan (50ms?) är identiska är det brytarens status.
Nu börjar det komma in en massa "använd __delay_ms()"-råd men mitt råd är att starta en timer-interrupt med kanske 20-30Hz, då blir resten enkelt.
Jag har som regel att i varje interrupt läsa porten
en enda gång! Ska man använda resultatet fler gångar i samma rutin sparar jag det lästa värde i en variabel. Då undviker man att brytaren studsar mellan första och andra avläsningen. Ska det hela vara 100% bergsäkert använder jag 3 avläsningar efter varandra.
Sedan sparar jag även en variabel med "förra avläsningen" i och först när de två är identiska kollar jag om man har tryckt eller släppt knappen. Efter det är det bara att kolla vad som händer.
Re: Toggle funktion för LED
Postat: 22 februari 2014, 13:06:46
av sodjan
Vad händer med den ursprungliga koden om knappen hålls intryckt?
(Jo *jag* vet, det är en hemläxa till dig).
Sen så är den fördröjning på 1 ms "ingenting" i sammanhanget
och gör ingen skillnad alls.
Tillbaka till ritbordet och tänkt till lite mer...

Re: Toggle funktion för LED
Postat: 23 februari 2014, 20:58:50
av wiktorahlander
Icecap skrev:
Jag föredrar att lösa detta i mjukvara och då är lösningen att läsa fler gångar och när två (eller fler) avläsningar med ett visst tidintervall mellan (50ms?) är identiska är det brytarens status.
Nu börjar det komma in en massa "använd __delay_ms()"-råd men mitt råd är att starta en timer-interrupt med kanske 20-30Hz, då blir resten enkelt.
Jag har som regel att i varje interrupt läsa porten en enda gång! Ska man använda resultatet fler gångar i samma rutin sparar jag det lästa värde i en variabel. Då undviker man att brytaren studsar mellan första och andra avläsningen. Ska det hela vara 100% bergsäkert använder jag 3 avläsningar efter varandra.
Sedan sparar jag även en variabel med "förra avläsningen" i och först när de två är identiska kollar jag om man har tryckt eller släppt knappen. Efter det är det bara att kolla vad som händer.
Har suttit å försökt lösa de där med timern som du föreslog vilket verkar som en mycket bra idé. Tyvärr har jag inte fått till det så förklara gjärna mer utförligt hur du menar!
sodjan skrev:Vad händer med den ursprungliga koden om knappen hålls intryckt?
(Jo *jag* vet, det är en hemläxa till dig).
Sen så är den fördröjning på 1 ms "ingenting" i sammanhanget
och gör ingen skillnad alls.
Tillbaka till ritbordet och tänkt till lite mer...

Det där hjälpte inte ett dugg.
Re: Toggle funktion för LED
Postat: 23 februari 2014, 21:37:33
av Swech
Kod: Markera allt
if(RA3==0 && flag==0){
RC3=1;
flag=1;
}
---- Vi antar att RA3 är 0 och flaggan var 0
Flaggan har ändrats till 1 när programmet kommer hit
if(RA3==0 && flag==1){
---- RA3 är fortfarande 0 och din flagga är 1
RC3=0;
flag=0;
---- Nu är din flagga 0 igen
---- Resultatet blir att RC3 växlar mellan 1 och 0 så länge som RA3 = 0
}
Swech
Re: Toggle funktion för LED
Postat: 23 februari 2014, 21:54:29
av wiktorahlander
Swech skrev:Kod: Markera allt
if(RA3==0 && flag==0){
RC3=1;
flag=1;
}
---- Vi antar att RA3 är 0 och flaggan var 0
Flaggan har ändrats till 1 när programmet kommer hit
if(RA3==0 && flag==1){
---- RA3 är fortfarande 0 och din flagga är 1
RC3=0;
flag=0;
---- Nu är din flagga 0 igen
---- Resultatet blir att RC3 växlar mellan 1 och 0 så länge som RA3 = 0
}
Swech
Jo att de blir sådär har jag förstått nu! Nu vill jag bara förstå hur jag avhjäper bouncen!
Re: Toggle funktion för LED
Postat: 23 februari 2014, 21:57:50
av danei
Du kan strunta i en eventuell studs, det är ju ändå slumpen som avgör om du släpper knappen när den lyser eller inte.
Du bör nog tänka lite på tonen om du vill ha hjälp. Vad har du fattat och vad har du inte fattat?
Re: Toggle funktion för LED
Postat: 23 februari 2014, 22:13:14
av Magnus_K
Tror jag fann en ganska bra pdf om ämnet. Tänker själv spara den i min pärm för den var pedagogisk och bra.
I slutet av sida två kanske du har vad du söker och det som låter bäst (i mina otroligt färska öron) är just vad Icecap skrev, att använda timer interrupt för att läsa av ingången vid ett visst intervall. Om du även skriver så att det krävs ett visst antal "TRUE" efter varandra för att läsa ingången som "TRUE" så känns det som att man har en mycket pålitlig debounce.
Eller har jag fel? Eller jag jag haft otur igen?
Ovan nämnda pdf'en ->
www.ganssle.com/debouncing.pdf
Re: Toggle funktion för LED
Postat: 23 februari 2014, 22:15:26
av danei
Det är nog en bra metod. Men i en sådan här applikation räcker en enkel delay bra. Men frågan är om det är det som är problemet för TS.
Re: Toggle funktion för LED
Postat: 24 februari 2014, 00:20:48
av wiktorahlander
Jag har efter en del problem lyckats lösa mitt problem med en timer som ICECAP föreslog!
Hade dessutom ett fel på original kretskortet som gjorde att RA3 ALLTID var hög....
Monterade pic på ett labb kort ist å nu fungerar det
Kod: Markera allt
#include <pic.h>
#include <htc.h>
__CONFIG (FOSC_INTRCCLK&WDTE_OFF&MCLRE_OFF&CP_OFF);
#define FOSC 8000000L
#define _XTAL_FREQ 8000000
#define ON 1
#define OFF 0
//LED:S
#define LED_BSPEGEL RC3
//BRYTARE
#define SW_BSPEGEL RA3
int button;
int flag;
int clock;
int bounce;
Init(void)
{
OSCCON = 0x70;
TMR0 = 0; //Clear the TMR0 register
OPTION_REG = 0B00000010;
}
main(void)
{
Init();
//CONFIG PORTS
TRISC=0x00;
ANSEL=0x00;
PORTC=0x00;
TRISA=0xff;
RC3 = 0;
//GRUNDVÄRDEN
flag=0;
bounce = 200; //TID för DEBOUCE
while(1) //LOOP FOREVER
{
if(T0IF && SW_BSPEGEL==1){ //NÄR TIMER OWERFLOW ÖKA CLOCK MED 1
clock=clock+1;
T0IF=0;
}
if(clock>bounce && flag==OFF && SW_BSPEGEL==0){ //TÄND LED FÖR BACKSPEGEL
flag=ON;
LED_BSPEGEL = ON;
clock=0;
}
if(clock>bounce && flag==ON && SW_BSPEGEL==0){ //SLÄCK LED FÖR BACKSPEGEL
LED_BSPEGEL = OFF;
flag=OFF;
clock=0;
}
}
}
finns även här
Re: Toggle funktion för LED
Postat: 24 februari 2014, 00:55:11
av sodjan
> Nu vill jag bara förstå hur jag avhjäper bouncen!
Det viktiga här är ju att du faktiskt förstog vad som var det *stora*
problemet med din ursprungliga kod! Det har inte med "de-bounce" att göra.
Om du inte vid det här laget ser det klart och tydligt så har du sannolikt
andra problem på gång.
Ett annat sätt att se på det är att en så kort kod som det var från början
nästan måste vara fel, det går inte att få önskad funktion med så
lite kod...

Re: Toggle funktion för LED
Postat: 24 februari 2014, 01:06:33
av wiktorahlander
sodjan skrev:> Nu vill jag bara förstå hur jag avhjäper bouncen!
Det viktiga här är ju att du faktiskt förstog vad som var det *stora*
problemet med din ursprungliga kod! Det har inte med "de-bounce" att göra.
Om du inte vid det här laget ser det klart och tydligt så har du sannolikt
andra problem på gång.
Ett annat sätt att se på det är att en så kort kod som det var från början
nästan måste vara fel, det går inte att få önskad funktion med så
lite kod...

För att se om jag förstod dig rätt, du såg fel förut men inte nu?
för som det är nu fungerar de precis som jag vill

Re: Toggle funktion för LED
Postat: 24 februari 2014, 01:11:03
av sodjan
V.v. kopiera inte all text från föregående inlägg!
Det blir väldigt mycket dubbel text i tråden...
Nej, det var bara det att jag inte uppfattade att du helt
hade förstått vad som var grundfelet med första koden. Om
det inte spelar någon roll för dig, så bryr jag mig inte heller...
