Sida 1 av 1

Problem med trckknapp-detektering i arduino

Postat: 4 oktober 2017, 23:13:31
av andnord
Hej!

Jag håller på med ett litet larm med en pirsensor för arduino och den fungerar bra i stort sett. Det är dock lite småproblem med knappdetektering.

Jag har programmerat den så att den larmar (d.v.s blinkar med en röd lysdiod och tjuter med en passiv pulserande summer) tills man trycker på en grön tryckknapp. När detta utförs återställs larmet men man ska bara behöva trycka en gång. Jag måste hålla in knappen för att det ska fungera i nuläget så jag sitter och funderar på vad jag eventuellt kan ha gjort fel.

Har någon nåt förslag?

20171004_223409.jpg

Kod: Markera allt

/* Ett litet larm med rörelsedetektor
*/

const int ledPin          =  10;      //Röd larmande lysdiod på digitalport 10
const int siren           =  13;       //En passiv summer för Arduino på digitalport 13
const int ButtonPin       =  11;    //Grön tryckknapp för att återställa larm på digitalport 11
const int PirDetektor     =  12;    //En PirSensor för Arduino på digitalport 12
const int ledKalPin       =  9;      //Grön lysdiod som lyser när kalibreringen av PirDetektorn är slutförd

int lysdiodStat = LOW;             // lysdiodStat used to set the LED
int alarmStat = LOW;               //Bestämmer statuset på larmet
int KnappStat = LOW;             //Bestämmer status på Återställningsknappen 
int PirStat = LOW;                  //Bestämmer statis på PirSensorn

unsigned long previousMillis = 0;  // will store last time LED was updated

// constants won't change :
long interval = 140;           // interval at which to blink (milliseconds)
int kalTid    = 10;            //Bestämmer kalibreringstid i sek för PirDetektorn 

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(siren, OUTPUT);
  pinMode(PirDetektor, LOW);
  pinMode(ledKalPin, OUTPUT);

  //Kalibrering av PirDetektorn

  for (int i=0; i < kalTid; i++)
  {
    delay(1000);
  }

  digitalWrite(ledKalPin, HIGH); //Tänder den gröna lysdioden för att visa att nu är kalibreringen slutförd och PirDetektorn redo...
}

void loop()
{
  PirStat = digitalRead(PirDetektor); //Läser in status från PirDetektorn
  
  

  if (PirStat == HIGH)
  {
    alarmStat = HIGH; //Aktiverar larmet 
  }

  if (KnappStat == HIGH)
  {
    alarmStat = LOW; //Återställer larmet efter detekterad knapptryckning.
  }

  unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval)
    {
      // save the last time you blinked the LED
      previousMillis = currentMillis;

      if (alarmStat == HIGH)
      {
        if (digitalRead(ledPin) == LOW)
        {
          digitalWrite(ledPin, HIGH);
          tone(siren, 1000);
          KnappStat = digitalRead(ButtonPin);

        } 
        else
        {
          digitalWrite(ledPin, LOW);
          noTone(siren);
            
        }

  
      }

      else
      {
        digitalWrite(ledPin, LOW); // Stänger av den larmande lysdioden
        noTone(siren);    //Stänger av siŕenen
      
        //Vid återställt larm nollställs även PirDetektorns och återställningsknappens status 
        KnappStat = LOW;  
        PirStat = LOW;
      }
   }
}

Re: Problem med trckknapp-detektering i arduino

Postat: 4 oktober 2017, 23:27:27
av Swech
Försök att separera funktionerna, nu läser du knappen beroende på larm och status på LED

Kör den separat istället

Swech

Re: Problem med trckknapp-detektering i arduino

Postat: 4 oktober 2017, 23:38:23
av andnord
OK, hur menar du då? Ska jag ha en funktion som läser av knappen och en annan som sköter larmet eller hur ska jag göra detta separat?


Försök att separera funktionerna, nu läser du knappen beroende på larm och status på LED

Kör den separat istället

Swech

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 02:03:05
av Glattnos
Varför ligger:

Kod: Markera allt

KnappStat = digitalRead(ButtonPin);
i denna?

