Ardu-Aquarium Controller v. 3.3.1

eccomi qua penso di aver finito almeno la scheda relè, ho cercato di farlla il più piccola possibile,ho aggiunto un connettore a due vie per la 220 (230VAC) e qualche piccola modifica , mancherebbe solo di finire di saldare alcune cosette ma penso che in generale dovrebbe essere tutto ok. Per quanto riguarda i pulsanti ancora non sono riuscito a capire il perchè funzioni bene solo il pulsante ESC e gli altri funzionano a tratti a furia di premerli svariate volte e quando funzionano fanno come gli pare. un altra cosa ancora non sono riuscito a capire il sensore di temperatura come collegarllo ma vediamo un pò, farò prove sopra a prove e ancora per il PH come funziona? scusate tutte queste domande e veramente sei grande Riccardo e lo siete tutti provo a mettere qualche foto ma per i bottoni non so se riuscirete a capirci qualcosa ma ci spero

grazie a tutti simone

scusatemi non riesco a caricare le foto mi da error

simon77blitz:
un altra cosa ancora non sono riuscito a capire il sensore di temperatura come collegarllo ma vediamo un pò, farò prove sopra a prove e

Io nn sono assolutamente un esperto, però il sensore di temperatura io lo faccio funzionare così (l’ho estratto da una pagina internet per avere un manualino a portata di mano)

Appunti DS1820.pdf (121 KB)

Ciao a tutti,
oggi pubblico i risultati, a mio avviso, di un bel lavoro di revisione di tutto lo sketch, che ha rivoluzionato i menù, l’uso delle variabili al suo interno ed a cui sono state aggiunte un paio di funzionalità in più per la gestione delle luci.
Cominciando dalla revisione dello sketch, per chi vorrà perdere qualche minuto a guardarselo, grazie agli insegnamenti e le idee di “Leouz”, abbiamo completamente abbandonato l’uso dei puntatori passati alle procedure grazie all’adozione di una struct contenente tutte le variabili utili alla gestione delle linee luci, questo ha permesso di richiamare tutte le procedure di gestione ed acquisizione dati della plaffoniera, semplicemente passando l’indice del vettore della struct corrispondente, siamo passati poi all’uso dei menù a scorrimento ed infine è stata eliminata la libreria dell’RTC la “DS1307”, ed è statoa migliorata la funzione statoluci che permette in caso di mancanza di corrente o di modifica dei dati della plafoniera di far ripartire le luci sempre dal punto giusto, tutto ciò è stato fatto per risparmiare più flash possibile ed avere spazio per le future funzioni, c’è ancora molto da fare, ma un po’ alla volta ci si arriva.
E’ stato inserito anche un range di +/- 1,5°, di temperatura al di fuori del quale, scatta un allarme sonoro disattivabile premendo il tasto ESC, ed in più nella schermata principale la temperatura lampeggia.
Abbiamo poi aggiunto la possibilità di impostare il modo di funzionamento delle linee:

In pratica ora è possibile accendere o spengere le luci in modo manuale, oppure lasciarle funzionare in modalità automatica con i fotoperiodi impostati, in caso di accensione o spegnimento manuale, entrambe le azioni avvengono in modo graduale (circa 30” in caso di luminosità impostata al massimo) per non disorientare/spanventare gli amati pesciolini.
Inoltre ora è possibile, qualunque sia la modalità di funzionamento delle linee, impostare la luminosità massima delle singole linee agendo sul numero di rampe del fading.

In InfoLuci ora oltre allo stato di funzionamento delle linee se sono on o off e la percentuale di fading al momento, viene anche visualizzata la modalità di funzionamento impostata: “A” per automatica “M” per manuale, la percentuale che viene visualizzata, esprime la luminosità della linea in relazione a quella massima impostata per la stessa.

Mi viene da dire che la parte gestione luci ora è completa di tutte le funzionalità necessarie ad un acquariofilo, semmai ulteriori migliorie del software, ma se qualcuno avesse suggerimenti ben vengano.
Sembrerebbe per il momento che non ci siano errori e lo sketch viene compilato senza errori anche con IDE 1.0.5 anzi con quest’ultimo lo sketch compilato è pure leggermente più piccolo di poco ma lo è.

