Quantcast
Channel: Intermedio
Viewing all articles
Browse latest Browse all 672

IOTree, un albero di natale intelligente, con Intel Edison

$
0
0

Visto che vengo spesso accusato di essere poco coinvolto negli addobbi natalizi quest'anno ho deciso di partecipare attivamente all'allestimento dell'albero.

Avendo appena ricevuto un Intel Edison non potevo non sfruttarlo per rendere l'albero piu' divertente ed intelligente.

Edison

Ne approfitto quindi per scrivere questo articolo, in cui illustrero' passo passo come creare due prese elettriche facilmente comandabili da Edison, utili in questo caso per comandare le luci dell'albero, ma altrettanto per mille altre applicazioni. Mostrero' anche il codice utilizzato per gestirle usando javascript e node.js (quindi facilmente utilizzabile attraverso l'Intel XDK), integrando anche delle richieste ad un webservice REST, trattando dunque con un solo esempio, alcune tecniche che possono rivelarsi utili in diversi campi di utilizzo.

Partiamo subito dal'hardware. Abbiamo bisogno di poter comandare le luci dell'albero, farle accendere e spegnere a nostro piacimento. Invece di modificare le luci, ho pensato di creare due prese elettriche controllabili, che potranno essere riutilizzate per diversi progetti.

Avete bisogno di:

  • Una scatola per cestelli elettrici esterni.
  • Un cestello
  • Due B-prese
  • Una placchetta di copertura.
  • Un cavo elettrico e una presa (Maschio)
  • Per ogni presa serve un relay, io ho utilizzato quelli del Kit Groove.


Partiamo dalla realizzazione delle prese elettriche comandabili.

Qui il materiale utilizzato:Il materiale utilizzato

Qui invece si puo' vedere come ho collegato i relays alle prese.

Collegamenti

Un cavo della linea va ad una delle prese, poi ho fatto un piccolo ponte con un altro cavo all'altra presa.
L'altra cavo di linea va ad uno dei relays, con un ponte verso l'altro.
Infine ho collegato gli altri due cavi provenienti dal relays all'altro polo delle b-prese.

Poi ho inserito tutti i componenti all'interno della scatolina ed ecco, le nostre prese controllabili.

Le prese complete

Sono poi passato al software.
L'idea e' di visualizzare un countdown sul display LCD dell'albero con il tempo che manca a natale (o a qualunque data vogliate) e controllare periodicamente il meteo e far accendere le luce dell'albero se nevica. Ovviamente vogliamo che le luci si accendano a natale. Inoltre ho aggiunto anche un pulsante che permette il controllo manuale dell'albero. Io ho utilizzato due strisce di luci, ognuna controllata da una presa, ma potete adattare il codice a quante ne volete.
Ma analizziamo ora passo passo il codice utilizzato.
Cominciamo ad includere le librerie che andremo ad utilizzare:

var mraa = require("mraa");
var http = require('http');
var LCD = require('jsupm_i2clcd');

libmraa: ci sara' utile per accedere facilmente ai sensori e alle uscite di Edison.
http: verra' utilizzata per fare il fetch del feed meteo con coi controlleremo se nevica o meno.
jsupm_i2clcd : viene utilizzata per scrivere facilmente sul display LCD

Ora vediamo le funzioni di cui avremo bisogno, ho inserito i commenti nel codice sperando di spiegare a sufficienza cosa succede passo passo.

Per prima cosa, creiamo alcune variabili di supporto:

// numero del pin a cui connetteremo un pulsante per accendere
// e spegnere manualmente le luci dell'albero
var buttonGpio = 8;
// i pin a cui collegeremo i nostri relays, io ne ho usati due, potete aggiungere quelli che preferite.
var relayGpio = [2,3];

// vettore che useremo per inizializzare i relays
var relay = Array();
// variabile che conterra' l'handler del nostro pulsante
var button;

// url di base di openweathermap per accedere al feed meteo
var owmUrl = "http://api.openweathermap.org";
// query da utilizzare per il meteo
var owmPath = "/data/2.5/weather?unit=metric&q="
// la citta dove viviamo
var yourCity = "Brescia,it";

// variabile di supporto che contiene lo stato relativo alla neve
var isSnowing = false;

// variabile che corrispondera' al nostro dislay lcd
var myLcd;

// flag per l'uso manuale
var turnOnLight = false;

Definiamo ora una funzione setup, che inizializzera' tutte le nostre variabili:

// Questa funzione serve a inizializzare le variabili, i pin etc
function setup() {

    // il bottone per accendere e spegnere le luci manualmente
    // lo inizializziamo e indichiamo che e' un ingresso
    button = new mraa.Gpio(buttonGpio);
    button.dir(mraa.DIR_IN);


    // inizializziamo tutti i relays, come output
    for ( var i=0; i<relayGpio.length; i++) {
	relay[i] = new mraa.Gpio(relayGpio[i]);
	relay[i].dir(mraa.DIR_OUT);
	relay[i].write(0);
    }

    // ed infine l'lcd
    myLcd = new LCD.Jhd1313m1 (6, 0x3E, 0x62);

}

Ora la funzione per il conto alla rovescia: 

