Start Elkretssimulator Karnaughdiagram Quine McCluskey


Koppla knappar till analog ingång

Problemet: digitala pinnar slut

Det finns bara ett begränsat antal digitala in/ut -gångar på de flesta mikrokontrollers. Säg att de digitala in/ut -gångarna är slut men du behöver ansluta några knappar. En variant är att använda en analog ingång på mikrokontrollern. Studera nedan schema.



Beroende på vilken knapp vi klickar på så skapas en spänningsdelare som ger olika typer av spänningar. Denna spänning läser vi sedan av med den analoga ingångens A/D -omvandlare och kan på så vis avgöra vilken knapp vi klickat på. Spänningen i ovan schema är 5 volt.

Prova kretsen i simulatorn. Klicka på någon av knapparna och studera hur det fungerar.

Klickar på S1

Om vi klickar på S1 så skapas en sluten krets med strömmen

I = U / (R1+R4) = 5 volt / ( 22 Ω + 220 Ω) = 5 volt / 244 Ω = ca 20 mA

Det betyder att spänning över voltmetern, som också är vår inkoppling till den analoga ingången på vår arduino senare, i schemat är

U1 = 20mA x 220 Ω = 4.5 volt

Klickar på S2

På motsvarande sätt om vi klickar på knapp S2 så får vi en sluten krets med strömmen

I = U / (R2+R4) = 5 volt / ( 100 Ω + 220 Ω) = 5 volt / 330 Ω = ca 15.6 mA.

Detta ger spänningen

U1 = 15.6 mA x 220 Ω = 3.4 volt

Klickar på S3

Klickar vi på S3 så får vi en sluten krets med strömmen

I = U / (R3+R4) = 5 volt / ( 220 Ω + 220 Ω) = 5 volt / 440 Ω = ca 11 mA

Detta ger spänningen

U1 = 11mA x 220 Ω = 2.5 volt

I vår kod måste sedan läsa av ett intervall eftersom spänningarna inte kommer bli exakt ovan värden. Men de är tillräckligt distinkta (åtskilda) för att vi säkert skall kunna avgöra i koden vilken knapp som är nertryckt.

Vad händer om vi klickar på flera knappar samtidigt, t.ex. alla 3 samtidigt? Om vi parallellkopplar R1, R2 och R3 får vi följande resistans

R = 1 / (1/R1 + 1/R2 + 1/R3) = 1 / (1/22 + 1/100 + 1/220) Ω = 1 / 0.06 Ω = 16.7 Ω

Dvs, vi får en ström på

5 volt / (16.7 &ohm + 220 Ω) = 5 volt / 236 Ω = 21 mA

Dvs spänningen U1 blir

U1 = 21mA x 220 Ω = ca 4.7 volt

Koppla ihop

Efter att ha grottat lite i motstånds -lådan hittade jag inte exakt ovanstående resistanser men däremot värden 24 Ω, 110 Ω samt 2 st 200 Ω så ovanstående spänningar kommer inte stämma för mig. Strunt i det! Den ihoplödda knappgrejen ser ut som nedan. Svart och Röd spänning in och organge signal ut till lämplig A/D -ingång.



Test

Mäter jag spänningen med multimeter får jag nu 2.48 volt, 3.19 volt eller 4.39 volt beroende på vilken knapp jag trycker.

Om jag trycker in signalen från knapparna i analog in pinne 3 och kör över följande program ...

int val = 0;

void setup() 
{
  Serial.begin(115200); 
}

void loop() 
{
  val = analogRead(3);
  Serial.println(val);  
}


Så får jag nu detta resultat beroende på vilken knapp jag trycker:

Trycker på knapp 1.



Trycker på knapp 2.



Trycker på knapp 3.



Är ovan värden vettiga? Vi kan göra en liten kontrollräkning. Den analoga insignalen ger ett värde 0-1024 mellan 0-5 volt. Vår kontrollmätning gav 2.48 volt, 3.19 volt eller 4.39 volt beroende på vilken knapp vi tryckte på. Det betyder att vi borde fått värdena:

2.48 * (1024 / 5) = 508
3.19 * (1024 / 5) = 653
4.39 * (1024 / 5) = 899

Detta stämmer inte riktigt med de värden vi fick men det är ganska bra ändå. Min voltmeter är troligtvis felkällan då batterierna är dåliga och den är inte heller kalibrerad. Det är inte så noga!

Okej, så vi kan skriva om programmet så att det ser ut såhär.

int val = 0;

void setup() 
{
  Serial.begin(115200); 
}

int knapp(int v)
{
  if(v>450&&v<550) return 1;
  if(v>600&&v<700) return 2;
  if(v>850&&v<950) return 3;
  return 0;
}

void loop() 
{
  val = knapp(analogRead(3));
  if(val)
  {
      Serial.println(val); 
  }
}


Fixa knappstuds

Ovan kod ger oss med säkerhet den knapp vi klickar på. Men det återstår fortfarande ett problem och det är knappstudset. Ett sätt att komma runt är t.ex. på följande sätt. Dvs vi fångar knapptrycket och behåller detta värde tills ingen knapp har varit tryckt på en liten stund. Interruptet anropar ISR ca 16 ggr per sekund.

int pval = 0;
int val = 0;
int keyPressed = 0;
int countNopress = 0;

void setup() 
{
  Serial.begin(115200); 

  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A =  1000; 
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12) | (1 << CS10); // 1024 prescaler
  TIMSK1 |= (1 << OCIE1A);
  sei();  
}

int knapp(int v)
{
  if(v>450&&v<550) return 1;
  if(v>600&&v<700) return 2;
  if(v>850&&v<950) return 3;
  return 0;
}

ISR(TIMER1_COMPA_vect)  // 16 ggr/sekund cirka
{
  pval = knapp(analogRead(3));
    
  if(pval == 0)
  {
    countNopress++;
    if(countNopress > 1)
      val = 0;    
  }
  else
  {
    if(val != pval)
    {
      val = pval;
      countNopress = 0;      
      doSomething(val);
    }
  }
}

int doSomething(int k)
{
  Serial.println(k); 
}

void loop() 
{
  
}



Nu anropas doSometing() bara 1 gång varje gång vi trycker på en knapp, precis som vi önskar. Programmet accepterar nu bara ett knapptryck om knapparna varit uppsläpta en liten stund (0.1 sek någonting).






Annons
Egen domän, epost & webbsida
Från 120 + 140 = 260 kr per år + moms för Brons -konto med .com -domän.

Bästa sättet att lära sig något, är att 1) ha något att Meka med 2) Meka.

Detsamma gäller förstås internet och webbsidor. Vill du lära dig göra roliga saker, t.ex. en fixa en egen hemsida på en egen domän eller installera en hemma-server på egen domän? Skaffa ett konto på ett billigt hjälpsamt webbhotell, där du kan ställa många dumma frågor till supporten. Välkommen!

Kontrollpanel (Direct Admin), där du kan lägga till epostadresser, installera wordpress för en företagssida eller privat blogg, lägga till subdomäner, tanka upp filer, ändra DNS -pekare och massor med annat. Behöver du hjälp fixa webbsida? Vi hjälper dig. Börjar ditt nuvarande webbhotell bli störande dyrt? Hör av dig, vi kan troligtvis hjälpa dig med flytten.
Karla Hosting AB • https://karlahosting.se