ArduoMemoryReminder
novembre 11, 2012 in da Giuseppe
Ultima Release del firmware: in aggiornamento per l’ hardware R.1.0
Ultimo aggiornamento del progetto R.1 : 30/11/2012
_______________________________________________________
Ultima Release del firmware: Rev.0.5I per l’ hardware R.0.0
Ultimo aggiornamento del progetto R.0 : 24/11/2012
_______________________________________________________
Progetto ITALIANO basato su Arduino Uno.
Ideato e creato da Giuseppe G., sviluppato in collaborazione con la comunità di arduino “vedi Partecipanti al progetto”
Il progetto base, prevede la costruzione di un device di semplice comprensione ed utilizzo, al fine di aiutare le persone bisognose a ricordare le assunzioni delle medicine giornaliere.
DESCRIZIONE DEL DEVICE.
Tramite un display LCD, si potrà visualizzare l’ora, la data, gli allarmi e la programmazione degli stessi.
Un altoparlante, avviserà tramite segnalazione acustica, l’allarme attivo per l’assunzione del medicinale.
Una serie di led, indicheranno da quale scompartimento si dovrà prelevare il medicinale.
Un pulsante verrà utilizzato per memorizzare l’avvenuta assunzione del medicinale.
Una mini tastiera, verrà utilizzate per programmare i vari parametri come ora, data, medicina e paziente degli allarmi giornalieri.
CARATTERISTICHE Tecniche.
Software:
- 32 allarmi giornalieri
- 2 pazienti
- 16 medicine per paziente
- segnalazione sonora a 10 suonerie differenti per i pazienti
- orario/datario
- ora legale
- lingua (IT / GB)
- autocorrezione orario girnaliera
- memoria dati su eprom
Hardware:
- Arduino UNO ATMEL328 32kflash, 2kSram, 2kEprom
- batteria tampone per non perdere l’ora
- alimentazione da rete 220Vac
- display LCD per visualizzare le funzioni
- mini tastiera per la programmazione dei parametri
- 32 scompartimenti per le medicine, 16 per il paziente 1 e 16 per il paziente 2
- segnalzione audio tramite altoparlante
- pulsante acquisizione allarme assunzione medicinale
COMPONENTI per la realizzazione del progetto base Release R.0.x:
n.1 Arduino Uno
n.1 display LCD
n.3 pulsanti KPT
n.1 pulsante rosso (ACK)
n.16 led rossi
n.16 led gialli
n.1 bacheca a scomparti
n.1 batteria tampone da 4,8V ricaricabile
n.1 alimentatore da rete 230Vac/9Vdc 300mA
n.5 resistenze 220ohm 1/4W
n.3 resistenze 10k 1/4W
n.3 resistenze 1k 1/4W
n.1 resistenza 22 ohm 1/2W
n.1 altoparlante 4-8ohm
n.1 transistor NPN BC337/40
n.2 condensatori poliestere da 1uF 50V
n.3 condensatori ceramici 10nF 60V
n.1 diodo zenere 6V2 1/2W
COMPONENTI per la realizzazione del progetto base Release R.1.x:
n.1 Arduino Uno
n.1 display LCD 16×2
n.5 pulsanti KPT
n.1 pulsante rosso (ACK)
n.32 led gialli
n.1 bacheca a 32 o 2 da 16 scomparti
n.1 shield RTC
n.1 alimentatore da rete 230Vac/9Vdc 300mA
n.2 resistenze 2k2 1/4W
n.1 resistenze 470 ohm 1/4W
n.1 resistenze 1k 1/4W
n.6 resistenza 22 ohm 1/2W
n.1 altoparlante 4-8ohm
n.1 transistor NPN BC337/40
n.2 condensatori poliestere da 1uF 50V
n.1 eprom 24C64 8pin DIP
n.1 trimmer 10k
FUTURE.
Il progetto subirà in un secondo momento, un upgrade con l’utilizzo di Arduino Mega o Due per poter implementare delle funzioni, che trasformeranno lo stesso in una sorta di dottore personale.
Stesura idee per l’implementazione hardware e software:
- Segnalazione audio ripetuta n. volte in 30 minuti per ricordare l’assunzione
- Aggiunta shield RTC con DS1307
- Aggiunta EPROM esterna per la memorizzazione medicinali assunti e non durante la giornata (sorta di audit-trail che traccia la cronostoria delle assunzioni)
- Illuminazione scompartimento in plexiglass lumineschente
- Presenza medicina nello scomparto
- Avviso termine medicinale (con inserimento dosi per scatola)
- Chiamata al cellulare per assunzione medicina lontano dal device
- Telecomando per chimate telefoniche di emergenza
- Misuratore di temperatura istantaneo
- Misuratore di battiti cardiaci
- Segnalazione mancata assunzione, termine del medicinale via telefono, SMS o E-Mail.
Discussione aperta per la ricerca:
arduomemoryreminder sul forum italiano software
( http://arduino.cc/forum/index.php/board,84.0.html )
e su
( http://www.fablabtorino.org/portfolios/ )
FUNZIONAMENTO:
Il device una volta configurato per la data, orario, lingua, suonerie e prorammato con le scadenze ed i medicinali da assumere, ricordeà ai pazienti la corretta assunzione di questi.
Il paziente, udendo la segnalazione sonora, dovrà recarsi entro 1 minuto, davanti al device, premere il pulsante ACK (acquisizione) ed assumere il medicinale segnalato con l’accensione del led rispettivo allo scompartimento, il quale rimarrà acceso ancora per 1 minuto, per permettere al paziente di prendere la medicina.
Se il pulsante ACK non viene premuto, il led continuerà a lampeggiare ancora per 30 minuti, dopo di chè, cessera di lampeggiare.
ISTRUZIONI PER LA PROGRAMMAZIONE:
Modalità di accesso alla configurazione del sistema:
Premere il tasto UP (config. system)
Parametro Valore
________________________________________
SET_hours___time 0-23
SET_minutes_time 0-59
SET_day_of__date 1-31
SET_month___date 1-12
SET_year____date 1970-2030
SET_ADJ_sec_time 0-59
SET_Legal___time 0-1
SET_Langu._GB/IT 0-1
SET_Sound.Pat._1 0-9
SET_Sound.Pat._2 0-9
SET_hours_time__ 0-23
Permette di impostare l’ora corrente
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_minutes_time 0-59
Permette di impostare i minuti dell’ora corrente
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_day_of_date 1-31
Permetee di imostare il giorno della data corrente
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_month___date 1-12
Permette di impostare il mese della data corrente
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_year___date 1970-2030
Permette di impostare l’anno della data corrente
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_ADJ_sec_time 0-59
Permette di impostare la correzione giornaliera in secondi del tempo
(questo parametro è stato inserito per correggere l’errore generato dal clock di Arduino Uno)
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Legal___time 0-1
Permette di attivare “1″ o disattivare “0″ l’ora legale per il cambio automatico
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Langu._GB/IT 0-1
Permette di selezionare la lingua inglese “0″ = GB o la lingua italiana “1″ = IT
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Sound.Pat._1 0-9
Permette di selezionare la suoneria dedicata al paziente 1 con una scelta di 10 tonalità diverse.
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Sound.Pat._2 0-9
Permette di selezionare la suoneria dedicata al paziente 2 con una scelta di 10 tonalità diverse.
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
PS.: Se durante l’inserimento dei parametri, non si interviene entro 60 secondi dall’ultima
pressione dei tasti, il device uscirà automaticamente dalla configurazione riportandosi alla
visualizzazione normale di standby.
Modalità di accesso ai parametri:
Premere il tasto DW (view config. alarms da 1 a 32)
Parametro Valore
________________________________________
AL1 Time:xx.xx 00.00-23.59
Pat.:0x 1-2
Med.:xx 0-32
AL2 Time:xx.xx 00.00-23.59
Pat.:0x 1-2
Med.:xx 0-32
AL3 Time:xx.xx 00.00-23.59
Pat.:0x 1-2
Med.:xx 0-32
…
…
…
…
…
…
AL32 Time:xx.xx 00.00-23.59
Pat.:0x 1-2
Med.:xx 0-32
Durante la visualizzazione della configurazione allarmi, è possibile premere
il tasto “ENT” ed entrare nella programmazione dell’allarme selezionato
SET_hour____ALx 00-23
Permette di impostare l’ora di intervento dell’allarme x
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_min.____ALx 00-59
Permette di impostare i minuti di intervento dell’allarme x
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Patient_ALx 01-02
Permette di impostare il paziente richiamato dell’allarme x
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
SET_Medicin_ALx 00-16 .. 17-32
Permette di impostare la medicina da segnalare dell’allarme x
Se la medicina inserita = 0, il dispositivo disattiverà l’allarme, non tenedo conto dell’orario.
Una volta inserito il parametro corretto, premere il tasto “ENT” per continuare
NB: Tutti i parametri saranno salvati in copia sulla eprom, in maniera che non vengano persi, causa spegnimento device.
PS.: Se durante l’inserimento dei parametri, non si interviene entro 60 secondi dall’ultima
pressione dei tasti, il device uscirà automaticamente dalla configurazione riportandosi alla
visualizzazione normale di standby.
Modalità di default:
Premere il tasto DW al riavvio del device
In questo modo, tutti i parametri verranno sovrascritti dai dati di default inseriti nell’array dello sketch, compreso la sovrascrittura della eprom.
Rimarranno invariati i parametri di configurazione del sistema.
Partecipanti al progetto Open Source:
Main Project & Research: Giuseppe G. (forum di arduino.cc)
Main Software Developer: tuxduino (forum di arduino.cc)
Tips and ideas (forum di arduino.cc):
Ale92 , cace99 , MauroTec , leo72 , cyberhs , Nik_90 , brunello
ELENCO Release Hardware del progetto:
ELENCO RELEASE / INFO FIRMWARE ArduoMemoryReminder per hardware R.0.0:
Prima release base funzionante testata: sketch_ArduoMemoryReminder_R05d
Guida veloce all’utilizzo del device ArduoMemoryReminder R05d
Revisione con dati in eprom ed inserimento array per parametri di default con funzione legata alla pressione del tasto down all’accensione. A_M_R_05f
Revisione con selezione lingua su eprom, gestione led con matrice by tuxduino e completamento descrizioni funzioni.A_M_R_05G
Revisione con matrice gestione led originale.A_M_R_05G1
Revisione con sistemazione bug ore allarme n.1 in conflitto in eprom con selezione lingua ed inserimento 10 segnalazioni sonore e pause differenti con frequenze basse per i due pazienti, memorizzate in eprom.A_M_R_05H
Revisione con inserimento gestione locazione creata ed inserita da tuxduino, sistemazione descrizione parametro “ora legale” in inglese e sistemazione bug selezione medicina 00 paziente 2.A_M_R_05i
Revisione provvisoria di partenza per l’utilizzo dell’hardware R.1.0a con varie adj sia HD che SW. Per l’utilizzo di una eprom esterna, occorre ricordare di inserire due resitenze nelle linee SDA e SCL da 2k verso il +5V.A_M_R_1_0_0c
/* Sketch ArduoMemoryReminder R.1.0c
________________________________________________________________________________________________________________
Invent & Create by Giuseppe G. (giusby & gengysghey) 04/09/2012
For remember to take the medicine of day
Basic design first published in the "http://www.arduomemory.blogspot.it" site
and later at FABLAB Turin for implementations at project
Cooperation whit tuxduino by forum arduino (R.0.5g-R.0.5i)
________________________________________________________________________________________________________________
Current version: (modify software for adapting new hardware R.1.0 start by tuxduino)
Revision:1.0.0(about 16858 bytes of 32256 flash and about xxx byte of sram free)
Compiled with Arduino IDE 0022 WinXP
Date:19/12/2012
ok - generation a new hardware circuit for free pin on Arduiono UNO R.1.0 (by Giuseppe G.)
ok - reloched connection pin matrix leds
ok - rtc: upgrade include necessary
ok - rtc: the ds1307 is the main generation of time
ok - rtc: if adjust the time and date, automatically adjust on rtc system
ok - reloched connection pin speaker
ok - reloched connection pin lcd
ok - pin input analog buttons da aggiornale
ok - insert key ESC & CFG
ok - insert function test read/write external eeprom
________________________________________________________________________________________________________________
Old version:
Current version:
Revision:0.5i(about 13570 bytes of 32256 flash and about 640 byte of sram free)
Compiled with Arduino IDE 0022 WinXP
Date:24/11/2012
ok 1- Insert a location management by tuxduino
ok 2- Correct the description parameter of DST, Daylight Saving Time
ok 3- Correct description button keyACK
ok 4- Correct bug select medicine 00 on patient 2
Revision:0.5H(about 13456 bytes with about 740 byte of sram free "free about 3k (-2768) of flash memory with matrix")
Compiled with Arduino IDE 0022 WinXP
Date:22/11/2012
ok 1- Correct bug selection language by eprom range n. 0, move to n.128
ok 2- Insert a new sound and select in config for patient
ok 3- Insert memory to erpom for select sound patient 1 & 2 on n.129 & n.130
ok 4- Remuve test alarm sound test on start-up defaut parameter
Revision:0.5G1(about 12944 bytes with about 900 byte of sram free "free about 3k (-2768) of flash memory with matrix")
Compiled with Arduino IDE 0022 WinXP
Date:20/11/2012
ok 1- Insert a new matrix by tuxduino for control led
ok 2- Relocation original matrix WriteCell() with verirow
Revision:0.5f(about 15714 bytes with about 1000 byte of sram free)
Compiled with Arduino IDE 0022 WinXP
Date:15/11/2012
ok 1- Insert a parameter default on array "def_par" and enable with push dw on start-up
ok 2- Insert a parameters on eprom
________________________________________________________________________________________________________________
Caracteristics R.0.5c-R.05d-R.0.5e-R.0.5fx-R.0.5gx-R.0.5i:
max 32 alarms
max 2 patient
max 16 medicine for patient (tot. 32 medicines)
________________________________________________________________________________________________________________
Hardware Basic components R.0.5c-R.05d-R.0.5e-R.0.5fx-R.0.5g-R.0.5H:
32 led yellow alarm medicine patient 1&2
1 speaker for noise alarm segnalation (4-8 ohm)
5 resistors 220ohm 1/4W
1 LCD 1602 (16ch x 2line)
1 trimmer 10k
1 Arduino Uno
3 resistors 10K 1/4W
4 resistors 1K 1/4W
3 ceramic condenser 10nF 50V
1 power switch 9Vdc 500mA
1 button red NA big (Enter/ACK)
3 button black NA small (Up/Down/Pgm)
2 mt flat 10 pin
1 connector 32 pin male for Arduino
1 transistor BC337 NPN
2 conderser poliestere 1uF 50V
1 battery 3V CR2032
1 RTC DS1307
1 EPROM 24C64
________________________________________________________________________________________________________________
The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 7
* LCD D5 pin to digital pin 6
* LCD D6 pin to digital pin 5
* LCD D7 pin to digital pin 4
* LCD R/W pin to ground
* LCD ends to +5V and ground
* wiper to LCD VO pin (10K resistor trimmer)
* buzzer/speaker pin A1
* led line1 alarm digital pin 5
* led line2 alarm digital pin 4
* led line3 alarm digital pin 3
* led line4 alarm digital pin 2
* led row1 alarm digital pin 6
* led row2 alarm digital pin 7
* led row3 alarm digital pin 8
* led row4 alarm digital pin 9
* input analog buttons pin A0
*/
//**********************************************************************************
//**********************************************************************************
// include the library code:
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Time.h>
#include <Tone.h>
// DS13O7 support
#include <DS1307RTC.h>
#include <Wire.h>
// external EEPROM define type 24C64 address 0
#define DEV_ADDR 0x50
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.send(rdata);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.send((int)(eeaddress >> 8)); // MSB
Wire.send((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) {
rdata = Wire.receive();
}
return rdata;
}
byte vp =32; // test counter char for external eprom
// declare the tones as an array
Tone sound;
const int DTMF[] = { 2200, 3300, 4600, 3800, 3800, 3800, 3800, 10000, 10000, 2200, 2200, 2200, 2200, 2200, 2200, 10000, 10000, 10000, 3800, 3800};
byte si=0; //variable increment counter note sound
// Tone output pin
const byte TONE_PIN = A1;
// default parameters array
// HH MM Pat Med HH MM Pat Med HH MM Pat Med HH MM Pat Med
const byte def_par[] = { 8, 0, 1, 1, 8, 30, 1, 2, 9, 0, 1, 3, 9, 30, 1, 4,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//declaration variables
int analogpin = 0; //variable input analog buttons
byte keycount = 0; //counter effective push button
byte keyDW = 0; //button key Down
byte keyUP = 0; //button key Up
byte keyACK = 0; // button key aquisition alarm
byte keyESC = 0; // button key exit function
byte keyCFG = 0; // button key configuration system
byte push = 0; // variable status botton
byte mempush = 0; // variable memory botton pressed
int prg = 0; // variable status program configuration
byte memalarm = 0; // variable status alarm
int s_old = 0; // memory old minute alarm
byte alarm = 0; // alarm active
int sel = 0; // select view alarms
byte lamp = 0; // blink on/off
byte sold = 0; // memory second old
int tast = 0; // value increase / decrease parameter
int ho_old=0; // mem old hour set
int mi_old=0; // mem old minute set
int da_old=0; // mem old day set
int mo_old=0; // mem old month set
int ye_old=0; // mem old year set
byte alm_h[33]; // array variable alarm hour view
byte alm_m[33]; // array variable alarm minute view
byte med[33]; // array variable alarm medicinale view
byte pat[33]; // array variable alarm patient
byte medic[1]; // variable view led alarm auxiliary
byte mtast; // memory pressure key up or down
byte mmin=0; // memory counter for auto-clear segnalation alarm
byte min_old=0; // counter minute for auto-clear segnalation delay
byte adjs=48; // adj off-set second time for day when not use the RTC
byte ltime=1; // legal time
byte memltime=0; // memory change legal time
byte _lang=0; // memory select language // tuxduino: underscore prefix means don't access this variable directly; use getCurrLang(), setCurrLang() instead
/*/////////*/
//int ramLibera = freeRam(); // define freeRam(); function for view sram free //R.0.5d
//
// Localization management by tuxduino
//
// list of defined languages
enum {
LANG_FIRST = 0,
LANG_EN = 0,
LANG_IT = 1,
LANG_LAST = 1,
};
// eeprom memory address of language setting by tuxduino
const byte EE_LANG_ADDR = 128;
// number of defined languages by tuxduino
const byte NUM_LANGS = LANG_LAST + 1;
// max size of localized string (including null-terminator)
// const byte MAX_STR_LEN = 17
// localized strings by tuxduino
const char* strings[][NUM_LANGS] = {
// 0123456789012345 0123456789012345
"SetDefault_ALARM", "Allarmi_predef. ", // 0
"Patient_" , "Paziente" , // 1
"Medicine______" , "Medicina______" , // 2
"____NO_ALARM____", "_NESSUN_ALLARME_", // 3
"SET_hours_______", "Impostazione_ore", // 4
"SET_minutes_____", "Impostaz._minuti", // 5
"SET_day_________", "Impostaz._giorno", // 6
"SET_month_______", "Impostaz.___mese", // 7
"SET_year________", "Impostaz.___anno", // 8
"SET_ADJ_sec_time", "Regol.sec.giorno", // 9
"SET_Day.Sav.Time", "Attiv.ora_legale", // 10
"SET_Lang.__EN/IT", "Linguaggio_EN/IT", // 11
"SET_Sound.Pat._1", "Suoneria_Paz.__1", // 12
"SET_Sound.Pat._2", "Suoneria_Paz.__2", // 13
" Time:" , " Ore:" , // 14
"Pat.:" , "Paz.:" , // 15
"SET_hour____AL" , "SET_ore_____AL" , // 16
"SET_min.____AL" , "SET_minuti__AL" , // 17
"SET_Patient_AL" , "SET_Pazient_AL" , // 18
"SET_Medicin_AL" , "SET_Medicin_AL" , // 19
};
// localized strings identifiers by tuxduino
enum {
STR_SET_DEFAULT_ALARM = 0,
STR_PATIENT = 1,
STR_MEDICINE = 2,
STR_NO_ALARM = 3,
STR_SET_HOURS = 4,
STR_SET_MINUTES = 5,
STR_SET_DAY = 6,
STR_SET_MONTH = 7,
STR_SET_YEAR = 8,
STR_ADJ_SEC = 9,
STR_SET_LEGAL_TIME = 10,
STR_SET_LANG = 11,
STR_SET_SOUND_PAT_1 = 12,
STR_SET_SOUND_PAT_2 = 13,
STR_TIME = 14,
STR_PAT = 15,
STR_SET_HOUR_AL = 16,
STR_SET_MIN_AL = 17,
STR_SET_PATIENT_AL = 18,
STR_SET_MEDICINE_AL = 19
};
// the the localized version of the specified string by tuxduino
const char* getString(byte stringId) {
return strings[stringId][_lang];
}
// select language; the selection is stored in eeprom by tuxduino
void setCurrLang(byte langId) {
if (langId < NUM_LANGS) {
_lang = langId;
EEPROM.write(EE_LANG_ADDR, _lang);
}
}
// get current language selection by tuxduino
byte getCurrLang() {
return _lang;
}
// read the currently selected language from eeprom by tuxduino
// initialize eeprom setting if necessary
void initLangFromEeprom() {
byte lang;
lang = EEPROM.read(EE_LANG_ADDR); // read language setting from eeprom
if (lang > LANG_LAST) { // if the value is invalid
lang = LANG_FIRST; // set it to a default value
EEPROM.write(EE_LANG_ADDR, lang); // and save it
}
// update global variable by tuxduino
_lang = lang;
}
// declare variable matrix by tuxduino R05G
const byte NUM_ROWS = 4;
const byte NUM_COLS = 4;
byte rowPins[NUM_ROWS] = { 2, 3, 4, 5 };
byte colPins[NUM_ROWS] = { 6, 7, 8, 9 };
byte cnt = 0;
byte value = 1;
byte sel_sound1=0; // memory select sound patient 1
byte sel_sound2=0; // memory select sound patient 2
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(A2, A3, 10, 11, 12, 13);
void setup() {
// bug Rev.0.5g1
// lang=EEPROM.read(0); // read language by eprom
// if (lang>1) {lang=0;EEPROM.write(0,0);}//set to standard language "GB" if no setting
initLangFromEeprom(); // by tuxduino
sel_sound1=EEPROM.read(129); // read sound patient 1
if (sel_sound1>9) {sel_sound1=0;EEPROM.write(129,0);}//set to standard sound patient 1
sel_sound2=EEPROM.read(130); // read sound patient 2
if (sel_sound2>9) {sel_sound2=0;EEPROM.write(130,0);}//set to standard sound patient 2
/*/////////*/
Serial.begin(9600); // start serial monitor //R.0.5d
Wire.begin();
sound.begin(TONE_PIN);
sound.play(DTMF[3], 500);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message version project to the LCD on start-up.
lcd.print("ArduoMemoryR1.0c");
lcd.setCursor(0, 1);
lcd.print("By Giuseppe & Co");
//analogButtons.checkButtons();
delay (1000);
// verify push down at start up for default parameter set
// if (digitalRead(keyDW)== 1) { // key down start up active
if (analogRead(analogpin)>=676 && analogRead(analogpin)<=678) { // key down start up active
lcd.setCursor(0, 1);
lcd.print(getString(STR_SET_DEFAULT_ALARM)); //R.0.5f
sound.play(DTMF[4], 500);
for (int i=0; i <= 31; i++){
alm_h[i+1]=def_par[(i*4)];
EEPROM.write((i*4), def_par[(i*4)]);
alm_m[i+1]=def_par[(i*4)+1];
EEPROM.write((i*4)+1, def_par[(i*4)+1]);
pat[i+1]=def_par[(i*4)+2];
EEPROM.write((i*4)+2,def_par[(i*4)+2]);
med[i+1]=def_par[(i*4)+3];
EEPROM.write((i*4)+3, def_par[(i*4)+3]);
}
} else {
for (int i=0; i <= 31; i++){
alm_h[i+1]=EEPROM.read(i*4);
alm_m[i+1]=EEPROM.read((i*4)+1);
pat[i+1]=EEPROM.read((i*4)+2);
med[i+1]=EEPROM.read((i*4)+3);
}
delay (1000);
}
//set start Time(hr,min,sec,day,month,yr);
//setTime(12,00,00,21,11,2012);
// set RTC DS1307 as current time source R.1.0.0
setSyncProvider(RTC.get);
//test leds and buzzer for 2 second
sound.play(DTMF[1], 500);
allOn(1);//all led on patient 1
lcd.setCursor(0, 1);
lcd.print("Patient_TEST__01");
delay (1000);
//lcd.setCursor(0, 0);
lcd.setCursor(0, 1);
lcd.print("Patient_TEST__02");
allOff();
sound.play(DTMF[1], 500);
allOn(0);//all led on patient 2
delay (1000);
//lcd.setCursor(0, 0); //R.0.5d
allOff();
lcd.clear();
}// end setup
//*************************************************************************************
//*************************************************************************************
void loop() {
// adj real time correction(increase adjs second for day"
if (hour() == 23 && minute() == 59 && second() == 60-adjs){
setTime(23,59,59,day(),month(),year());
// also update RTC
RTC.set(now());
}
// automatic legal time correction +1
if (ltime==1 && hour() == 2 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 3 && day() > 24 ){
setTime(03,00,00,day(),month(),year());
memltime=0;
// also update RTC
RTC.set(now());
}
// automatic legal time correction -1
if (memltime == 0 && ltime==1 && hour() == 3 && minute() == 00 && second() == 00 && weekday() == 1 && month()== 10 && day() > 24 ){
setTime(02,00,00,day(),month(),year());
memltime=1;
// also update RTC
RTC.set(now());
}
// verify if is active all's alarms (1-32)
// PS.: The first section n. 0 is used for view segnalation alarm when active
for (int i=1; i <= 32; i++){
if (alm_h[i] == hour() && alm_m[i] == minute() && med[i] != 0 && prg==0 && memalarm == 0 ){
alarm = 1;
alm_h[0] = alm_h[i];
alm_m[0] = alm_m[i];
pat[0] = pat[i];
med[0] = med[i];
}
} // end for i active alarms
//read status button acknoleg
push = 0; //reset memory push pressed
//// assign the push button read select
inputbuttons();
if (keyCFG== HIGH) {push = 5; }// key cgf system select
if (keyESC== HIGH) {push = 4; }// key esc select
if (keyDW== HIGH) {push = 3; }// key down select
if (keyUP== HIGH) {push = 2; }// key up select
if (keyACK== HIGH) {push = 1; }// key ENTER/ACK select
if (push == 2) {
byte b = i2c_eeprom_read_byte(DEV_ADDR, 0);
Serial.println(b);
Serial.println(vp);
}
if (push == 3) {
vp=vp+1;
i2c_eeprom_write_byte(DEV_ADDR, 0 , vp);
}
if (keyDW== 0 && keyUP== 0 && keyACK== 0 && keyESC== 0 && keyCFG== 0) {mempush = 0; }// reset memory push button & exe function
if (push == 1 && alarm == 1 && mempush == 0) {// acknoleg alarm
mempush=1;
memalarm = 2;
alarm = 0;
rexit();
medic[0] = med[0];
verirow();
}
// reset memory alarm old
if (push == 1 && alarm == 0 && memalarm == 1 && mempush==0) {
mempush = 1;
gen_reset();
}
// verify new minute in alarm for automatically noise off
if (second() == s_old && memalarm == 1) {
alarm = 0;
}
// reset total alarm and memory after minute
if (second() == s_old && memalarm == 2) {
gen_reset();
}
// set start minute memory alarm and view single medicine
if (alarm == 1 && memalarm == 0) {
memalarm = 1;
s_old = 59;
min_old = minute();
mmin = 0;
}// end if set start minute memory alarm
// increase minute counter memory of alarm segnalation
if (memalarm == 1 && min_old != minute()) {
mmin++;
min_old = minute();
}
// reset auto-clear memory alarm segnalation after 30 minutes
if (memalarm == 1 && mmin == 30) {
gen_reset();
}
// generation blink second
if (sold != second()) {
sold = second();
lamp = not lamp;
}
// active alarm noise segnalation
if (lamp == 1 && alarm == 1 && memalarm != 2) {
noise_alarm();//call noise alarm segnalation
} else {
si=0;
}
//write the time & date o LCD
if (prg == 0){
lcd.setCursor(0, 0);
printDigits(hour());// hour current time
if (lamp == 1) {lcd.print("*");
} else {
lcd.print(":");
} //segnalation run second
printDigits(minute());//minute current time
//view date & patient blinking if alarm is run
if (lamp == 1 && memalarm == 1) {
//reset all led
allOff();
lcd.setCursor(0, 0);
printDigits(alm_h[0]);
lcd.print(".");
printDigits(alm_m[0]);
lcd.setCursor(6, 0);
lcd.print(getString(STR_PATIENT));
lcd.setCursor(14, 0);
printDigits(pat[0]);
lcd.setCursor(0, 1);
lcd.print(getString(STR_MEDICINE));
lcd.setCursor(14, 1);
printDigits(med[0]);
} else {
medic[0] = med[0];
verirow();
//view current date
lcd.print("_");
printDigits(day());
lcd.print("/");
printDigits(month());
lcd.print("/");
printDigits(year());
}
if (prg == 0 && memalarm == 0){
lcd.setCursor(0, 1);
lcd.print(getString(STR_NO_ALARM));
}
} //end write the time & date in standby mode
configuration(); // call configuration subroutine
/*/////////*/
// Serial.println(ramLibera); //view memory free
//Serial.println(weekday()); //view week day for test legal time
}//end loop program
//************************************************************************
/*/////////*/
//function for check free sram //R.0.5d
//int freeRam () {
// extern int __heap_start, *__brkval;
// int v;
// return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
// }
void noise_alarm(){
//generation noise alarm for patient
if (pat[0]==1) {
si=si+sel_sound1;
if (si > 20) {si=1;}
sound.play(DTMF[si], 50+(sel_sound1*200));
}
if (pat[0]==2) {
si=si+sel_sound2;
if (si > 20) {si=1;}
sound.play(DTMF[si], 50+(sel_sound2*200));
}
}
void configuration(){
// configuration system program parameters
if (prg == 81) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_HOURS));// by tuxduino
lcd.setCursor(0, 1);
ho_old = ho_old + tast;
if (ho_old > 23 || ho_old < 0) {ho_old = 0;}
tast = 0;
printDigits(ho_old);
}
if (prg == 82) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_MINUTES));// by tuxduino
lcd.setCursor(0, 1);
mi_old = mi_old + tast;
if (mi_old > 59 || mi_old < 0) {mi_old = 0;}
tast = 0;
printDigits(mi_old);
}
if (prg == 83) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_DAY));// by tuxduino
lcd.setCursor(0, 1);
da_old = da_old + tast;
if (da_old > 31 || da_old < 1) {da_old = 1;}
tast = 0;
printDigits(da_old);
}
if (prg == 84) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_MONTH));// by tuxduino
lcd.setCursor(0, 1);
mo_old = mo_old + tast;
if (mo_old > 12 || mo_old < 1) {mo_old = 1;}
tast = 0;
printDigits(mo_old);
}
if (prg == 85) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_YEAR));// by tuxduino
lcd.setCursor(0, 1);
ye_old = ye_old + tast;
if (ye_old > 2030 || ye_old < 1970) {ye_old = 2012;}
tast = 0;
printDigits(ye_old);
}
if (prg == 86) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_ADJ_SEC));// by tuxduino
lcd.setCursor(0, 1);
adjs = adjs + tast;
if (adjs > 59 || adjs < 0) {adjs = 0;}
tast = 0;
printDigits(adjs);
}
if (prg == 87) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_LEGAL_TIME));// by tuxduino
lcd.setCursor(0, 1);
ltime = ltime + tast;
if (ltime > 1 || ltime < 0) {ltime = 0;}
tast = 0;
printDigits(ltime);
memltime=0;
}
if (prg == 88) {
byte lang;
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_LANG));// by tuxduino
lcd.setCursor(0, 1);
lang = getCurrLang() + tast;
if (lang > LANG_LAST) {
lang = LANG_FIRST;
}
setCurrLang(lang);
tast = 0;
printDigits(lang);
memltime=0;
}
if (prg == 89) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_SOUND_PAT_1));// by tuxduino
lcd.setCursor(0, 1);
sel_sound1 = sel_sound1 + tast;
//check the sound patient n.1 selected
if (sel_sound1 > 9 || sel_sound1 < 0) {sel_sound1 = 0;}
EEPROM.write(129,sel_sound1);
tast = 0;
printDigits(sel_sound1);
memltime=0;
}
if (prg == 90) {
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_SOUND_PAT_2));// by tuxduino
lcd.setCursor(0, 1);
//check the sound patient n.2 selected
sel_sound2 = sel_sound2 + tast;
if (sel_sound2 > 9 || sel_sound2 < 0) {sel_sound2 = 0;}
EEPROM.write(130,sel_sound2);
tast = 0;
printDigits(sel_sound2);
memltime=0;
}
//check the end of configuration system
if (prg == 91) {
lcd.clear();
prg = 0;
sel = 0;
alarm = 0;
memalarm = 0;
tast=0;
mtast=0;
setTime(ho_old,mi_old,0,da_old,mo_old,ye_old); //set new time&date
// also update RTC
RTC.set(now());
}
// configuration parameters of alarms
//increase or decrease hour alarm select
if (prg == 1) {
alm_h[sel+1] = alm_h[sel+1] + tast;
if (alm_h[sel+1] > 23 || alm_h[sel+1] < 0) {alm_h[sel+1] = 0;}
checkhour(alm_h[sel+1]);
//write to eprom the parameter change
EEPROM.write((sel*4)+prg-1, alm_h[sel+1]);
}
//increase or decrease minute alarm select
if (prg == 2) {
alm_m[sel+1] = alm_m[sel+1] + tast;
if (alm_m[sel+1] > 59 || alm_m[sel+1] < 0) {alm_m[sel+1] = 0;}
checkmin(alm_m[sel+1]);
//write to eprom the parameter change
EEPROM.write((sel*4)+prg-1, alm_m[sel+1]);
}
//increase or decrease patient alarm select
if (prg == 3) {
pat[sel+1] = pat[sel+1] + tast;
if (pat[sel+1]> 2 || pat[sel+1] < 1) {pat[sel+1] = 1;}
checkpat(pat[sel+1]);
//write to eprom the parameter change
EEPROM.write((sel*4)+prg-1, pat[sel+1]);
}
//increase or decrease medicine alarm select
if (prg == 4) {
med[sel+1] = med[sel+1] + tast;
if (tast != 0) {mtast=1;}// memory pressure key up or down
//verify patient select for to assigne the medicine
if ((med[sel+1]> 16 || med[sel+1] < 0) && pat[sel+1] == 1) {med[sel+1] = 0;}
// if ((med[sel+1]> 32 || med[sel+1] < 17) && pat[sel+1] == 2) {med[sel+1] = 17;} //bug R05h 24-11-2012
if (med[sel+1]==1 && pat[sel+1] == 2) {med[sel+1] = 17;} //bug R05h 24-11-2012
if ((med[sel+1]> 32 || med[sel+1] < 0 || med[sel+1] ==16) && pat[sel+1] == 2) {med[sel+1] = 0;} //bug R05h 24-11-2012
checkmed(med[sel+1]);
//write to eprom the parameter change
EEPROM.write((sel*4)+prg-1, med[sel+1]);
//parameter view on displey
med[0]=med[sel+1];
pat[0]=pat[sel+1];
verirow();
if (mtast == 1) {// verify pressure key up or down
mtast=0;// reset memory pressure key up or down
verirow();
}
}
if (prg == 5) {//exit prog time and date
gen_reset();//general reset
}
// acknoleg alarms and confirm configurations parameters
if (push == 1 && mempush == 0) {// verify preseed enter button (ACK)
if (mempush ==0 && prg >= 1 && prg < 5 ) {// enter select change parameter of alarm
mempush=1;
prg = prg + 1;
lcd.clear();
rexit();//reset and exit program parameter
}
if (mempush ==0 && prg == 81) {// confirm hour time
mempush=1;
prg = prg + 1;
lcd.clear();
mi_old = minute();//set minute memory for autoexit after 1 minute
rexit();
}
if (mempush ==0 && prg == 82) {// confirm minute time
mempush=1;
prg = prg + 1;
lcd.clear();
da_old = day();
rexit();
}
if (mempush ==0 && prg == 83) {// confirm day date
mempush=1;
prg = prg + 1;
lcd.clear();
mo_old = month();
rexit();
}
if (mempush ==0 && prg == 84) {// confirm month date
mempush=1;
prg = prg + 1;
lcd.clear();
ye_old = year();
rexit();
}
if (mempush ==0 && (prg >= 85 && prg <= 90) ) {// confirm year date, adjs, legal time
mempush=1;
prg = prg + 1;
lcd.clear();
rexit();
}
if (prg == -1) {// editor select alarm for change
mempush=1; //bug Rev.0.5a
prg = 1;
lcd.clear();
rexit();
}
}// end acknoleg alarms
//test pressure key
//// if (push == 1) {Serial.println("ent");}
//// if (push == 2) {Serial.println("up");}
//// if (push == 3) {Serial.println("down");}
// decrease the parameter select
if (push == 3 && prg >= 1 && mempush == 0) { //decrease data
mempush = 1;
tast=-1;
rexit();
}
// increase the parameter select
if (push == 2 && prg >= 1 && mempush == 0) { //increase data
mempush = 1;
tast=1;
rexit();
}
// verify the push pressed for open configuration system
if (push == 5 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) { //open configuration system
mempush = 1;
memalarm=0;
alarm=0;
prg = 81;
ho_old = hour(); //memory old hour before change
lcd.clear();
sel = 0;
rexit();
//push=0;
}
// verify the push pressed for open configuration alarms
if (push == 3 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) { //open configuration parameters alarms
mempush = 1;
memalarm=0;
alarm=0;
prg = -1;
sel = 0;
rexit();
}
// verify the push pressed for open configuration alarms
if (push == 2 && prg == 0 && mempush == 0 && (memalarm == 0 || memalarm ==2)) { //open configuration parameters alarms
mempush = 1;
memalarm=0;
alarm=0;
prg = -1;
sel = 31;
rexit();
}
// increase the alarm view
if (push == 3 && prg == -1 && mempush == 0) { //increase view
mempush = 1;
memalarm=0;
alarm=0;
sel = sel + 1;
rexit();
if (sel > 31) {sel = 31;}
}
// decrease the alarm view
if (push == 2 && prg == -1 && mempush == 0) { //decrease view
mempush = 1;
sel = sel - 1;
rexit();
if (sel < 0) {sel = 0;}
}
// verify the time for insert the new parameter
if ((s_old == second() || push==4) && prg != 0){//reset automatically function if don't touch buttons
lcd.clear();
prg = 0;
sel = 0;
alarm = 0;
memalarm = 0;
med[0]=0;
tast=0;
mtast=0;
//verirow();
allOff();
s_old=second();
rexit();
}
//view the parameters set of alarms
if (prg == -1){
lcd.setCursor(0, 0);
lcd.print("AL");
lcd.print(sel+1);
lcd.print(getString(STR_TIME));
printDigits(alm_h[sel+1]);
lcd.print(".");
printDigits(alm_m[sel+1]);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(getString(STR_PAT));
printDigits(pat[sel+1]);
lcd.print("__Med.:");
printDigits(med[sel+1]);
}
}
void gen_reset(){// general reset clear view all memory segnalation
prg=0;
sel=0;
memalarm = 0;
medic[0]=0;
med[0]=0;
alm_h[0]=0;
alm_m[0]=0;
pat[0]=0;
tast=0;
mtast=0;
lcd.clear();
// reset all led and all line led
allOff();
}
void rexit(){ //reset timer 1 minute for auto exit program
s_old = second()-1;
if (s_old < 0) {s_old = 59;}
sound.play(DTMF[5], 50);
}
void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0
if(digits < 10)
lcd.print('0');
lcd.print(digits);
}// end void printDigit
void checkhour(int digh){// utility for print description set hour of alarm
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_HOUR_AL));// by tuxduino
lcd.print(sel+1);
lcd.print(" ");
lcd.setCursor(0, 1);
tast = 0;
printDigits(digh);
}
void checkmin(int digm){// utility for print description set minute of alarm
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_MIN_AL));// by tuxduino
lcd.print(sel+1);
lcd.print(" ");
lcd.setCursor(0, 1);
tast = 0;
printDigits(digm);
}
void checkpat(int digp){// utility for print description set patient of alarm
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_PATIENT_AL));// by tuxduino
lcd.print(sel+ 1);
lcd.print(" ");
lcd.setCursor(0, 1);
tast = 0;
printDigits(digp);
}
void checkmed(int dige){// utility for print description set medicine of alarm
lcd.setCursor(0, 0);
lcd.print(getString(STR_SET_MEDICINE_AL));// by tuxduino
lcd.print(sel + 1);
lcd.print(" ");
lcd.setCursor(0, 1);
tast = 0;
printDigits(dige);
}
// function set all led to OFF by tuxduino
void allOff() {
byte i;
for (i = 0; i < NUM_COLS; i++) {
pinMode(colPins[i], INPUT);
}
for (i = 0; i < NUM_ROWS; i++) {
pinMode(rowPins[i], INPUT);
}
}
// function set all led to ON by tuxduino
void allOn(byte highOrLow) {
byte i;
for (i = 0; i < NUM_COLS; i++) {
pinMode(colPins[i], OUTPUT);
digitalWrite(colPins[i], highOrLow);
}
for (i = 0; i < NUM_ROWS; i++) {
pinMode(rowPins[i], OUTPUT);
digitalWrite(rowPins[i], !highOrLow);
}
}
void verirow() {
// select patient 1 or 2 and adj number of medicine (modified for insert writeCell on release R05G1)
if(med[0] >16){cnt=med[0]-17; value=0;} else {cnt=med[0]-1; value=1;}
writeCell(cnt,value);
}
// function by tuxduino, insert by Giuseppe G. in the software release R.05G
// cellNumber: 0..ROW*COLS
// value: HIGH=1=patient2 or LOW=0=patient1
void writeCell(byte cellNum, byte value) {
byte row;
byte col;
row = cellNum / NUM_COLS;
col = cellNum % NUM_COLS;
allOff();
pinMode(colPins[col], OUTPUT);
digitalWrite(colPins[col], value);
pinMode(rowPins[row], OUTPUT);
digitalWrite(rowPins[row], !value);
}
//function select button pressed insert on R_1_0_0a
void inputbuttons()
{
int ib=0;
ib = analogRead(analogpin);
if (keycount == 5 && ib>=676 && ib <=678) {keyDW=1; } else {keyDW=0; }// key down
if (keycount == 5 &&ib>=438 && ib <=440) {keyUP=1; } else {keyUP=0; }// key up
if (keycount == 5 &&ib>=240 && ib <=242) {keyACK=1; } else {keyACK=0; }// key ack / Enter
if (keycount == 5 &&ib>=193 && ib <=195) {keyESC=1; } else {keyESC=0; }// key Esc
if (keycount == 5 &&ib>=119 && ib <=121) {keyCFG=1; } else {keyCFG=0; }// key CFG system
if (keycount > 30 ) {keycount=0; } // repeat time key pressed
if (ib < 1000) {keycount++; } else {keycount=0; }// key press = 0
}
//end sketch ArduinoMemory Reminder By Giuseppe G. (FABLAB Torino)
___________________________________________________________________________________________
Bugs da sistemare:
“Al momento nessuno”
ELENCO RELEASE / INFO FIRMWARE ArduoMemoryReminder per hardware R.1.0:
****** IN LAVORAZIONE ******







Lasciate un commento della Vostra impressione, qualsiasi essa sia.
GRAZIE!
Ciao.
Giuseppe G.