Abbiamo anche migliorato in precisione l’esecuzione dei fading, niente di che, ma almeno sapete tutto ciò che è stato fatto.

Come sempre, in allegato a questo post l’ultima versione dello sketch e nel 4° post iniziale le spegazioni più dettagliate, ed anche lì lo sketch aggiornato.
A breve riprenderò in mano anche il discorso dei sensori di livello per l’implemetazione della funzione di osmoregolazione e per schedulare i cambi automatici dell’acqua, cose messe momentaneamente da parte perché era in corso la revisione che ho presentato oggi. (troppa carne sul fuoco :sweat_smile:)

acquarium_controller_v_3.ino (43.8 KB)

Spettacolare. :grin:

se al pusto delle freccie su/giiu. metti un potenziometetro infinito, vedrai che scorrere i menù e i valori sarà molto più comodo e immediato. potresti metterlo come integrazione alla pulsantiera :)

PaoloP: Spettacolare. :grin:

Grazie PaoloP... Quando te la fai l'acquario??? ]:D

lesto: se al pusto delle freccie su/giiu. metti un potenziometetro infinito, vedrai che scorrere i menù e i valori sarà molto più comodo e immediato. potresti metterlo come integrazione alla pulsantiera :)

Ci penso, l'idea mi solletica, ma credo che aspetterò di aver finito tutte le funzioni prima di aggiungere altro codice... Attualmente lo sketch compilato è a 22,6K e considerando che effettivi sono disponibili 28k teneto conto dei 4k del bootloader capisci che sto un pò con i byte/acqua alla gola... :cold_sweat: Grazie per il suggerimento ad ogni modo.

Ciao a tutti Riccardo

riciweb: Quando te la fai l'acquario??? ]:D

Si.. si... mi manca solo quello in casa!! :astonished:

ma scusate con questo sistema l'acquario diventa praticamente indipendente? se no cosa manca? se non erro bisogna gestire la temperatura, l'ossigenazione, il ricircolo dell'acqua, la salinazione, il rilascio del cibo... poi?

edit: le luci

come 4k di bootloader, di che Arduino stai parlando?

Quoto.
Solo sull’Arduino MEGA il bootloader occupa 4 kB, sulla vecchia 2009 ne occupava 2 mentre sulla UNO ne occupa solo 0,5.

lesto: ma scusate con questo sistema l'acquario diventa praticamente indipendente? se no cosa manca? se non erro bisogna gestire la temperatura, l'ossigenazione, il ricircolo dell'acqua, la salinazione, il rilascio del cibo... poi?

edit: le luci

Questo progetto, nella mia testa ha diversi scopi, il primo in assoluto è rendere la gestione di un acquario il più possibile semplice e facile, premesso ciò, qualunque acquariofilo di esperienza ti può dire che i parametri da tenere sotto controllo in acquario e le cose che è possibile automatizzare, sono innumerevoli, di fatto in effetti gli acquari che richiedo la maggior competenza, il maggior numero di cose da controllare ed automatizzare, sono gli acquari marini, ma non è a tanto che questo progetto vuole arrivare, di fatto alla fine del percorso, questo sara un controller per un acquario base o se vuoi un "Hello world" dell'automazione degli acquari", quindi arrivati al controllo completo della plafoniera, del ph, della conducibilità e all'automazione dei cambi dell'acqua ecco che l'acquariofilo avrà la vita molto ma molto più semplice. Cio non toglie che poi chiunque potra prenderlo e personalizzarlo a suo piacere, ad esempio un'altro bel controllo da fare sarebbe sulla portata del ritorno in acqua dal filtro per monitorare lo stato di intasamento delllo stesso e manutenzionarlo solo se necessario... potrei andare avanti decine di pagine ad elencarti cose che si possono fare in un acquario...