// funzione che serve per il conto alla rovescia
// fino ad arrivare a natale.
function countDown() {

    // natale 2014, ma potete metterci la data che volete
    var end = new Date('12/24/2014 00:00 AM');

    var _second = 1000;
    var _minute = _second * 60;
    var _hour = _minute * 60;
    var _day = _hour * 24;
    var timer;

    var now = new Date(); // la data di oggi

    // calcoliamo ora la distanza tra oggi e la data di fine
    var distance = end - now;
    if (distance < 0) { // l'attesa e' finita.
	// definiamo il messaggio da visualizzare se la data di fine e' raggiunta
	lcdMessage = " !! Merry Christmas !!";
	// scriviamola sull riga 1 dell'lcd
	myLcd.setCursor(1,1);
	myLcd.write(lcdMessage);
	//accendiamo anche le luci!
	turnOnLight = true;
        return;
    }

    // Formattiamo il tempo mancante
    var days = Math.floor(distance / _day);
    var hours = Math.floor((distance % _day) / _hour);
    var minutes = Math.floor((distance % _hour) / _minute);
    var seconds = Math.floor((distance % _minute) / _second);

    // Creiamo la stringa da visualizzare
    lcdMessage = "-" + days + "d:" + hours + "h:" + minutes + "m:" + seconds + "s";
    // Visualizzaimola sul display
    myLcd.setCursor(1,0);
    myLcd.write(lcdMessage);

}

Passiamo ora a scrivere la funzione che scarica un feed json per il meteo, utilizzando le api di openweathermap.org :

// Questa funzione controlla il meteo e
// riporta lo stato attuale sul display
function checkWeather() {
    // costruiamo l'url per la richiesta
    var url = owmUrl + owmPath + yourCity

    try {
	// maggiori info sull'api utilizzata qui : http://openweathermap.org/api

	// creiamo una richiesta http all'url sopra
	http.get(url, function(res) {
	    // qui salviamo il contenuto della risposta del server
	    var body = '';

	    // leggiamo la risposta pezzo per pezzo
	    res.on('data', function(chunk) {
		body += chunk;
	    });

	    // e alla fine della richiesta, leggiamo il risultato
	    res.on('end', function() {
		//facciamo il parsing del risultato per avere un oggetto javascript
		var weather = JSON.parse(body) // il webservice chiamato restituisce un file json, dobbiamo farne il parsing

		// qui trovate la tabelle dei codici che vengono restituiti dal webservice:
		// http://openweathermap.org/weather-conditions
		var id = weather.weather[0].id; // prendiamo il codice delle condizioni per la giornata corrente
		if(id>=600 && id<623) { // i valori compresi tra 600 e 623 indicano neve
		    isSnowing = true; // settiamo la variabile che indica la neve
		    turnOnLight = true; // e si, nevica! vogliamo le luci scintillanti!
		} else {
		    isSnowing = false; // niente neve, almeno per ora.
		}

	    // riportiamo le condizioni meteo sul display
	    lcdMessage = "Weather: "+weather.weather[0].description;
	    myLcd.setCursor(0,0);
	    myLcd.write(lcdMessage);

	    });
	}).on('error', function(e) {
	    // se qualcosa va storto nella richiesta http lo scriviamo sul display

	    lcdMessage = "Weather: ERROR";
	    myLcd.setCursor(0,0);
	    myLcd.write(lcdMessage);

	    console.log("Got error: ", e);

	});
    } catch(e) { // anche qui, se abbiamo una eccezione segnaliamolo
	lcdMessage = "Weather: ERROR";
	myLcd.setCursor(0,0);
	myLcd.write(lcdMessage);
	console.log("can't fecth the weather feed")
    }
};

 

Ci siamo quasi, abbiamo quasi tutti i pezzi che ci occorrono, scriviamo due funzioni, una che accenda tutte le luci ed una che le spenga:

// piccola funzione che accende tutte le luci connesse ai relays
function turnOn(){
    for(var i=0; i<relay.length; i++)
	relay[i].write(1);
}

// funzione per spegnere i relays
function turnOff(){
    for(var i=0; i<relay.length; i++)
	relay[i].write(0);
}

Ok, ora manca solo la funzione che controlli il bottone, e verifichi se sia il caso o meno di accendere le luci:

// questa e' la funzione che controlla se e' stato premuto il bottone
// ed in caso accende o spegne le luci.
// verifica inoltre se sta nevicando o se e' gia' natale ed in caso accende le luci

function makeChristmas() {

    // controlliamo lo stato del bottone
    if (button.read() == 1) {
	// se premuto, cambio lo stato delle luci
	turnOnLight = !turnOnLight;
    }

    // ora verifico se devo accendere le luci o meno
    if(turnOnLight || isSnowing) {
	turnOn(); // FESTA
    } else {
	turnOff(); // NOIA
    }
}

 

ed infine creiamo una funzione di init, e usiamo alcuni timer per far partire tutto quanto:

// funzione di init, inizializza le variabile necessarie
// e avvia il primo controllo meteo
function init() {
    setup()
    checkWeather();
}


// setup di tutte le variabili
init();
// controlliamo ogni 10 millisecondi il bottone, e lo stato
setInterval(makeChristmas, 10)
// ogni secondo aggiorniamo il conto alla rovescia
setInterval(countDown, 1000);
// ogni ora controlliamo il meteo
setInterval(checkWeather, 360000);

 

E abbiamo finito, potete eseguire il codice con l'Intel XDK o da shell richiamando lo script con node.js!

Io mi sono permesso di addobbare creativamente l'albero...
Ecco qualche foto dello splendido IOTree!!

IoTree

Edison al comando

 

Dettaglio

Spero di aver stimolato un po' di curiosita' e fantasia, per i vostri prossimi progetti, per le prossime IOFeste!
Michele

  • Desarrolladores
  • Estudiantes
  • Arduino
  • Linux*
  • Internet de las cosas
  • JavaScript*
  • Intermedio
  • Dirección URL
  • Ejemplo de código
  • Empecemos
  • Bibliotecas
  • Zona de temas: 

    IDZone

    Viewing all articles
    Browse latest Browse all 672

    Trending Articles



    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>