Toggle funktion för LED

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Toggle funktion för LED

Inlägg 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.
Senast redigerad av wiktorahlander 22 februari 2014, 01:43:09, redigerad totalt 1 gång.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Toggle funktion för LED

Inlägg 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!
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Re: Toggle funktion för LED

Inlägg 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? :shock:

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

Re: Toggle funktion för LED

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

Re: Toggle funktion för LED

Inlägg 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... :-)
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Re: Toggle funktion för LED

Inlägg 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.
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Toggle funktion för LED

Inlägg 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
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Re: Toggle funktion för LED

Inlägg 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!
danei
EF Sponsor
Inlägg: 27416
Blev medlem: 2 juni 2003, 14:21:34
Ort: Östergötland
Kontakt:

Re: Toggle funktion för LED

Inlägg 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?
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Toggle funktion för LED

Inlägg 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
Senast redigerad av Magnus_K 23 februari 2014, 22:17:18, redigerad totalt 1 gång.
danei
EF Sponsor
Inlägg: 27416
Blev medlem: 2 juni 2003, 14:21:34
Ort: Östergötland
Kontakt:

Re: Toggle funktion för LED

Inlägg 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.
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Re: Toggle funktion för LED

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

Re: Toggle funktion för LED

Inlägg 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... :-)
wiktorahlander
Inlägg: 22
Blev medlem: 1 mars 2012, 20:19:36

Re: Toggle funktion för LED

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

Re: Toggle funktion för LED

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