[quote author=Michele Menniti link=topic=141419.msg1264344#msg1264344 date=1370266332] come 4k di bootloader, di che Arduino stai parlando? [/quote]

leo72: [quote author=Michele Menniti link=topic=141419.msg1264344#msg1264344 date=1370266332] come 4k di bootloader, di che Arduino stai parlando?

Quoto. Solo sull'Arduino MEGA il bootloader occupa 4 kB, sulla vecchia 2009 ne occupava 2 mentre sulla UNO ne occupa solo 0,5. [/quote]

Devo sempre scrivere qualche Riccardata, ma in questo caso sono contento di averla scritta così grazie a voi ho corretto un mia convinzione sbagliata :blush:, o mi è rimasta in testa la reference del Leonardo o non so che dire, in ogni caso è un vero sollievo scoprire che il bootloader sulla UNO è 0,5k scusate maaaa doppio wau carpiato con avvitamentooooooo XD XD XD XD Pensavo di essere messo maluccio, non che ora abbia da scialare, ma va molto meglio!!!

Scusatemi :blush:

Riccardo

Sì, anche la Leonardo ha un bootloader da 4 kB.

Chiedo scusa :~, ma nel revisionare lo sketch, mi sono sfuggiti alcuni errorini (non che non ce ne siano altri ma questi erano scandalosi), quindi riposto il file depurato dal buon “Leouz” anche da alcuni while bloccanti.
Con l’occasione ringrazio anche “danidiscus”, “Dandovino” ed a breve anche “cmarcello”, che sono sempre lì pronti a testare le mie cialtronate… :grin:

PS: Ho sostituito i file anche nei post precedenti, scusate ancora :blush:.

acquarium_controller_v_3.ino (43.8 KB)

leo72: [quote author=Michele Menniti link=topic=141419.msg1264344#msg1264344 date=1370266332] come 4k di bootloader, di che Arduino stai parlando?

Quoto. Solo sull'Arduino MEGA il bootloader occupa 4 kB, sulla vecchia 2009 ne occupava 2 mentre sulla UNO ne occupa solo 0,5. [/quote] appunto e la MEGA avrebbe 128 o 256k di memoria.... quindi quei 4k diverrebbero ininfluenti ;)

riciweb: PS: Ho sostituito i file anche nei post precedenti, scusate ancora :blush:.

l'mportante è che aggiorni la versione nel primo post, è lì che la magior parte della gente andrà a cercare ps. ora ci butto un occhio :)

edit: uhmm il codicemi pare buono, non ho trovato cose ottimizzabili al volo. Do qualche consiglio, liberi di fare ciò che volete: 1. formattate meglio il codice 2. dividete il codice in vari file, meglio se uno per sensore. 3. il main rimane come semplice logica pura, che legge i dati da un'array di strutture (in questo modo lastruttura può essere "alimentata" da eeeprom, SD, seriale, LCD+tastierino... insomma qualsiasi cosa) 4. la Wire, in caso di errore, è bloccante. tempo fa la riscrissi in modo non bloccante, ma in rete ce ne sono varie implementazioni già pesantemente testate 5. riducete al minimo le tipologie differenti di standard, per occupare meno spazio e avere meno codice possibilimente in errore. Io starei su sensori i2c. un altro test è staccare "al volo" i componenti, vedere se il tutto supporta il problema, riattaccarli, e vedere se riparte. Sono casi rari disturbi elettromagentici così forti, ma considerado che il vostro progetto è fatto per restare acceso 24h su 24h per 365gg all'anno... 6. attenzione agli overfglow dei timer, anche della millis()

per esempio riga 129 (dallealtre parti sembrerebbe ok):

if (ArrayVariabiliTasti[Indice].ValoreTasto == true && (((millis() >= (ArrayVariabiliTasti[Indice].TempoTasto + 250))) || ((millis() >= (ArrayVariabiliTasti[Indice].TempoTasto + 10)) && ArrayVariabiliTasti[Indice].TastoPremuto == false)))

andrà in errore all'overflow, con imprevedibili risltati sistemala con

if (ArrayVariabiliTasti[Indice].ValoreTasto == true && 
    (
        millis()-ArrayVariabiliTasti[Indice].TempoTasto >= 250
    || 
        (
            millis()-ArrayVariabiliTasti[Indice].TempoTasto >= 10 
            && ArrayVariabiliTasti[Indice].TastoPremuto == false
        )
    )
)
  1. per la gestione plafo, non è più semplice creare una funzione lineare (y = m*x+q) con valori settabili? dove x è il numero di minuti a partire dalla data di accensione/spegnimento, e y il valore delle luci. Trovare m e q è semplice sopratutto considerando che molto probabilmente avrete sempre q=0.(q è il valore minimo delle luci), in questo modo conservate la data di inizio, magari in secondi dal 1970 (timestamp, che spesso gli RTC calconano tranquillamente), che quindi occupa solo 4 byte (chiamiamola S), e 2 byte (un intero usigned è sufficiente per 65536 secondi, pari a 18 ore) per memorizzare la durata del fading in secondi (chiamiamola D), più un byte per valore fading iniziale a S e valore di fading finale a D, che poi il priomo byte si può risparmiare essendo il vecchio valore di D: infatti il fading è un array ciclico. quindi a partire da S avrete X=0 e y= valore attuale delle luci (accese o spente), e a S+D avrete x = D e y= valore finale delle luci
  2. al posto di controllare ad ogni ciclo l'RTC, potete impostarlo come "sveglia". Potreste fare che ogni azione da eseguire è shedulata in un apposita struttura con timestamp di esecuzione e comando/funzione da richiamare. In questo modo, viene semplice calcolare il numero di secondi per eseguire la prossima operazione, impostare la sveglia sull'RTC, e mandare il micro "a nanna". ovvio che il pin di risveglio sarà collegato anche alla tastiera (magari però su un pin diverso, non so se si può ascoltare più pin). Così risparmiate un sacco di batteria, e analizzando lo scheduler vi accorgete se qualche istruzione và "fuori posto"!

magari butto giù qualcosa io, ma non avendo un RTC dovrete darmi supporto.

complimenti per il progetto :)

molto bello!! tempo e soldi permettendo... proverò a replicarlo così da implementare/rimpiazzare quello che ho ora per gestire, sempre con arduino, i led dell'acquario :)

ho alcune domande:

  1. ho trovato su ebay le sonde di temperatura .. e costano circa la metà di quelle che ho trovato negli shop più rinomati; dite che son buone lo stesso?

  2. tutti gli integrati ecc ecc .. da dove li hai presi? ad es. il PCF8574AP non lo trovo da nessuna parte ....

grazie

ps. pensi sia sviluppabile con touchscreen così da eliminare i tasti fisici? :) tipo questo per intenderci: http://www.robot-italy.com/it/itdb02-2-4e-2-4-tft-lcd.html

Se mi permettete... state consumando un sacco di RAM (al momento il consumo statico è di 1391 byte): perché non mettete le stringhe stampate sull'LCD dentro alla funzione F()? Esempio:

lcd.print("IMP. FOTOPERIODO L");

diventa

lcd.print(F("IMP. FOTOPERIODO L"));

lesto: l'mportante è che aggiorni la versione nel primo post, è lì che la magior parte della gente andrà a cercare ps. ora ci butto un occhio :)

Già fatto, ma grazie per avermelo ricordato ;)

