Arduo Memory Reminder Medicine

La precisione nel conteggio del tempo la fornisce l'RTC. UNO o DUE non fa differenza.

Per quanto riguarda l'implementazione dell'elenco di allarmi come array di struct, ho scritto la addAlarm(), a breve ti posto qualcosa.

:wink: Ok.

Aspetto un tuo feedback. Grazie.

La cosa mi ha preso un po' la mano... :wink:

Il programma è ancora poco "pulito" e incompleto per mancanza di tempo. Descrivo brevemente le features attuali.

Impostazione dell'ora tramite seriale con comando "T". Esempio:

T2012-11-13 18:16:00

Imposta data e ora al 13 novembre 2012, ore 18 e 16 e 0 secondi.
Se si collega l'RTC ai pin opportuni e si de-commenta il #define HAS_RTC nella parte iniziale dello sketch, mantiene data e ora indefinitamente.

Inserimento degli allarmi tramite seriale con comando "A". Esempio:

A18:15P01M02

Imposta un allarme giornaliero alle 18:15, per il paziente 01 e la medicina 02.
Sul display vengono mostrati il nome del paziente e il nome della medicina.
Questi nomi attualmente sono fissati nel codice. In futuro dovranno essere gestibili in modo dinamico come gli allarmi (impostabili da seriale) e memorizzabili su eeprom.
Premendo il puslante di ack l'allarme sparisce dal display.

Elenco degli allarmi: L
Cancellazione degli allarmi: C
Caricamento degli allarmi da eeprom: R (non necessario comunque perché li ricarica ad ogni avvio o reset)
Salvataggio degli allarmi su eeprom: S
Elenco degli allarmi in formato "macchina", per una futura lettura su PC: D

Quindi ricapitolando per memorizzare una serie di allarmi su eeprom si fa così:

  1. inserire uno ad uno gli allarmi desiderati con il comando A descritto prima
  2. una volta terminato, mandare il comando S per salvarli in eeprom.
  3. Fatto: d'ora in poi gli allarmi verranno letti da eeprom.

Si possono memorizzare più allarmi con gli stessi valori ora:minuto.

Note hardware:
il mio "pulsante" è un tastierino analogico, quindi per me la condizione di "premuto" significa che leggendo il canale A0 leggo un valore al di sotto di una certa soglia. Nel caso di un pulsante digitale bisogna modificare la funzione ackButtonPressed() in modo che legga lo stato alto o basso di un pin digitale (se si usa una resistenza di pullup lo stato premuto è LOW).

La segnalazione di un allarme avviene per ora soltanto tramite una scritta sul display. Ovviamente in futuro bisognerà copiare il codice del programma originale che interagisce con i led e i buzzer...

Note software:
l'allarme è una struct, l'elenco degli allarmi è un array di struct, intorno al quale però ho costruito una classe per rendere il codice più maneggevole. L'ho scritto un po' di fretta, quindi se avrò più tempo nei prossimi giorni cercherò di migliorarlo.
Ho cercato di abbondare con i commenti per rendere il tutto più comprensibile.

LCDDailyAlarmClock.ino (14.3 KB)

Alarm.h (548 Bytes)

Alarms.h (2.51 KB)

Alarms.cpp (4.99 KB)

:astonished: wow! da paura!

Dalle descrizioni che dai, hai dedicato un bel pò di tempo al progetto! Bravo!
Darò un'occhiata e se riesco provvedo all'inserimento del codice su A.M.R. R05d con l'implementazione del comando dei led.

Ciao.

Preso dall'entusiasmo, temo di essere entrato un po' troppo "a gamba tesa" :stuck_out_tongue:
Il fatto è che avevo scritto qualcosa di simile l'anno scorso, per cui oltre a qualche idea nuova ho riciclato anche qualche "pensata" vecchia ma implementata in modo nuovo...

Credo che potrei essere maggiormente d'aiuto, almeno ora, con piccole migliorie mirate al tuo codice, e/o rispondendo a tue domande specifiche...

(ho comunque intenzione di portare avanti il codice che ho appena postato :slight_smile: )

