
Får väl då i stället ta itu med PROGRAMMET, en ÖVERSIKT.
Till att börja med får jag ursäkta för att programmet (som jag bifogar ett senare inlägg) med förklaringar är skrivet på svengelska.
Jag gjorde mina första program för en god bit över 40 år sedan, och då var det bara engelska som gällde. Som värst skrev vi programmen direkt i maskinkod (!), men oftast på något mellannivå-språk (Assembler, PL/I, PL/M, eller dylikt) på en Teletype-terminal som stansade en hålremsa, vilken sedan lästes in i minidatorn. Då var det 7-bitar ASCII som gällde, och programmen förstod inte Å, Ä och Ö, så de kunde inte användas.
I en terminal eller på en skrivare kunde man substituera tecknen [, \ och ] med skandinaviska tecken, men i programmen hade de en fördefinierad betydelse, så därför kunde de inte användas där.
Dessutom hade datorerna inte så mycket minne heller - vår "största" dator hade 20 kbyte (!!!) centralminne, så man skulle inte uppta det med onödiga förklaringar eller dylikt.
Trots det lyckades vi faktiskt klämma in avancerade FEM-analyser i den maskinen. Programmet upptog hela programminnet så när som på en byte. Det var bara en kille vars initialer kunde skrivas som en HEX-kod, men det gick inte vi andra med på, så den sista byten förblev oanvänd