lesto: uhmm il codicemi pare buono, non ho trovato cose ottimizzabili al volo. Do qualche consiglio, liberi di fare ciò che volete: 1. formattate meglio il codice 2. dividete il codice in vari file, meglio se uno per sensore. 3. il main rimane come semplice logica pura, che legge i dati da un'array di strutture (in questo modo lastruttura può essere "alimentata" da eeeprom, SD, seriale, LCD+tastierino... insomma qualsiasi cosa)

1) Hai ragione, ma la formattazione quando si usa un’editor esterno è abbastanza ostica ed in uno sketch così lungo l’IDE attuale di Arduino complica la vita, stiamo usando Notepad++, che però usa tabulazioni e spazi in modo diverso dall’IDE ufficiale, aggiungi che ci mettiamo le mani in più persone ed ecco che la formattazione salta, ma mi impegnerò per migliorarla o almeno uniformarla. 2) So che è possibile farlo, ma non so come si fa, imparerò anche questo perché effettivamente sarebbe meglio. 3) Questa sarebbe la conseguenza della divisione in file dello sketch? Non sarebbe male!

lesto: 4. la Wire, in caso di errore, è bloccante. tempo fa la riscrissi in modo non bloccante, ma in rete ce ne sono varie implementazioni già pesantemente testate 5. riducete al minimo le tipologie differenti di standard, per occupare meno spazio e avere meno codice possibilimente in errore. Io starei su sensori i2c. un altro test è staccare "al volo" i componenti, vedere se il tutto supporta il problema, riattaccarli, e vedere se riparte. Sono casi rari disturbi elettromagentici così forti, ma considerado che il vostro progetto è fatto per restare acceso 24h su 24h per 365gg all'anno...