Kod: Markera allt

      if (alarmStat == HIGH)
      {
        if (digitalRead(ledPin) == LOW)
        {
          digitalWrite(ledPin, HIGH);
          tone(siren, 1000);
          KnappStat = digitalRead(ButtonPin);
Det är väll bättre om programmet vet Knappens läge hela tiden :)

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 08:28:00
av SeniorLemuren
Felet ligger väl i att du sätter på larmet varje gång huvudloopen körs så länge PirStat == HIGH.
Sätt en variabel t.ex knappOn =true när du trycker in knappen. och kolla den i stället för knappen när larmet skall aktiveras. Sätt knappOn= false när (PirStat != HIGH.

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 14:10:18
av andnord
Ja alltså om PirStat får värder "HIGH" så utlöses larmet. Därefter återställs ju detta värde till "LOW" så fort man trycker in knappen men det är något som inte riktigt klaffar.


SeniorLemuren skrev:Felet ligger väl i att du sätter på larmet varje gång huvudloopen körs så länge PirStat == HIGH.
Sätt en variabel t.ex knappOn =true när du trycker in knappen. och kolla den i stället för knappen när larmet skall aktiveras. Sätt knappOn= false när (PirStat != HIGH.

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 15:45:07
av Swech
det ligger ett tutande på 1 sekund.
du läser inte knappen så länge som tutandet pågår

Swech

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 16:36:14
av SeniorLemuren
andnord skrev:Ja alltså om PirStat får värder "HIGH" så utlöses larmet. Därefter återställs ju detta värde till "LOW" så fort man trycker in knappen men det är något som inte riktigt klaffar.


SeniorLemuren skrev:Felet ligger väl i att du sätter på larmet varje gång huvudloopen körs så länge PirStat == HIGH.
Sätt en variabel t.ex knappOn =true när du trycker in knappen. och kolla den i stället för knappen när larmet skall aktiveras. Sätt knappOn= false när (PirStat != HIGH.
Ja men i nästa varv på loopen så läser du ju in ett nytt värde : PirStat = digitalRead(PirDetektor); //Läser in status från PirDetektorn
och då går ju larmet igång igen direkt och så håller det ju på så länge PirStat == "HIGH".

Här sätter du ju igång larmet varje huvudloop.

Kod: Markera allt

void loop()
{
  PirStat = digitalRead(PirDetektor); //Läser in status från PirDetektorn  

  if (PirStat == HIGH)
  {
    alarmStat = HIGH; //Aktiverar larmet 
  }
Och direkt efter så stänger du av larmet i samma huvudloop när knappen är intryckt. Släpper du knappen så går ju larmet på direkt i nästa varv på loopen

Kod: Markera allt

if (KnappStat == HIGH)
  {
    alarmStat = LOW; //Återställer larmet efter detekterad knapptryckning.
  }
Om du däremot sätter en variabel till true när du trycker in knappen och testar på den i stället för på knappen så kommer larmet inte på så länge variabeln är true. Variabeln sätter du till false när PirStat == "LOW" Variabeln simulerar alltså att knappen är intryckt till nästa larmsituation.

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 20:52:28
av andnord
Jag förstår inte riktigt varför det skulle bli annorlunda då än om jag lägger till en extra variabel. Jag provade dock att göra som du beskrev fast det gjorde ingen större skillnad. Larmet återställs när man trycker på knappen men först efter 2-3sek. Om man håller ner knappen så stannar larmet men släpper man upp knappen innan 2-3sek så fortsätter den larma. Så vill man att återställa måste man vänta denna tid. Förstår inte riktigt vad det är som gör att det tar tid men jag skulle tro att det är något under if-satserna för alarmStat

Jag har annars testat med while-loop där jag har haft KnappStat (LOW) som kriterier när den ska hoppa ur den och PirStat som krierier för att den ska hoppa in i den. Det fungerade inte heller något bättre tyvärr.

I teorin kanske man borde kunna lägga in en paus i början av programmet
med en delay(3000) innan inläsning av PirStat och KnappStat men då är ju nackdelen att det inte funkar om PirSensorn larmar igen innan denna tid.

Kod: Markera allt

bool knappOn  = false;

Kod: Markera allt

PirStat  = digitalRead(PirDetektor);
KnappStat  = digitalRead(ButtonPin);

Kod: Markera allt

if (KnappStat == HIGH)
{
   knappOn = true;
} 

if (KnappStat == LOW)
{
    knappOn = false;
}

if (PirStat == HIGH)
{
    if (knappOn == true)
    {
        alarmStat = LOW;

    }

   else
   {
       alarmStat = HIGH;
   }
}
SeniorLemuren skrev:Om du däremot sätter en variabel till true när du trycker in knappen och testar på den i stället för på knappen så kommer larmet inte på så länge variabeln är true. Variabeln sätter du till false när PirStat == "LOW" Variabeln simulerar alltså att knappen är intryckt till nästa larmsituation

Re: Problem med trckknapp-detektering i arduino

Postat: 5 oktober 2017, 22:40:55
av Glattnos
Har du provat att ta bort Pir-sensorn och bara simulera den med en knapp?

Re: Problem med trckknapp-detektering i arduino

Postat: 6 oktober 2017, 20:44:13
av SeniorLemuren
[quote="andnord"]Jag förstår inte riktigt varför det skulle bli annorlunda då än om jag lägger till en extra variabel. Jag provade dock att göra som du beskrev fast det gjorde ingen större skillnad. Larmet återställs när man trycker på knappen men först efter 2-3sek. Om man håller ner knappen så stannar larmet men släpper man upp knappen innan 2-3sek så fortsätter den larma. Så vill man att återställa måste man vänta denna tid. Förstår inte riktigt vad det är som gör att det tar tid men jag skulle tro att det är något under if-satserna för alarmStat

Jag har annars testat med while-loop där jag har haft KnappStat (LOW) som kriterier när den ska hoppa ur den och PirStat som krierier för att den ska hoppa in i den. Det fungerade inte heller något bättre tyvärr.

I teorin kanske man borde kunna lägga in en paus i början av programmet
med en delay(3000) innan inläsning av PirStat och KnappStat men då är ju nackdelen att det inte funkar om PirSensorn larmar igen innan denna tid.

Kod: Markera allt

bool knappOn  = false;

Kod: Markera allt

PirStat  = digitalRead(PirDetektor);
KnappStat  = digitalRead(ButtonPin);

Kod: Markera allt

if (KnappStat == HIGH)
{
   knappOn = true;
} 

if (KnappStat == LOW)
{
    knappOn = false;
}

if (PirStat == HIGH)
{
    if (knappOn == true)
    {
        alarmStat = LOW;

    }

   else
   {
       alarmStat = HIGH;
   }
}

Kod: Markera allt

if (KnappStat == HIGH)
{
   knappOn = true;
} 

if (KnappStat == LOW)
{
    knappOn = false; //********här blir ju knappOn false så fort du släpper knappen då gör ju knappOn ingen nytta.********************''***
}
Nej det är klart att detta inte funkar du sätter ju knappOn till false så fort du släpper knappen. Det var inte vad jag föreslog. knappOn skall naturligtvis fortsätta att vara true även när knappen har släppts och sättas false först när PirStat inte är HIGH längre.

Re: Problem med trckknapp-detektering i arduino

Postat: 9 oktober 2017, 10:47:05
av andnord
OK men då tror jag att jag förstår lite bättre vad du menade. Det är alltså så att denna pir sensor slår alltså inte direkt av utan den skickar signal till mikroprocessorn i flera sekunder och därför behöver man ha denna knapp-simulator som du beskrev SeniorLemuren och detta provade jag nu och nu funkar den precis som jag vill ha den.

Tack så jättemycket SeniorLemuren och även till ni andra som engagerade er i att hjälpa mig!!

//Andreas

Re: Problem med trckknapp-detektering i arduino

Postat: 9 oktober 2017, 10:54:03
av Jonaz
Du kan ändra hur länge du vill att pirsensorn skall vara hög, med den ena potensiometren som sitter där, den andra är till för känsligheten. Kommer inte ihåg hur kort minsta tid är dock.

Re: Problem med trckknapp-detektering i arduino

Postat: 9 oktober 2017, 11:43:46
av Icecap
PIR-sensorns ON-tid bör ju vara rimligen likgiltig så länge µC'n detekterar en aktivering.

Men ja, det "ska" fungera så att när PIR-sensorn är inaktiv ska "det är kvitterat"-variabeln vara inaktiv.
Den aktiveras så att om man trycker på knappen ska den aktiveras.

Larmet ska låta om PIR-sensorn har varit aktiv OCH kvitterings-variabeln är inaktiv.

Det är alltid bra att skriva ner hur saker och ting ska fungera då många funktioner faktisk ska tänkas igenom.

Re: Problem med trckknapp-detektering i arduino

Postat: 9 oktober 2017, 13:58:21
av andnord
Jaha kan man? Det visste jag ej men jag gör nu att det finns två st potensimetrar som man kan ställa in med en skruvmejsel. Tack för tipset Jonaz!!
Jonaz skrev:Du kan ändra hur länge du vill att pirsensorn skall vara hög, med den ena potensiometren som sitter där, den andra är till för känsligheten. Kommer inte ihåg hur kort minsta tid är dock.