(ho comunque intenzione di portare avanti il codice che ho appena postato smiley )

Ciao tuxduino. :grin:

Intanto ottimo lavoro scrupoloso che determina interesse al progetto ArduoMemoryReminder. Grazie!

La "gamba tesa" spesso è fonte di miglioramento, come credo in questo caso.

Osservando il tuo post, ed in particolare il codice fornito, occorre chiarire e determinare lacuni aspetti del progetto.

  1. La programmabilità del device, che dovrà essere di semplice intuizione, possibilmente senza PC (il PC si userà solo per verifiche e/o programmazione)
  2. La funzionalita e la comprensione del device che verrà utilizzato da persone con problemi di varia natura
  3. Lo spazio disponibile per il codice hex da caricare su arduino Uno.

Premessa:
Comincio con il chiederti se hai postato tutto correttamente o se manca qualcosa, perchè caricandolo sull'IDE 1.0.1, compreso le librerie "Alarms" e "Alarm" mi dà errore su:

// Oggetto che gesetisce l'elenco degli allarmi.
Alarms alarms;

Segnalando:
LCDDailyAlarmClock:446: error: 'alarms' was not declared in this scope

"Ricorda che non sono esperto nell'utilizzo di librerie ed IDE"

In riferimento al Punto 1:
"Poco rilevante al momento, il codice non prevede ancora una cfg dei parametri"

In riferimento al Punto 2:
"Tenere presente che una volta funzionante, il dispositivo sarà utilizzato da persone diversamente abili o con problemi di memoria, quindi il paziente non dovrà preoccuparsi di fare nulla al di fuori della pressione del pulsante ACK per consentire al device di memorizzare l'assunzione del medicinale."

In riferimento al Punto 3:
"Con la gestione delle variabili char, sei sicuro che la UNO supporti almeno 64 di queste da 10-15 caratteri ciascuna + codice + eventuali implementazioni?"

Una volta definita la modalità di gestione di questi tre punti, si può procedere con l'upgrade al codice.

Sono sicuro che saprai già come gestire eventualmente il tutto.

Intanto ancora grazie per il lavoro svolto. E' bello vedere che esiste ancora qualcuno disponibile a partecipare a qualcosa di creativo ed utilie a tutti, specialmente a chi ne ha veramente bisogno.

PS.: Sei d'accordo se inserisco il tuo nickname nel progetto postato al FABLAB come (main software developer), questo invoglierebbe altri a partecipare al progetto ed a uno scambio di opinioni credo interessanti anche di un certo livello?

Giuseppe G.

Ho dato una scorsa al progetto.
Bravi ad entrambi :stuck_out_tongue:

Volevo suggerire solo una risposta al problema del reset dell'Arduino.
Esso avviene sempre, a meno che:

  1. non interrompi la pista RES-EN, però poi devi resettare la scheda a mano ogni qual volta la devi riprogrammare
  2. non riflashi l'Atmega8U2: http://arduino.cc/forum/index.php/topic,130621.0.html

Intanto ottimo lavoro scrupoloso che determina interesse al progetto ArduoMemoryReminder. Grazie!

Grazie a te per l'apprezzamento :slight_smile:

Intanto ancora grazie per il lavoro svolto. E' bello vedere che esiste ancora qualcuno disponibile a partecipare a qualcosa di creativo ed utilie a tutti, specialmente a chi ne ha veramente bisogno.

Non vorrei sembrarti cinico ma confesso -per onestà- che programmare mi diverte un sacco :stuck_out_tongue:

Veniamo ora ai contenuti...

Comincio con il chiederti se hai postato tutto correttamente o se manca qualcosa.

A casa l'ho pure caricato sulla scheda per provarlo... probabilmente ho fatto qualche errore nel caricamento dell'allegato... Controllerò meglio.

"Ricorda che non sono esperto nell'utilizzo di librerie ed IDE"

Lo diventerai 8)

  1. La programmabilità del device, che dovrà essere di semplice intuizione, possibilmente senza PC (il PC si userà solo per verifiche e/o programmazione)

Poco rilevante al momento, il codice non prevede ancora una cfg dei parametri.