4) Non sapevo di questa cosa, ma mi documenterò. 5) Hai ragione, usare sempre lo stesso standard sarebbe meglio, ma sto cercando dei compromessi adatti anche a principianti come me, non è un caso se tutto il progetto è fatto con cose molto basic, io ho iniziato da zero e vorrei che tutto fosse di facile approccio, ad esempio i sensori di temperatura sono one-wire, comodi ma con una libreria pesantuccia ed allo stesso tempo gli unici digitali che si trovano già in formato water-proof, una valida alternativa potrebbero essere i TI TMP100 http://www.ti.com/product/tmp100 o altri della stessa famiglia, ma non esistono water-proof ed il formato non è certo per principianti, sempre della TI Leouz a trovato quest’altro chip che è fighissimo http://www.ti.com/product/LMP91200 , ma sti formati uno terra terra come me come li usa e soprattutto, saprei farli funzionare??? Ci sono infinite soluzioni, ma il mio livello attuale è troppo basso :(

lesto: 6. attenzione agli overfglow dei timer, anche della millis()

per esempio riga 129 (dallealtre parti sembrerebbe ok):

if (ArrayVariabiliTasti[Indice].ValoreTasto == true && (((millis() >= (ArrayVariabiliTasti[Indice].TempoTasto + 250))) || ((millis() >= (ArrayVariabiliTasti[Indice].TempoTasto + 10)) && ArrayVariabiliTasti[Indice].TastoPremuto == false)))

andrà in errore all'overflow, con imprevedibili risltati sistemala con

if (ArrayVariabiliTasti[Indice].ValoreTasto == true && 
    (
        millis()-ArrayVariabiliTasti[Indice].TempoTasto >= 250
    || 
        (
            millis()-ArrayVariabiliTasti[Indice].TempoTasto >= 10 
            && ArrayVariabiliTasti[Indice].TastoPremuto == false
        )
    )
)

La parte della lettura dei tasti è da rivedere meglio, grazie per la tua segnalazione, provo subito il tuo codice, ma intendo rivedere meglio tutta la cosa, nel senso che attualmente con la IOexp, sembra che il bus I2C sia spazzolato in continuazione in attesa che venga premuto un tasto, quando in effetti i PCF8574 hanno un piedino INT che segnala appunto le variazioni sui piedini di I/O, leggendo quello, con la wire posso leggere il PCF solo quando serve effettivamente, a breve quindi farò questa modifica...

lesto: 7. per la gestione plafo, non è più semplice creare una funzione lineare (y = m*x+q) con valori settabili? dove x è il numero di minuti a partire dalla data di accensione/spegnimento, e y il valore delle luci. Trovare m e q è semplice sopratutto considerando che molto probabilmente avrete sempre q=0.(q è il valore minimo delle luci), in questo modo conservate la data di inizio, magari in secondi dal 1970 (timestamp, che spesso gli RTC calconano tranquillamente), che quindi occupa solo 4 byte (chiamiamola S), e 2 byte (un intero usigned è sufficiente per 65536 secondi, pari a 18 ore) per memorizzare la durata del fading in secondi (chiamiamola D), più un byte per valore fading iniziale a S e valore di fading finale a D, che poi il priomo byte si può risparmiare essendo il vecchio valore di D: infatti il fading è un array ciclico. quindi a partire da S avrete X=0 e y= valore attuale delle luci (accese o spente), e a S+D avrete x = D e y= valore finale delle luci

