Hej.
Håller på och försöker knåpa ihop ett litet larm med arduino. Har kommit till där jag har en magnetswitch till dörren och vill ha en fördröjning på ca 15-20 sekunder så man hinner larma av.

Någon som vet hur man kodar detta för det fungerar ju inte med delay för då går det inte att larma av.
Jag larmar av med en rfid tag.
Vore mycket tacksam för förslag för har nu kört fast totalt plus att jag inte programmerat förut.
 
  • Gilla
D09
  • Laddar…
tommib
Använd millis() som returnerar millisekunder sedan start. Anropa den och lagra värdet när dörren öppnas och kolla sedan en gång per loop om du överskridit tidsgränsen.

if(dörren_öppnad) // Anropa bara en gång, annars startar du om fördröjningen så länge som dörren är öppen...
timer1 = millis()+15000

och sen sist i loopen

if(timer1<millis())
->LARM


Obs att det är pseudokod, inget du kan klippa och klistra. En annan lösning är att kolla in de många timerbibliotek som finns.
 
  • Gilla
Danne3
  • Laddar…
tommib skrev:
if(dörren_öppnad) // Anropa bara en gång, annars startar du om fördröjningen så länge som dörren är öppen...
timer1 = millis()+15000

och sen sist i loopen

if(timer1<millis())
->LARM
Jag har förvisso ingen erfarenhet av Arduino, men jag misstänker att det med ovanstående pseudokod finns risk för att larmet går direkt när man öppnar dörren, om det sker strax innan systemets millisekundsräknare överflödar.

Ett enkelt sätt att undvika det är att se till att timer1 har samma längd som millis() och vid varje testtillfälle beräkna skillnaden:

if(dörren_öppnad) //bara vid förändring av dörrens status
timer1 = millis();

....

if( (millis() - timer1) >= 15000)
->LARM
 
  • Gilla
Danne3
  • Laddar…
tommib
Jo, det är riktigt, det gör den. Beroende lite på hur man har typat variablerna blir det dock knas med din variant också, t.ex. om man av någon anledning använder signed. Internt är millis en unsigned long och wrappar ca var 50e dag. Risken föreligger bara när man öppnar dörren just under de femton sista sekunderna innan det slår över. Jag tyckte det var ett acceptabelt fel med tanke på kvaliteten på en sån här larmlösning. Det vore bättre att använda en timer och en interrupt så slipper man hela problemet.
 
  • Gilla
Danne3 och 1 till
  • Laddar…
Tack ska läsa på lite om timer och millis
 
tommib skrev:
...wrappar ca var 50e dag. Risken föreligger bara när man öppnar dörren just under de femton sista sekunderna innan det slår över.
Och det är ju just den typen av buggar som man absolut inte vill behöva leta efter..😊
Att blanda in interrupt kan ju också leda till liknande scenarion ifall man inte har koll på atomära operationer eller tillfälliga avstängningar av interrupts.
 
  • Gilla
Danne3 och 2 till
  • Laddar…
Får inte till det, fick en timer att fungera som körs var 20e sekund men problemet blir då att öppnar jag dörren när timern har 5 sekunder kvar så tjuter det.
Vore mycket tacksam för lite mer vägledning.
Så här ser koden ut där den kollar om dörren är öppen.

if (digitalRead(switchPin) == LOW && antiON == 1 && allarm == 0){
lcd.clear();
lcd.print("ALARM!!");
allarm == 1
 
Inte ska du väl behöva tillsatser nu när du har din Arduino. Läs på lite och Googla så hittar du mängder kring det mesta man kan tänka sig göra med en sån. När jag sökte nu efter något som lite förklarar det tommib och Polyene var inne på så tog det max 30 s att hitta ett ganska vettigt stycke som både förklara problematiken lite och visar olika lösningar.

Arduino timers.
 
  • Gilla
Danne3 och 1 till
  • Laddar…
Tyvärr är jag nog för dum, har suttit i flera dagar och det enda jag får till är en timer som börjar om hela tiden. Jag vill ju timern ska starta när dörren öppnas och räkna ner sen kolla igen om larmet på och isåfall larma
 
tommib
Du är inte dum (eller vad vet jag, men vi utgår från att du inte är det), bara ovan med programmering.

Testa följande. Det saknas nog en del, BH kommentarsruta är inte direkt en optimal kodeditor. Men du kanske kan lista ut det med hjälp av koden nedan....

I setup:

unsigned long t1 = 0;
unsigned long t2 = 0;
boolean door_open = false;
boolean triggered = false;
boolean alarm = false;

//.....allt annat relaterat till din setup


I loop, precis i början:

t1 = millis();

// kolla om dörren är öppen, om den är det sätt door_open = true;

// Sätt bara t2 om dörren öppnas för första gången.
if(door_open && !triggered){
t2 = t1;
triggered = true;
}

// Här letar du efter din RFID-tagg. Spelar ingen roll egentligen var exakt i koden, men någonstans i loop.
// Om rfid-taggen hittas sätt t2=0 och triggered=false;


if(t2+15000 < t1 && triggered){
alarm = true;
}


EDIT: Notera att jag använde polyenes metod, den är bättre :)
 
  • Gilla
Polyene och 1 till
  • Laddar…
Tack tommib ska se imorrn om jag förstår bättre :)
 
tommib: Bra med ett konkret exempel! Dock så lider det fortfarande av 50-dagarsproblemet i och med att "t2 + 15000" kan överflöda. Ändra den sista if-satsen till "if( (t1 - t2) > 15000 && triggered)" så löser det sig!
 
Redigerat:
  • Gilla
Danne3 och 1 till
  • Laddar…
Jag skulle vilja tillägga att det kan vara klokt, i synnerhet om man inte är så van vid programmering, att döpa sina variabler lite mera lättförståeligt.

#define ALARM_DELAY 15000

t1 = time_now
t2 = time_door_opened
osv

Blir betydligt enklare när du går tillbaka till koden om ett halvår, eller två dagar :) , om allt har lätttolkade namn.
 
Redigerat:
  • Gilla
osiris och 3 till
  • Laddar…
tommib
Jahapp.... glömde ändra där, la bara till editen :surprised:

Dock så kan din variant också att få problem men åt andra hållet inser jag nu. I fallet 10 sek före rollover så kommer t1 bli ett högt tal vilket t2 också kommer få. När millis() sedan anropas igen och går över så kommer t1 vara låg. Detta kommer ge att t1-t2 kommer bli negativ (eller väldigt stor). Jag vet faktiskt inte exakt vad som händer, om arduino-IDE castar om till signed eller om det blir rätt ändå och det värdet överstiger 15k som det borde göra. Detta skulle då göra att larmet inte triggar alls...
 
  • Gilla
Danne3
  • Laddar…
Vi vill skicka notiser för ämnen du bevakar och händelser som berör dig.