Come ti dicevo ho buttato giù lo sketch in fretta, per cui risultava più semplice implementare la programmazione via seriale che gestire tasti e display.
Ho comunque già qualche idea in merito...

Il mio keypad è analogico (5 tasti che provocano letture diverse su A0 quando premuti), non so che tastiera usi tu (appena ho tempo lo guardo sul sito). Considero questa differenza di hw un incentivo a mantenere il codice "bello pulito" e modulare in modo che cambiando una semplice #define sia possibile utilizzare diverse "tastiere" (o per meglio dire "pulsantiere").

Comunque la programmazione senza PC mi pare di capire che al momento è poco prioritaria. Anche perché non è affatto banale da implementare...

  1. La funzionalità e la comprensione del device che verrà utilizzato da persone con problemi di varia natura

Tenere presente che una volta funzionante, il dispositivo sarà utilizzato da persone diversamente abili o con problemi di memoria, quindi il paziente non dovrà preoccuparsi di fare nulla al di fuori della pressione del pulsante ACK per consentire al device di memorizzare l'assunzione del medicinale.

L'ultima parola ovviamente spetta a te, in particolare su questo punto, per valutare se un certo modo di operare del device sia idoneo o meno a quello che tu immagini essere l'utente finale tipico.

Il fatto che ci sia solo un grosso pulsante di conferma comunque semplifica non poco la situazione.

  1. Lo spazio disponibile per il codice hex da caricare su arduino Uno.

Con la gestione delle variabili char, sei sicuro che la UNO supporti almeno 64 di queste da 10-15 caratteri ciascuna + codice + eventuali implementazioni?

Per il mio sketch occupa metà flash rom. Confido si possa ottimizzare, soprattutto perché nella Time.h ci sono molte stringhe...
Comunque no, non sono sicuro ci stia tutto. Ma la "premature optimization" è Male(TM), quindi chi vivrà vedrà... :slight_smile:

PS.: Sei d'accordo se inserisco il tuo nickname nel progetto postato al FABLAB come (main software developer)

Ne sarei onorato... Ma così mi tocca poi finire il lavoro! :smiley:

LCDDailyAlarmClock:446: error: 'alarms' was not declared in this scope

Posta l'errore completo.

Sospetto che ci sia un baco in Time.cpp: prova ad inserire queste righe prima di #include "Time.h":

#if ARDUINO >= 100
#include <Arduino.h> 
#else
#include <WProgram.h> 
#endif

:wink: Ok!

Sospetto che ci sia un baco in Time.cpp: prova ad inserire queste righe prima di #include "Time.h":

Code:

#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

Ma perchè accade questo ?
PS: Mi piacerebbe capire perchè. C' e un link dove viene spiegato ? O è un problema della libreria non aggiornata?

:slight_smile: Ciao Leo72,

Ho dato una scorsa al progetto.
Bravi ad entrambi smiley-razz

Volevo suggerire solo una risposta al problema del reset dell'Arduino.
Esso avviene sempre, a meno che:

  1. non interrompi la pista RES-EN, però poi devi resettare la scheda a mano ogni qual volta la devi riprogrammare
  2. non riflashi l'Atmega8U2: http://arduino.cc/forum/index.php/topic,130621.0.html

Grazie per l'info utile per poter implementare l'eventuale SW per gestire la visone/programmazione dei parametri.

Scusa per la domanda banale, ma basta il ponticello HD o bisogna inserire anche le parti del SW ?

Il ponticello funziona grazie alle modifiche SW :wink:
Va quindi modificata prima la scheda per saldare il connettore ICSP, poi va cambiato il firmware all'Atmega e poi si può utilizzare il ponticello.

Ma perchè accade questo

Le versioni di Arduino precedenti alla 1 includevano WProgram.h. E' un dettaglio tecnico dovuto al fatto che Arduino è basato un progetto precedente denominato Wiring. Nel passaggio alla 1.0 hanno rinominato il .h principale in Arduino.h. Le librerie non aggiornate per la 1 hanno un problema, perché WProgram.h è sparito. Grazie alla #define ARDUINO è possibile "capire" in che ambiente stiamo compilando, e comportarsi di conseguenza.