Credo di aver capito cosa intendi, ma abbiamo visto ed anche provato a buttare giù altre funzioni simili, il risultato però e che la stessa funzione eseguita in background per tutte tre le linee diventa troppo impegnativa per Arduino che contemporaneamente fa anche altre cose, è per questa ragione che attualmente le luci vengono gestite con due procedure, la prima “Statoluci()”, serve a riallineare Arduino con la gestione delle luci in caso di variazione dei dati o di mancanza di corrente, quando le linee sono in modalità automatica, mentre “GestioneLuci()” che invece cicla continuamente in background, grazie appunto ai dati che eventualmente gli passa “Statoluci()” fa funzionare le luci eseguendo semplici confronti sugli orari e su millis().

lesto: 8. al posto di controllare ad ogni ciclo l'RTC, potete impostarlo come "sveglia". Potreste fare che ogni azione da eseguire è shedulata in un apposita struttura con timestamp di esecuzione e comando/funzione da richiamare. In questo modo, viene semplice calcolare il numero di secondi per eseguire la prossima operazione, impostare la sveglia sull'RTC, e mandare il micro "a nanna". ovvio che il pin di risveglio sarà collegato anche alla tastiera (magari però su un pin diverso, non so se si può ascoltare più pin). Così risparmiate un sacco di batteria, e analizzando lo scheduler vi accorgete se qualche istruzione và "fuori posto"!

magari butto giù qualcosa io, ma non avendo un RTC dovrete darmi supporto.

Ecco qui non so se ho capito bene cosa intendi e se anche fosse non saprei nemmeno da dove cominciare, in più cosa intendi per risparmiare batteria, il controller è alimentato dalla rete domestica…

In ogni caso grazie per il tuo interessamento e per l’offerta di collaborazione, io sono disponibilissimo con il mio RTC.

Grazie Lesto

zioTonino: complimenti per il progetto :) molto bello!! tempo e soldi permettendo... proverò a replicarlo così da implementare/rimpiazzare quello che ho ora per gestire, sempre con arduino, i led dell'acquario :) ho alcune domande: 1. ho trovato su ebay le sonde di temperatura .. e costano circa la metà di quelle che ho trovato negli shop più rinomati; dite che son buone lo stesso? 2. tutti gli integrati ecc ecc .. da dove li hai presi? ad es. il PCF8574AP non lo trovo da nessuna parte .... grazie ps. pensi sia sviluppabile con touchscreen così da eliminare i tasti fisici? :) tipo questo per intenderci: http://www.robot-italy.com/it/itdb02-2-4e-2-4-tft-lcd.html

Ciao zioTonino, Grazie per i complimenti, per i tuoi quesiti, non è facile darti una risposta, io per i miei acquisti uso spesso ebay, anche per i pcf, in alternativa puoi vedere si RS o Distrelec, sulla qualità poi non so proprio che dire, finche non li hai in mano e difficile dirlo… :| Per il touchscreen, come ho già scritto molte volte, il controller anche nella componentistica, vorrei che rimanesse il più basic possibile, se ci fai caso il circuito è fatto quasi tutto con connessioni che trovi anche nell’ ABC - Arduino Basic Connections del grande pighixxx, quello che tu hai linkato è bellissimo, e ci ho pure giochicchiato, ma si beve un mare delle poche risorse di Arduino UNO, quindi per usarlo sei in pratica costretto ad usare un MEGA, magari in futuro tempo permettendo si potrà vedere di fare una versione del controller anche così, ma prima voglio completare questo. La sfida che sto cercando faticosamente di vincere a causa della mia scarsa preparazione è di riuscire fare tanto con poco e nel modo più semplice possibile, ecco perché sono li che limo il codice in continuazione per non consumare tutta la flash della UNO o mi ostino ad usare un LCD 20x4…

leo72: Se mi permettete... state consumando un sacco di RAM (al momento il consumo statico è di 1391 byte): perché non mettete le stringhe stampate sull'LCD dentro alla funzione F()? Esempio:

lcd.print("IMP. FOTOPERIODO L");

diventa

lcd.print(F("IMP. FOTOPERIODO L"));

Grazie del consiglio, e sopratutto permettiti sempre ti prego :) ma così non si consuma più flash? Faro un po’ di prove ad ogni modo.

Grazie a tutti. Riccardo