Il mondo della domotica compie passi da gigante giorno per giorno, infatti, è una delle branche della tecnologia che si è più evoluta in questi anni. In questo articolo ne vedremo un assaggio e stravolgeremo il modo di utilizzare un ambiente domotico facendo sfiorare il reale al virtuale.
Cosa è la domotica, cosa offre?
Con il termine domotica si intende quella tecnologia che rende più confortevole ed energeticamente ottimizzato l'utilizzo di un ambiente. La parola domotica nasce dall'unione di due parole: domus, termine latino che significa casa, e la parola robotica. Tante sono le opzioni offerte da questa tecnologia; è possibile controllare termostati, luci, serrande motorizzate, insomma tutto quello che può essere azionato manualmente. Parallelamente all'evoluzione elettronica avanza il software che permette di utilizzare queste centraline; d'obbligo le applicazioni per smartphone e web che consentono di controllare da remoto il proprio appartamento. Gli applicativi generalmente sono presentati in due modalità: visualizzando una planimetria dell'ambiente sotto forma d'immagine statica oppure una lista di dipositivi controllabili.
Cosa proponi con questo progetto?
Propongo di realizzare un applicativo che vada oltre oltre la semplice presentazione della planimetria o della lista degli attuatori; propongo di esplorare il proprio appartamento in una realtà virtuale rispecchiando il più possibile il mondo reale. Ovviamente i vantaggi risultano molteplici, infatti potremmo vedere l'effetto dell'illuminazione all'interno di una stanza.
Come procediamo? Di cosa necessito per realizzare il progetto?
Per prima cosa occorre suddividere il progetto in due macro categorie, prodotti Hardware e Software.
Per il controllo degli attuatori, in questo progetto utilizzeremo delle luci, una board Arduino 2009 (attualmente fuori commercio; una quasiasi board Arduino con una porta seriale va bene) ed una serie di LED ad alta luminosità.
Il software ha una notevole valenza, infatti, occupa circa il 90% del progetto. Di seguito i tool free / trial necessari all'implementazione dell'architettura:
- Arduino Compiler
- Unity 3D
- Google Sketchup
L'utilizzo di tool come Sketchup richiedono una base minima di modellazione 3D, è molto semplice da utilizzare ed online troverete un sacco di videotutorial. Unity, invece, richiede un minimo di esperienza nello sviluppo software in C#; esso basa i sui script su tre linguaggi: Javascript, C# e Boo. Inutile dire che C# è il linguaggio meglio supportato ed implementato dell'intera piattaforma.
Iniziamo a realizzare qualcosa? Si ma da cosa partiamo?
Implementiamo la planimetria del nostro appartamento con Sketchup; se la avete a disposizione in 2D, digitalizzatela ed importatela(File-> Import). Non avendo a disposizione quella del mio appartamento, ho fatto una piccola ricerca su Google image, trovando quella qui di seguito:
Image Credits:feelhomeinrome
Importata l'immagine, iniziamo con lo strumento "Line" a tracciare il perimetro dell'appartamento; quando raggiungerete il punto di partenza del tracciato, verrà creato un solido:
Rendiamo la costruzione tridimensionale utilizzando lo strumento "Push/Pull". Basterà semplicemente avvicinarsi ai segmenti colorati di azzurro e, tenendo premuto il tasto sinistro del mouse, muovere verso l'alto. Effettuando questa operazione dobbiamo tenere sempre sotto controllo l'altezza, visibile nel riquadro in basso a destra:
Procediamo con la creazione degli altri muri per completare l'appartamento, il risultato dovrebbe rispecchiare l'immagine qui di seguito:
Completate le opere murarie, sbizzarriamoci inserendo oggetti, colorando i muri e così via dicendo. Per fare questo, utilizziamo il modulo 3D Warehouse di Sketchup. Questo modulo contiene tutti gli oggetti 3D creati dalla community di Sketchup; qui troverete tutto il necessario per arredare la vostra casa. Data la mia quasi totale assenza di istinto da Interior Designer, ho rispettato la disposizione dei mobili disegnati sulla planimetria 2D ottenendo questo risultato:
Posizionati gli elementi di arredo, dobbiamo inserire il pavimento eliminando l'immagine bidimensionale della planimetria (fate attenzione nell'eliminare l'immagine: potreste eliminare l'intera struttura!):
Realizziamo nuovamente il pavimento attraverso lo strumento "Rectangle". Posizionatevi in un angolo della planimetria, tenendo premuto il tasto sinistro del mouse, portatevi nell'angolo opposto a quello di partenza. Creato il rettangolo, eliminate le zone esterne all'appartamento lasciando semplicemente il pavimento interno alla casa; il risultato dovrebbe essere simile a questo:
Carina, vero? Esportiamo l'oggetto 3D rendendolo compatibile con Unity, quindi, clicchiamo su File e poi Export. Selezioniamo il formato File .*fbx e successivamente spuntiamo le seguenti opzioni di esportazione:
- Export two-sided faces;
- Export texture maps;
- Scale Units: meters.
Abbiamo l'oggetto 3D, procediamo con l'import in Unity
L'import (del file precendetemente esportato) in Unity richiede qualche passaggio in più per essere compatibile al 100%. L'esportazione da Sketchup provoca la perdita dei collegamenti delle texture sul modello 3D, per questo motivo seguiamo questi semplici passaggi per risolvere il problema:
Create un nuovo progetto Unity e cliccate con il tasto destro del mouse sulla cartella Assets nominandola con il nome che più vi aggrada. Selezionate tutte le immagini presenti nella cartella affiancata al file *.fbx ed incollatele all'interno della cartella creata in precedenza. Fatto questo, possiamo importare il nostro modello 3D, quindi Assets->Import new Asset; Unity provvederà automaticamente alla ricerca delle textures e ad applicarle nel miglior modo possible.
Ultimo step per completare l'import è cambiare la scala del modello, quindi cliccate sul file contenuto nella cartella Assets ed impostate attraverso l'Inspector il valore 1 alla proprietà Scale Factor:
Non dimenticate di cliccare sul tasto Apply!.
Applicata la scala sull'oggetto, aggiungiamo un plane da GameObject->Create Other->Plane e successivamente trasciniamo il modello 3D sul Plane:
Se avete ottenuto lo stesso risultato, allora siete ad un OTTIMO punto!
Impostiamo i punti luminosi!
Questa fase è abbastanza custom: potete impostare quante luci volete nei punti più disparati; quindi accedete al menù GameObject->Create Other-> Point Light e posizionatela dove più vi aggrada:
Dopo aver impostato il punto luce, dobbiamo necessariamente assegnare ad esso un Box Collider. Attraverso questo componente riusciremo ad intercettare il Mouse Click event per effettuare l'attuazione sulla luce. Tenendo il focus sul componente luminoso andiamo su Component->Physics->Box Collider. All'interno dell'Inspector troverete il physics appena aggiunto:
Non dimenticate di spuntare la voce Is Trigger; questa proprietà è estremamente importante per catturare il click all'interno dello script.
Ed ora la parte più interessante: il protocollo di comunicazione
Per far chiarezza sul da farsi, fate riferimento al workflow qui di seguito:
Come è possibile notare, il computer host invierà attraverso la porta seriale un buffer contenente dei byte. Successivamente, la board Arduino si occuperà di leggere il buffer ed effettuare le attuazioni richieste. Il protocollo di comunicazione occuperà massimo 3 byte suddivisi in con questa logica:
- 1° byte - firma del pacchetto: byte necessario per il riconoscimento del buffer da parte della scheda Arduino. Sarà costantemente valorizzato con il valore 0xFF;
- 2° byte - indentifica l'attuatore su cui effettuare l'ON/OFF; in poche parole il pin fisico digitale della board Arduino;
- 3° byte - identifica l'operazione di spegnimento o accensione da effettuare sull'attuatore identificato dal byte precedente.
Prendete con le pinze questo protocollo, ognuno può crearsene uno proprio, è semplicemente di esempio per lo scopo
Di seguito il codice da flashare sull'Arduino board:
/* * Serial Protocol * Antonio Blescia * */ byte buffer[3]; byte LENGHTBUFFER = 0x03; byte SIGNATURE = 0xFF; void setup() { Serial.begin(9600); } //Main Loop void loop() { //Verifico se il buffer della seriale contiene 3byte if (Serial.available() == LENGHTBUFFER) { //Leggo il buffer con un delay di 10ms buffer[0] = Serial.read(); delay(10); buffer[1] = Serial.read(); delay(10); buffer[2] = Serial.read(); } //Se la signature corrisponde a quella richiesta if(buffer[0] == SIGNATURE) { //Effettuo l'attuazione specificata nel terzo byte sul nodo identificato dal secondo byte digitalWrite(buffer[1],buffer[2]); } //Ripulisco il buffer memset(buffer,0,sizeof(buffer)); }
Il codice è abbastanza semplice; i commenti dovrebbero essere sufficienti per farvi comprendere al meglio il funzionamento. Le attuazioni vengo effettuate sulla base di quello che viene spedito dal sistema che ospita l'applicazione 3D. Utilizzando questo tipo di approccio si è diminuita in maniera drastica la dimensione del firmware, delegando la scelta dell'attuatore su cui effettuare il controllo al device più performante, in questo caso il pc.
Il Socket client su Unity
Prima di iniziare a scrivere il codice occorre vedere alcuni punti teorici. Ogni classe diachiarata deve necessariamente ereditare la classe MonoBehaviour; essa contiene tutti i metodi e gli attributi utili a gestire il lifecycle e gli eventi su un oggetto all'interno della scena. Funzioni fondamentali di lifecycle sono Start() e Update(); la prima funzione viene richiamata non appena l'oggetto viene inserito all'interno della scena, la seconda funzione viene richiamata ogni qualvolta viene aggiornato il frame (se il gioco viene eseguito a 50 frame per secondo, esso sarà richiamato 50 volte ogni secondo). OnMouseDown(), infine, viene richiamata ogni volta che viene intercettato l'evento click.
Data questa "infarinatura" teorica generale, procediamo alla creazione del client che invia il buffer contenente i dati fordamentali citati in precedenza. Creiamo un nuovo Assets da Assets-> Create -> C# Script; successivamente nominiamolo in SwitchLamp (il nome non è obbligatorio).
Ecco il contenuto dello script:
using UnityEngine; using System.Collections; using System.IO.Ports; using System.Net.Sockets; public class SwitchLamp : MonoBehaviour { private SerialPort _serialPort; private GameObject _light; private AudioSource _audioSource; public AudioClip _audioClip; private byte _code; void Start () { this.light.enabLED = false; //Apro la porta serial di Arduino _serialPort = new SerialPort ("/dev/tty.usbserial-A600euoH", 9600); _serialPort.Open (); } // Update is calLED once per frame void Update () { } void OnMouseDown(){ //Avvio l'effetto audio del click _audioSource = gameObject.AddComponent<AudioSource>(); _audioSource.clip = _audioClip; _audioSource.Play(); //Ricavo l'oggetto del componente che invoca l'evento _light = GameObject.Find (this.name); //Invero lo stato della luce _light.light.enabLED = !_light.light.enabLED; //Corrisponde al nome dell'oggetto che invoca l'evento switch (_light.light.name) { case "CameraLight1": _code = 0x02; break; case "CameraLight2": _code = 0x03; break; case "CameraLight3": _code = 0x04; break; } if (!_light.light.enabLED) { //Se spento _serialPort.Write(new byte[]{0xFF,_code,0x00},0,3); } else { //Se acceso _serialPort.Write(new byte[]{0xFF,_code,0xFF},0,3); } _audioSource = null; } }
Salviamo lo script ed assegnamolo ad ogni object di tipo luce inserito nella scena. Per fare ciò, basterà trascinarlo nell'inspector di ogni oggetto:
Il risultato
Conclusioni
Scopo finale del progetto è quello di simulare le attuazioni su un ambiente virtule che rispecchino il più possibile la realtà. In questo articolo abbiamo semplicemente trattato la base per poter simulare e controllare degli attuatori reali; successivamente si potrebbero creare delle attuazioni su elettroserrature e serrande per esempio. Ovviamente la fantasia è alla base di tutto!
Il modello 3D della casa che abbiamo realizzato potrebbe essere stampato con una stampante 3D e "arredato" con gli oggetti estrapolati da Google WareHouse! Ricordate che l'export del modello era stato realizzato utilizzando i metri? Così facendo risulterà tutto scalato a dovere e rispecchierà la realtà al 100%!
Prossimo step del progetto sarà quello di utilizzare il modello 3D stampato, posizionando fisicamente dei LED interfacciati a loro volta ad una board Arduino; il tutto controllato attraverso le brainwaves!
Spero che questo nuovo approccio alla domotica abbia attirato la vostra attenzione! Non vedo l'ora di leggere i vostri commenti a riguardo; saranno sicuramente molto utili per l'implementazione di nuove funzionalità!
Sembra davvero incredibile…
Però devo ammettere che senza il video non sarebbe stato altrettanto chiaro.
Chissà com'è vederlo in funzione dal vivo 🙂
Bell’articolo Antonio, l’ho letto solo ora grazie a un link su facebook 🙂
Bellissimo!
Avevo installato Sketchup ma non lo avevo utilizzato avevo fatto delle piccole prove.
Abituato ad Autocad non mi trovavo con questo programma e quindi non avevo approfondito, ma con i passaggi che hai illustrato ho rivalutato la cosa ed affronterò con più attenzione tutto il discorso.
Esistono più versioni di Sketchup? Se si quale mi consigli?
Vorrei disegnare oggetti 3d ma con misure determinate, in pratica vorrei stabilire spessori e misure impostandoli.
Grazie per il bellissimo articolo.
Un’ultima domanda non ho ben capito il ruolo di Arduino.
Si ho visto nel filmato che accende dei led e quindi con la seriale invia al pc e nell’immagine virtuale si accendono.
In ogni caso risulta utile per far corrispondere ad azioni od eventi reali un’azione nell’ambiente virtuale.
Comunque grazie molto interessante.
Sergio
Bellissimo!
Voglio provare a farlo anche io sul mio appartamento.. 🙂
Ciao,
interessante! E’ possibile fare anche il contrario, ovvero azionare interruttori reali che cambiano l’accensione di luci dentro il modello di Unity o è complicato?
Andrea
Ciao a tutti sono nuovo e appena abbonato ho letto questo articolo ed è veramente interessante, volevo capire qual’è il comando su unity che dice ad arduino quale pin comandare e cosa fare?
da quello che ho capito dovrebbe essere questo “_serialPort.Write(new byte[]{0xFF,_code,0x00},0,3);”
ma non riesco a capire quale valore specifica ad arduino su quale pin intervenire e che valore dargli se HIGH o LOW, poi altra domanda è possibile con questo sistema comandare anche pin PWM?
Grazie
Innanzitutto grazie,
dopodichè volevo chiederti se è possibile dirottare i comandi in tcp/ip, tramite la shell eth?
Grazie