:wink:
Bene! Al momento dell' inserimento del SW per la gestione dal PC ne terrò presente.

Grazie.

Ma non basterebbe inserire una patch nella libreria per sistemare il problema ? :roll_eyes:

E' proprio quella che ti ho postato prima :wink:

Time.h, come molte altre, non è una libreria "core", mantenuta dal team di Arduino. L'aggiornamento ad Arduino 1 sta al buon cuore e alla vonlontà dellos viluppatore / manutentore della libreria...

tuxduino:

[quote author=Giuseppe G. link=topic=124000.msg995631#msg995631 date=1352890280]
Ma non basterebbe inserire una patch nella libreria per sistemare il problema ? :roll_eyes:

E' proprio quella che ti ho postato prima :wink:
[/quote]
Non è così semplice! :smiley:
Quel sistema regola solo l'include del core di Arduino in base alla versione dell'IDE. Ma non fa nient'altro.
Dall'IDE 002x sono cambiate tantissime cose a livello di librerie per cui non è detto che con quel semplice trucco tutto funzioni sempre.

leo72:

tuxduino:

[quote author=Giuseppe G. link=topic=124000.msg995631#msg995631 date=1352890280]
Ma non basterebbe inserire una patch nella libreria per sistemare il problema ? :roll_eyes:

E' proprio quella che ti ho postato prima :wink:

Non è così semplice! :smiley:
Quel sistema regola solo l'include del core di Arduino in base alla versione dell'IDE. Ma non fa nient'altro.
Dall'IDE 002x sono cambiate tantissime cose a livello di librerie per cui non è detto che con quel semplice trucco tutto funzioni sempre.
[/quote]

Lo so che in generale è così. Nel caso di Time.h mi è bastato fare quella modifica e la libreria ha funzionato... Ovvio che la cosa migliore da fare è contattare lo sviluppatore :slight_smile:

Nuova versione.

Il pulsante di ack è attivo basso e collegato al pin ACK_BTN_PIN (12).

Il led/buzzer attivo alto è collegato sul pin ALARM_LED_PIN.

Quando c'è un allarme attivo il pin ALARM_LED_PIN lampeggia con periodo 1s e duty cycle 50%. In pratica sta acceso per 500ms e spento per 500ms.
Appena si preme il plsante di "accettazione" allarme (ack) l'allarme termina e il lampeggio del led si ferma.

Vengono utilizzate due nuove librerie:
// Button http://www.arduino.cc/playground/Code/Button
// FancyLED GitHub - carlynorama/Arduino-Library-FancyLED: Arduino Library for working with LEDs. Includes non-delay blinking, toggling status and other features
Entrambe richiedono la "patch-wprogram" postat in precedenza per poter compilare sotto Arduino 1.0.

LCDDailyAlarmClock.ino (15.5 KB)

FreeRam.h (256 Bytes)

:sweat_smile:
Ciao tuxduino,
che fatica starti dietro!

Ho dato un'occhiata al nuovo codice e noto con stupore, che usi molto le librerie, cosa che dovrei fare anche io.
Spesso mi imbatto in soluzioni obsolete o con accrocchi sw per far funzionare le idee, quando basterebbe conoscere soluzioni già testate, come quella del led.
Il problema è, come e dove andarle a cercare.
Usare le librerie, però non comporta un ulteriore ampliamento del SW e quindi spazio in memoria flash?

Bando alle ciance, credo che non basti la soluzione che hai postato per la libreria "Time.h", mi vengono fuori altri errori.

Al di là di questo, sono un po antiquato sll' IDE, in quanto la versione 1.0.1 mi da diversi problemi sul PC che ho a casa con sitema Win XP Pro SP3 installato su un PC AMILO datato, e non posso testare il tuo codice a livello HD. Si può portare il tuo codice ad una versione ridotta dell' IDE, tipo 0022 dove non ho problemi?

Ho visto che la 0022 non apre i file .INO ma solo i .PDE, mentre viceversa funziona.

Hai consigli a riguardo? (non mi dire che devo cambiare il PC!!! =( )

Ciao.

:slight_smile:

Tra il reinventare la ruota ad ogni sketch ed utilizzare quasi soltanto librerie bisogna trovare un punto di equilibrio.
Dipende da molti fattori... In definitiva è una scelta personale, anche legata al particolare progetto o momento.
Talvolta trovo più semplice / veloce / divertente / formativo scrivere codice mio per fare una cosa comune piuttosto che andarmi a cercare una libreria già fatta e capire se fa al caso mio.
Altre volte è meglio o più conveniente affidarsi a codice già pronto, per evitare di perdere tempo in dettagli importanti ma non direttamente legati al progetto in corso.

C'è poi il discorso di base: l'uso di librerie (nel caso di Arduino parliamo di solito di classi C++) rende il codice dello sketch più pulito e leggibile (ovvero meno probabilità di bachi e maggior facilità di modifiche).

Esempio: scrivo un programma che fa lampeggiare un led. Il lampeggio può essere avviato o fermato premendo un pulsante. Posso mettere tutto nello sketch principale e la cosa rimane comprensibile, manoto che già in un esempio così semplice vado a "mescolare" nel sorgente variabili legate esclusivamente alla gestione dello stato del led e altre variabili che entrano solo nel calcolo dello stato del pulsante. Inoltre il codice del led deve rimanere separato da quello del pulsante, per evitare il caos.
Ecco che introduco allora delle funzioni per raggruppare pezzetti di logica dentro un'unica chiamata dal nome intuitivo. Tipo isButtonPressed(), oppure activateLedBlink().
Nel passo successivo noto che posso raggruppare questse funzioni e le variabili di stato su cui operano in una classe, portando il tutto in file separati. Ecco che nascono ad esempio la classe Button e la classe BlinkingLed. E nel contesto di Arduino queste sono già due librerie. Che posso mettere in sketchbook/libraries e riutilizzare in altri progetti più o meno semplici.
Non solo: posso ora utilizzare più led e più pulsanti indipendenti nello stesso programma in modo estremamente semplice (e in certa misura elegante), senza aggiungere per questo decine di righe di codice.

Discorso analogo vale ad esempio per la temporizzazione degli eventi: l'esempio blink without delay mostra la tecnica di base. Per sketch banali la si può anche usare nuda e cruda (con la variabile _prevMillis usata direttamente) ma all'aumentare dellal complessità diventa molto comodo (e talvolta indispensabile) usare librerie già pronte che la incorporano. Anche perché spesso hanno funzionalità aggiuntive che un'implementazione "nuda e cruda" porta a trascurare.

La risposta breve è: se una cosa la devi fare, il codice lo devi mettere. Che sia scritto direttamente nello sketch o già presente in una funzione di libreria, cosa cambia ?

Più in dettaglio...
In generale è vero il contrario. Usando le funzioni di una libreria al posto della ripetizione del codice "nudo e crudo" si risparmia sulla dimensione del programma. Inoltre il compilatore è abbastanza intelligente da includere nell'eseguibile finale solo le funzioni effettivamente utilizzate di una libreria. Può capitare tuttavia che il "peso" di una libreria sia maggiore rispetto ad un eventuale codice specifico scritto ad hoc, ad esempio perché la funzione di libreria tenta di risolvere il problema in termini più generali, quindi include codice che in quel particolare progetto a noi non serve.
Anche qui non esiste una ricetta valida per tutte le occasioni: bisogna valutare caso per caso, magari provare diverse librerie o, se necessario, (ri)scrivere alcune funzionalità da zero in modo dedicato al particolare problema.

Il mio consiglio è di passare alla 1.0.2, comunque proverò a compilare lo sketch anche sotto l'ultima versione pre-1.0 (mi pare sia la 0023).
Eventualmente ti mando un zip con il codice delle librerie che ho sul mio pc. Può essere che abbia fatto qualche modifica in più che non ricordo...
Dal punto di vista del PC non credo ci siano problemi nel passare dalla 22 alla 1.0.2. Le richieste di sistema sono circa uguali.