To sensor et kort, DS3231 og pir

Dav i gruppen

Jeg kunne tænke mig at lave en Sketh med to sensor, ur DS3231 og pir(bevægelsføler)

Jeg har begge som, kan det kaldes for løse altså på to kort.

Jeg er bare ikke lige hvordan det skal gøres??

Jeg har prøvet med et par andre og det virkede ikke.

Som jeg forstår det skal der laves noget der hedder "State Motor" jeg har fulgt "Multi-tasking the Arduino - Part 1", men syntes ikke rigtig jeg kan komme igan. >:(

Nogen der har en rigtig god ide til hvordan jeg kommer i gang med dette arbejde.

Hi
Ivan

Hej Ivan,

Ja, jeg ved heller ikke hvad du vil gøre ... det siger din beskrivelse ikke

Og her kan du se det første trin du er nødt til at tage fat på et blank papir og skriv 3 til 6 linjer med hvad der skal ske. (Mine eksempler her er fri fantasi)

  • Check om der er gået 5 minutter siden sidst, blink med grøn LED, med mindre noget af nedenstående er sket.
  • Hvis PIR er ON så tænd rød LED, men ikke hvis sensor A er aktiv.
  • Hvis PIR er OFF og sensor B måler mindre end "20" i 3 minutter så blink med rød LED.

Så forfiner men det.

Udvid sætningerne med lidt flere detaljer om hvad der skal måles, grænseværdier, hvor lang tid er "et blink" osv. Du skal ikke tænke på programmeringen endnu. Du kan dog tænk på hvordan sensoren giver data og hvordan man får et "rent" signal. (Her tænker jeg på f.eks. kontakt bounce, analog jitter/spikes. Den slags kan løses enten i software eller med mere elektronik.)

Du bliver ved med pøse lidt detaljer på i et par omgange. Der kan godt være nogle "Pile" mellem sætningerne, som f.eks. at udførsel af linje 2 skal "registreres" af linje 1.

Hvis det bliver for rodet så begynd forfra - dit første sæt var ikke en god beskrivelse af rimeligt selvstændige begivnheder.

--
Når du har den slags design færdig kan vi begynde lave det maskin venligt. Med lidt held er hver linje et lille selvstændigt modul. Skriv i detalje (uden at tænke på C-syntaksen) hvordan trinet udføres. Sådan her er "halvvejs" i detaljering.

Læs PIR værdi analog (3 gange med gennemsnit)
Hvis værdi > forrige værdi+20 kald det "ON".
Læs Sensor A.
Hvis Pir-ON og SensorA-On tænd Rød Led, start timer.
Hvis timer > 700 msec sluk Rød LED

Nu kan man begynde at skrive lidt kode. Et modul for hver linje. Et modul må ikke blive "hængende", det må ikke sidde i en løkke med at vente på en kontakt åbner/lukker. Hvis kontakten er forkert, så gør ikke aktionen (tænde LED). Om lidt kommer du tilbage til samme modul og kan gentage testen. delay() er netop sådan en løkke der venter. Derfor må den ikke bruges. Det er det som Blink-LED-without-delay forsøger demonstrere. Se også Arduino Playground - HomePage

For hvert modul vil der være nogle ting der skal gemmes til næste gang man kommer til modulet (timers, f.eks) eller en variabel som læses af et andet modul. De skal have en "start" tilstand eller steup, og det noterer du skal gøres i setup().

Din loop() kode skal helst kun af kalde alle 4-6 moduler på rad og række. Ingen if/then eller andet. Logikken for at holde styr på timers og blink er jo inde i hvert modul, og de antaglien få interaktioner gøres ved der skrives i de fælles variabler.

--
Ja, alt meget nemt for mig at skrive. Jeg har gjort det i 40+ år med diverse afstikker og pauser. Det vigtige er at du ikke tænker kode og C-syntaks før du har beskrevet opgaven; først grovt, og så trinvis forfine det. Hvis du tænker "her skal sensoren læses i en for-løkke... nej en while-løkke" inden du er enig med dig selv om hvordan den passer ind i helheds billedet, så bliver det spaghetti-kode der kun virker sommetider.

Der er nogle der søger/googler efter kode der "næsten" gør det de vil og så hamrer de på det med cut-n-paste indtil de kompilerer. Somme tider virker det men de ved ikke hvorfor, og derfor er det meget frustrende at arbejde videre med det.

--
Det der State motor er et af mange "skabeloner" man kan bruge i kodning. Hvis din detalje beskrivelse er detaljeret nok, så ender du nok op med en "state motor" uden at vide at det er det du har. Der er ikke så meget magi i det :wink: Hvis man ved det er en state motor så kan man tilrette udseendet af koden så det fremgår mere tydeligt.

Forsat god lyst til dit projekt!

Hej Msqure

Ok, det var noget at en ordenlig forklaring, jeg prøver at lave en beskrivelse af hvad det er jeg vil.
Jeg var lige for hurtig det er DS3231 og LM35 og en LCD skærm, jeg skal have til at arbejde sammen.
Det er måske et for stort job til en newbiee like me :astonished: , hvad mener du om det er det for stort et job jeg vil gå i gang med.

Takker for dit indspark

Hi
Ivan

Selvfølgeligt er det et stort projekt hvis du synes det er stort (alt er relativt) ... men man tackler det som man tackler det at spise en elefant. En bid ad gangen.

Du laver et lille program der gør "noget" med din LCD. F.eks. at den viser på LCD'en samme tekst du sender den på Serial. Og kun den.

Så laver du et lille program der kan snakke med din LM35. Kun den. og det indlysende her er at den sender temperaturen til Serial. Sån en gang hver 10. sekund. (Her må du -undtagelsesvis- bruge delay() for at vente 10 sekunder. Her er det tilladt da du kun har een ting at holde styr på)

Og ditto med DS3231 hvor du sender tiden. Her kan du blive lidt mere eventyrlysten og "smage" på tiden fra chippen og lade det afgøre at du kun skriver til Serial én gang hver 6. sekund.

OK, her har du så nu dine bygge klodser. Du skal kun bruge delmængder fra hvert program når du samler det store program. Nu skal du tage stiling til at fordele dine I/O pinde. Uden at lave noget program skal du også sørge for at få alle #include og variabler sat op. Altså noget med et tomt setup() og loop() og bare få det at kompilere.

Du skal lave en samling af alt det der blev lavet i hver setup i de 3 programmer i en fælles setup. (For at holde skidt og kenl hver for sig, kan du vælge at leve en void setup_LCD() og void setup_LM35() osv og bare kalde dem fra den rigtige void setup() )

OG nu er vi næsten der hvor det bliver svært. Jeg har ikke lige nu kigget på kommunikations protokollen for de 3 enheder, så der kan være en udfordring der. Du laver 3 funktioner : do_LCD(), do_Temp() og do_Clock(). Lav dem tomme først og kald alle 3 i loop().

Udvid do_LCD() så den viser indholdet af en streng variabel - en der er defineret global (dvs foran setup()).

Nu vil den løkke køre "for hurtigt". Din LCD vil sandsynligtvis flimre fordi den opdaterer hele tiden. Derfor i do_LCD() (ikke i loop) laver du samme timer konstruktion som vist i den berømte link-without-delay : den sørger for at uanset hvor ofte du kalder do_LCD så laver den kun ændringer hvis der er gået mere et sekund siden sidste ændring.

Udvid din do_temp() så den læser temperaturen og putter streng værdien i det som do_LCD viser

Og så er der uret. Den lægger tiden pænt formatteret i samme variabel - nåh nej, det oveskriver jo temperaturen, så måske skal LCD vise to "strenge" en for hver linje.

Nu ved jeg jo ikke hvad du vil gøre med de her dele : måske er det "bare" (det er jo ikke så "bare") et ur med temperatur; måske skal du ligefrem tænde en lampe/varme/blæser hvis bestemte temperatur og tid betingelser er opfyldt. Det er så den "højeste" niveau af logikken og den kan passende sættes i loop() delen. Så er dit program pænt opdelt i at de "lavere" ting med kommunikere/læse/opdaringsfrekvens ligge i de forskllige do_moduler og formålet med program er tydligere i loop()