Demo FishinoHomeAuto
Cos'è FishinoHomeAuto ?
FishinoHomeAuto è un'applicazione abbastanza semplice di Fishino nel campo della domotica.
Installazione della demo
Per prima cosa occorre procurarsi una scheda microSD in cui inserire i files della demo.
L'esempio è dentro la libreria Fishino, nella cartella esempi/FishinoHomeAuto. I files da copiare nella microSD si trovano nella cartella STATIC e vanno copiati nella directory radice della scheda; NON copiate tutta la cartella STATIC ma i singoli files, in modo da ottenere il risultato che si vede nell'immagine di sinistra.
Per il momento non modifichiamo nulla; possiamo intravedere l'immagine della casa e le immagini delle lampadine e del termometro, oltre ad alcuni file di contorno
Caricamento dello sketch
Apriamo ora lo sketch FishinoHomeAuto.ino nell'ide, scegliendolo dagli esempi della libreria Fishino; qui utilizziamo la nostra FishIDE, ma potete usare tranquillamente l'IDE di Arduino.
#define STANDALONE_MODE
#define MY_SSID "casamia"
#define MY_PASS "1234"
#define IPADDR 192, 168, 1, 10
#define GATEWAY 192, 168, 1, 1
#define NETMASK 255, 255, 255, 0
Inseriamo la scheda microSD nel nostro Fishino e colleghiamo il tutto al pc; apriamo quindi il monito seriale e vediamo cosa appare!
Se è andato tutto bene, verranno visualizzate alcune informazione sulla connessione e sugli elementi interattivi abilitati nel programma :
Resetting Fishino...OK
Connecting AP...OK
Waiting for IP.........OK
IP Address :192.168.1.251
Setting up SD card...
Found 12 appliances
l1:0:2
l2:0:3
l3:0:5
l4:0:6
l5:0:8
l6:0:9
l7:0:15
l8:0:16
l9:0:17
l10:0:18
l11:0:19
t1:3:0
Init done
Web server starting...
Ready to accept HTTP requests...
Il log del monitor seriale mostra che :
- Ci siamo connessi al nostro access point con l'IP 192.168.1.251
- Abbiamo rilevato 12 componenti del nostro sistema domotico ('appliances')
- I primi 11, nominati da L1 a L11 sono connessi ad uscite digitali (:0) alle porte 2, 3, 5, 6, 8, 9, 15, 16, 17, 18 e 19
- L'ultimo, nominato T1, è un ingresso analogico (:3) connesso alla porta analogica A0 del Fishino
- L'inizializzazione è avvenuta con successo (Init Done)
- Il sistema è pronto ad accettare connessioni dal browser (Web server starting...Ready to accept HTTP requests...)
Tenendo aperto il monitor seriale, apriamo ora il browser ed inseriamoci il nostro indirizzo IP; sul monitor seriale apparirà un log dei files scaricati dal browser:
Vista sul browser
Sul browser appare l'immagine della casa, con le lampadine inizialmente spente ed il termometro che indica una temperatura fittizia, visto che non abbiamo connesso nessun sensore; premendo i vari simboli delle lampadine queste si accenderanno e/o spegneranno, e contemporaneamente le uscite sul Fishino cambieranno stato, cosa che potremmo vedere se avessimo connesso dei LED alle uscite:
File: INDEX.HTM
Read file INDEX.HTM
File: JQUERY.JS
Read file JQUERY.JS
File: MAIN.JS
Read file MAIN.JS
File: FLOOR.JPG
Read file FLOOR.JPG
File: MAP.TXT
Read file MAP.TXT
File: FAVICON.ICO
File: LAMPOFF.PNG
Read file LAMPOFF.PNG
File: TERMO.PNG
Read file TERMO.PNG
TOGGLED APPLIANCE lx
(Stato dell'utenza lx cambiato), dove lx indica il nome dell'utenza.
TOGGLED APPLIANCE l1
TOGGLED APPLIANCE l4
TOGGLED APPLIANCE l9
L'applicazione viene configurata tramite pochi files; il file index.htm contenente il codice html e, dentro questo, il collegamento all'immagine della casa, il file map.txt che mappa gli I/O di Arduino con le utenze e le posizioni delle stesse sull'immagine ed alcuni files con le immagini (floor.jpg, lampon.png, lampoff.png, termo.png).
Vediamo in dettaglio i vari files, nei punti principali.
Il file map.txt
Vediamo per primo il file map.txt, che è un semplice file di testo contenente dati in formato JSON :
{
"l1" : {"kind":"do", "io" : "2", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 93, "y" : 367 },
"l2" : {"kind":"do", "io" : "3", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 230, "y" : 374 },
"l3" : {"kind":"do", "io" : "5", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 179, "y" : 469 },
"l4" : {"kind":"do", "io" : "6", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 237, "y" : 504 },
"l5" : {"kind":"do", "io" : "8", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 286, "y" : 224 },
"l6" : {"kind":"do", "io" : "9", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 326, "y" : 353 },
"l7" : {"kind":"do", "io" : "15", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 348, "y" : 461 },
"l8" : {"kind":"do", "io" : "16", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 323, "y" : 183 },
"l9" : {"kind":"do", "io" : "17", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 428, "y" : 171 },
"l10" : {"kind":"do", "io" : "18", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 428, "y" : 398 },
"l11" : {"kind":"do", "io" : "19", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 573, "y" : 403 },
"t1" : {"kind":"ai", "io" : "0", "image" : "termo.png", "x" : 520, "y" : 211, "scale" : 0.1, "delta" : -5, "prec" : 1, "textpref" : "", "textsuff" : "°C", "textx": 20, "texty" : 15 }
}
Come si nota, sono presenti 2 parentesi graffe che racchiudono tutto il blocco, ed una serie di linee che descrivono le varie utenze. Vediamo in dettaglio una linea relativa ad una lampadina:
"l1" : {"kind":"do", "io" : "2", "imageoff" : "lampoff.png", "imageon" : "lampon.png", "x" : 93, "y" : 367 },
La linea inizia col nome dell'utenza tra virgolette ("l1"), seguita da un carattere di due punti (:) ed una lista di elementi racchiusi tra parentesi graffe, il tutto terminato da una virgola (,). Il formato del file è determinante; anche un solo piccolo errore, come ad esempio la mancanza di una virgola o un carattere sbagliato e non funziona nulla.
Tra le parentesi graffe gli elementi sono del tipo chiave:valore, dove la chiave è un nome tra virgolette (stringa) ed il valore è o una stringa, sempre tra virgolette, o un numero. Tutte le utenze iniziano col descrivere il tipo di utenza (kind) e l'I/O alla quale è connessa (io):
"kind":"do", "io" : "2", .....
Come si può facilmente intuire, "do" sta per "Digital Output", ovvero uscita digitale. Per il termometro avremo "ai", che sta per "Analog Input", ovvero ingresso analogico. Nella linea di esempio abbiamo quindi un'uscita digitale connessa all'I/O 2 di Fishino.
Attualmente nel codice javascript in main.js sono implementati i soli I/O digitali e l'input analogico; è comunque relativamente semplice imlementare anche un controllo tipo slider o potenziometro per un output analogico.
I valori successivi dipendono dal tipo di controllo; per i controlli di tipo digitale abbiamo 2 nomi di immagini, uno che rappresenta il valore LOW, in questo caso una lampadina spenta, l'altro che rappresenta l'immagine del valore HIGH, in questo caso una lampadina accesa :
"imageoff" : "lampoff.png", "imageon" : "lampon.png", ...
In questo caso abbiamo le immagini "lampoff.png" e "lampon.png". Per ultimo abbiamo la posizione della lampadina sull'immagine relative all'angolo in basso a sinistra della stessa; in questo caso al punto 93;367. La posizione si riferisce al centro dell'immagine dell'elemento, per facilitarne il posizionamento. Sempre in questo caso, al centro del cerchio che rappresenta le lampadine
Per gli input analogici, ovvero il nostro termometro, cambia poco :
"t1" : {"kind":"ai", "io" : "0", "image" : "termo.png", "x" : 520, "y" : 211, "scale" : 0.1, "delta" : -5, "prec" : 1, "textpref" : "", "textsuff" : "°C", "textx": 20, "texty" : 15 }
Qui l'immagine è una sola ("image"), in questo caso il file "termo.png"; successivamente abbiamo la posizione sull'immagine della casa (520, 211) e 2 valori di conversione che servono a trasformare il valore analogico letto (che va, sulle schede Fishino, da 0 a 1023) in un valore che rappresenta la temperatura. La formula utilizzata è :
temp = val · scale + delta
Dove 'temp' è la temperatura visualizzata, 'val' è il valore letto con digitalRead e 'delta' è una costante aggiuntiva. Modificando i valori di 'scale' e 'delta' possiamo quindi adattare la lettura a qualsiasi sensore analogico a disposizione. Per capire come fare, supponiamo che il nostro sensore di temperatura ci restituisca i seguenti valori :
220 per una temperatura di -10 gradi
1100 per una temperatura di 50 gradi
Ricaviamo il valore di 'scale' tramite :
scale = (50 - (-10)) / (1100 - 220) = 0.0681818
E successivamente il valore di 'delta' :
delta = temp - val · scale = 50 - 1100 · 0.06818 = -25
Ovviamente il discorso funziona bene con sensori che rispondono in modo lineare alla temperatura; una NTC, per esempio, NON è lineare se non per un campo sistretto di temperatura, per cui occorrerebbe un'interpolazione più complicata (quadratica o cubica), con l'introduzione di più costanti nel file e conseguente modifica del javascript in main.js.
A seguire abbiamo 2 stringhe, che costituiscono il prefisso ed il suffisso del valore da visualizzare ('textpref' e 'textsuff'); in questo caso vogliamo visualizzare il numero senza alcun prefisso e con l'indicazione dei gradi centigradi "°C" come suffisso.
Per ultimo abbiamo ancora 2 coordinate, che rappresentano dove poszionare il testo con la temperatura rispetto all'immagine del termometro; se le mettiamo entrambe a 0 ci troveremo il testo posizionato al centro del termometro, cosa non bellissima; in questo caso l'abbiamo spostato di 20 e 15 pixels rispettivamente verso destra e verso il basso per avere una visualizzazione più chiara.
Il file index.htm
Questo file è un semplicissimo file HTML contenente lo stretto indispensabile per visualizzare l'immagine, il richiamo ai nostri 2 javascript di gestione ed un paio di stili CSS per ottimizzare il posizionamento degli elementi :
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<meta name="HandheldFriendly" content="True" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="main.js"></script>
<title>Fishino Home Automation Demo</title>
</head>
<body>
<h1><center>FishinoHomeAuto demo application</center></h1>
<style>
#container {
position:relative;
display:table;
margin: 0 auto;
}
.itemcontainer {
position:absolute;
display:block;
}
.imtip {
position:relative;
}
.texttip {
position:absolute;
}
</style>
<div id="container" align="center" border-color="red" border-width=2>
<img src="floor.jpg"/>
</div>
</body>
</html>
In questo file potete cambiare praticamente tutto, dall'immagine di sfondo in poi. Con un po di modifiche allo sketch ed al formato del file map.txt è possibile anche realizzare un'applicazione completa su più pagine.