Jämfört med det är ju en Arduino med 32 kbyte programminne rena lyxen!
Nåja, nu var det ju inte meningen att förfalla i sentimentala memoarer, men det är nu en bortförklaring till språket (det går inte att lära en [så här] gammal hund nya tricks!), samt att beskrivningarna i programmet säkert är bristfälliga och ibland t.o.m. kan vara svårförståeliga.
Vidare är det skäl att nämna, att jag definitivt inte är programmerare. Det var aldrig min inriktning heller - det kom liksom på sidan om. Jag har nog programmerat en hel del sedan dess, men bara för husbehov.
Flere saker kunde säkert göras bättre. Strukturer och flöden och namnen på rutiner och variabler kan synas konstiga och inkonsekventa - och det är de säkert också. Det är saker som det inte finns förklaringar på.
Jag har sett många eleganta programlösningar här på forumet, så jag vet att det finns skickliga programmerare här. Jag tar gärna emot både råd och förslag, det är både lärorikt och uppfriskande att se på något problem på ett nytt sätt. Därför: "Keep them coming!".
Så tillbaka till huvudspåret.
Först en kort redogörelse hur de olika minnena används:
Det finns endast en Joystick med vilken man konfigurerar systemet. Det betyder förstås menyer, menyer betyder mycket text, mycket text tar upp minne, och - tvärt emot min jämförelse med 70-talet - det har inte AVR328:n heller för mycket av.
Menytexterna skall vara enkla att komma åt så därför har jag placerat dom i Arduinons interna EEPROM där de upptar 512 byte (av 1024).
Lösningen möjliggör upp till 64 textsträngar med en sammanlagd längd av 382 byte, inklusive terminator (0x00) efter varje text. 128 byte upptas av vektorerna (till texterna) och två byte är reserverade för systemets pin-kod:
0x000 - 0x07F : Vektorer (64x word)
0x080 - 0x1FD : Textsträngar
0x1FE - 0x1FF : Pin-kod
Fotnot: Det finns en rutin som skriver ut "texsträng nr n" på displayen. "n" syftar till vektorn och vektorn pekar på början av den textsträng som skall skrivas ut. Varje text slutar med en s.k. null-terminator (0x00).
En liten nackdel är förstås, att det interna EEPROMet måste programmeras först m.h.a. ett skilt program, före man laddar ner själva bevattningssystemprogrammet. Bevattningsprogrammet alternerar inte på något sätt textsträngarna.
Att göra upp textsträngarna kan också vara omständigt. Därför har jag gjort upp ett Excel/LibreCalc-"program" där man bara matar in de textsträngar man vill ha, och det allokerar både vektor och minne och genererar färdig kod för EEPROM-laddningsprogrammet. Det är bara att föra över med Copy-Paste.
I det tabellprogrammet sätter man också pin-koden intialt, men den kan man sedan ändra på i programmet. Det finns ingen "factory default" för pin-koden. Ifall man kompilerat programmet för att använda pin-kod och man glömt koden, finns det en speciell input man skall ställa för att göra "pin code override".
En central målsättning var, att systemet skall klara en omstart (reset) utan att tappa tråden. Det betyder, att konfiguration och status måste sparas i icke-flyktigt minne och att programmet efter en reset först läser in dessa värden och på basen av det "hittar tillbaka" till den punkten där avbrottet kom.
Detta med att hitta tillbaka måste förstås på rätt sätt. Ifall systemet falerade onsdag morgon och startar upp igen först på lördag eftermiddag (ex. strömavbrott), så är det inte meningen, att alla bevattningar och statusrapporter mellan onsdag och lördag skall köras i en rad för att komma ifatt.
"Hitta tillbaka" betyder alltså, att:
- Konfigurationerna för zoner och lucka skall finnas kvar
- Ifall systemet var mitt i en bevattningsfas skall den slutföras
- Antalet omstarter loggas, men ifall bevattningar uteblivit under avbrottet, ett meddelande därom skicks till servern
Då jag samtidigt ville, att om Arduinon t.ex. pajade och jag ersatte den med en annan, skulle också den hitta rätt, utan att jag behövde mata in alla parametrar på nytt.
Därmed var det klart, att eftersom RTC-modulen också har ett EEPROM på sig, är det det som skall användas för:
- Inställningar och parametrar (zoner, växthus, system)
- Diverse statusinformation, flaggor, etc.
- Logg
mm.
Fotnot 2: I själva verket brukar jag uppdatera programmet så, att jag laddar ner den nya versionen på en annan Arduino Nano och sedan går jag ut i växthuset och swappar (utan att ens koppla ifrån strömmen, fast det rekommenderar jag ju inte åt andra...

Igår tappade jag den ena Arduinon i vattentunnan

...det där med tunnan inomhus...
Det externa EEPROMet är 4 kbyte (32 kbit) och där finns det gott om ledigt utrymme ännu. För närvarande använder systemet i princip endast 0x0000 till 0x01FF men inte ens då är alla platser allokerade. Vi får återkomma till allokeringen senare.
En annan utmaning var, att programmet skall sköta många uppgifter parallellt - bevattning, rapportering, självövervakning, interaktion med en eventuell användare, mm. För att klara detta elegant hade det behövts ett realtids-operativsystem, då hade man kunnat köra dom som separate processer och datautbyte mellan dom.
Men det har nu Arduinon inte och det skulle knappast rymmas i det minnet heller. Så det gäller att få ihop det på annat sätt.
Det syns i hur uppgifterna och rutinerna är uppdelade.
För närvarande upptar programmet 78% av minnet och då är långt ifrån allt implementerat ännu. Den andra kritiska faktorn, nämligen SRAM-minnets användning, är, att 33% upptas av globala variabler. Många av dessa kommer från biblioteksrutiner vilka jag inte velat tumma på, eftersom man då får göra det varje gång biblioteket updateras också.
Jag har inte ens försökt förstå var den kritiska gränsen går, d.v.s. hur mycket som vid något tillfälle maximalt upptas av dynamiska variabler och subrutin-call, men jag vill nog inte höja på det där värdet
Är det nån som har en uppfattning om hur man kan försöka ta reda på den saken? [utan en riktigt bra simulator]
Till slut en översikt över "loopen": Programmet loopar alltså igenom:
run30()
En rutin, som kontinuerligt pollar klockan och miljöparametrar för att visa på displayen.
Ifall klockan är en jämn halvtimme kallar den på andra rutiner för loggning, starta bevattning, mm.
tempShow()
Uppdaterar displayen med de värden run30() pollat.
Test: Joystick klickad?
Det betyder användarinteraktion och då öppnas huvudmenyn med rutinen Menu10().
Test: phase > 0
Denna flagga sätts tidigare i loopen antingen i run30() (programmerad bevattning, [1..3]) eller av användaren (manuell bevattning [4])
och då startas själva bevattningen i rutinen watering(). Flaggan nollas efter utförd bevattning.