Tecnologia vestible

Per començar Elements d'entrada Elements de control Programació   Recursos CITCEA
Projectes Elements de sortida Elements no electrònics Dades pràctiques   Inici

Hiker

El Hiker consisteix en una canellera que incorpora dues funcions: altímetre i brúixola que es poden alternar prement un polsador i mostren la informació en un Neo Pixel ring.

Pel que fa a la primera funció es es fa servir un sensor GPS i funciona de manera que cada 62,5 m d'alçada s'encendrà un LED i, per tant, la corona sencera de LED encesos serà equivalent a 1000 m d'alçada. Un sistema de colors prèviament determinat ajudarà al senderista a saber exactament si es troba a 120 m o 1120 m. Si ens trobem entre 0 i 1000 m el color dels LED serà el groc, entre 1000 i 2000 m el verd, entre 2000 i 3000 m el blau i entre 3000 i 4000 m seran LED vermells. El sistema no contempla alçades superiors a 4000 m.

Per altra banda, el sensor de camp magnètic farà de brúixola, que consisteix en un LED de color blau que sempre indica el nord i d'un altre de taronja fix al Neo Pixel ring. La funció d'aquest últim LED és senyalar la direcció que té el muntanyenc.

La llista de materials principals és la següent:

1   Placa Flora

1   Neo Pixel ring de 16 LED

1   Sensor GPS

1   Sensor d'acceleració i camp magnètic

1   Polsador

1   Resistència de 10 kΩ

1   Bateria

La figura següent mostra l'esquema del circuit:

esquema

El prototip va quedar com es mostra a les fotografies següents. En una d'elles es mostra la part interior de la canellera (on hi ha la placa Flora, la bateria i el sensor GPS) i en l'altra es veu la part exterior (on tenim el polsador i el Neo Pixel ring). El sensor d'acceleració i camp magnètic està ocult sota la placa Flora.

vista interior

vista exterior

A continuació tenim el llistat del programa:

	//Llibreries
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>
	// NEO PIXEL RING
Adafruit_NeoPixel cadena = Adafruit_NeoPixel(16, 6, NEO_GRB + NEO_KHZ800);
				// Cadena de 16 leds , pota 6 del flora
	// Definim LED de referència
#define TOP_LED  0
int topLED = TOP_LED;
int  a1 = topLED;  // Varíable que comptarà la posició

	// SENSOR CAMP MAGNÈTIC
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);
	// SENSOR GPS
Adafruit_GPS SensorGPS(&Serial1);   // Definim el sensor i li diem que faci servir la connexió Serial1
boolean usingInterrupt = false;     // No farem servir interrupcions
   	 // La funció millis() ens va donant el temps transcorregut en mil·lisegons
   	 // Quan el valor ja no hi cap (al cap d'uns 50 dies) es reinicialitza (torna a zero)
uint32_t timer = millis();   	 // Variable que guarda informació del temps per evitar saturació 
	// POLSADOR
int buttonPin = 10;     // Assignem el polsador a la pota de la placa Flora
int buttonState;    // Variable per llegir l'estat del polsador
int buttonState2;
int lastButtonState = HIGH;    // Lectura previa de l'input
int lastButtonState2 = LOW;
int mode = 0;  // Mode inicial
void setup() {  
	// SENSOR GPS
	Serial.begin(115200);   	 // Comunicació amb l'ordinador
	SensorGPS.begin(9600);   	 // Comunicació amb el sensor GPS
	SensorGPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);    // Configuració del sensor
	SensorGPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // El sensor envia dades un cop cada segon (1 Hz)
	delay(1000);   	 // Espera un segon a que el GPS s'inicialitzi amb la configuració
	// SENSOR CAMP MAGNÈTIC
	Serial.begin(9600);
	// Inicialitza el sensor
	// Si falla, mostra un misatge al monitor sèrie i es bloqueja el programa
	if (!mag.begin()){
		Serial.println("Comprova la connexió amb el sensor");
		while (1);
	}
	// NEOPIXEL RING
	cadena.begin();  // Inicialitza els Neo Pixels   	 
	cadena.show();
	// POLSADOR
	pinMode(buttonPin, INPUT);  // Initialitza el polsador com a INPUT (no necesites OUTPUT)
	digitalWrite(buttonPin, HIGH);
}
void loop() {
	for (int k = 0; k < 16; k++){
		cadena.setPixelColor(k, 0, 0, 0);  // Apaga tots els pixels (0 a 15)
	}
	buttonState = digitalRead(buttonPin);   // Llegeix l'estat del polsador
	buttonState2 = digitalRead(buttonPin);
	if (buttonState == LOW) {   // Si hi ha canvi d'estat en el polsador, canvia el mode.
		if (buttonState == LOW && lastButtonState == HIGH) {
			mode = mode + 1;
		}
		if (mode == 2){
			mode = 0;
		}
	}
	lastButtonState = buttonState;
	if (mode == 0){   // Mode altímetre
		for (int k = 0; k < 16; k++){
			cadena.setPixelColor(k, 0, 0, 0);  // Apaga tots els pixels (0 a 15)
		}
		// GPS
		// Part de conexió amb l'ordinador i extracció de dades
    	char dades = SensorGPS.read();    // Llegim dades del Sensor GPS
		if (SensorGPS.newNMEAreceived()){   
			// Si han arribat dades del sensor
			if (!SensorGPS.parse(SensorGPS.lastNMEA())) {
				// Mira si les dades tenen informació útil
				return;  // Si no, torna a començar el loop per llegir dades noves
			}
		}
		if (SensorGPS.satellites==0){
			//Si no troba satelits fes circumferències blanques fins trobar-ne
			for (int k=0; k<16; k++){
				cadena.setPixelColor(k, 30, 30, 30);   // Pixel de color blanc
				cadena.show(); // Actualitza
				delay(200);  // Espera 
				buttonState2 = digitalRead(buttonPin);  // Llegeix l'estat del polsador
				if (buttonState2 == LOW){
					// Si hi ha canvi d'estat en el polsador, canvia al mode brúixola
					if (buttonState2 == LOW && lastButtonState2 == HIGH){
						mode = 1;
						lastButtonState2 = LOW;
						break;
					} 
				}
				lastButtonState2 = buttonState2;
			}
			// Si tots els leds ja estan encesos, apagals tots 
			for (int k = 0; k < 16; k++){
				cadena.setPixelColor(k, 0, 0, 0);  // Apaga tots els pixels (0 a 15)
			}
			return;
		}
		// Resposta del Neo Pixel ring segons l'altitud donada pel GPS
		for (int k=0; k<16; k++){
			cadena.setPixelColor(k,0,0,0);
		}
		a1=topLED;
		if (SensorGPS.altitude  <= 1062.5){
			for (int h = 62.5; h <= 1062.5; h = h + 62.5) {
				if (SensorGPS.altitude >= h) {
					cadena.setPixelColor(a1, 255, 255, 0);  // Pixel de color groc
					cadena.show();   // Actualitza 
					a1++;
				} else {
					delay(5000);
					break;
				}
			}
		} else if (1062.5 < SensorGPS.altitude  <= 2062.5){
			for (int h = 1062.5; h <= 2062.5; h = h + 62.5) {
				if (SensorGPS.altitude >= h) {
					cadena.setPixelColor(a1, 0, 255, 64);  // Pixel de color verd
					cadena.show();   // Actualitza 
					a1++;
				} else {
					delay(5000);
					break;
				}
			}
		} else if (2062.5 < SensorGPS.altitude  <= 3062.5){
			for (int h = 2062.5; h <= 3062.5; h = h + 62.5) {
				if (SensorGPS.altitude >= h) {
					cadena.setPixelColor(a1, 15, 201, 240);  // Pixel de color blau
					cadena.show();   // Actualitza 
					a1++;
				} else {
					delay(5000);
					break;
				}
			}
		} else if (3062.5 < SensorGPS.altitude  <= 4062.5){
			for (int h = 3062.5; h <= 4062.5; h = h + 62.5) {
				if (SensorGPS.altitude >= h) {
					cadena.setPixelColor(a1, 255, 0, 0);  // Pixel de color vermell
					cadena.show();   // Actualitza 
					a1++;
				} else {
					delay(5000);
					break;
				}
			}
		}
	}
	if (mode == 1){  // Mode brúixola
		for (int k = 0; k < 16; k++){
			cadena.setPixelColor(k, 0, 0, 0);  // Apaga tots els pixels (0 a 15)
		}    
		// SENSOR CAMP MAGNÈTIC
		float pi = 3.1415927; 
		sensors_event_t event2; 
		mag.getEvent(&event2);
		float angle = (atan2(event2.magnetic.y,event2.magnetic.x) * 180)/pi;
		// Resposta del Neo Pixel ring segons la desviació
		// respecte el Nord donada pel sensor de camp magnètic
		cadena.setPixelColor(a1, 100, 30, 0);
			// Pixel de color taronja que ens marcarà la nostra direcció
		cadena.show();   // Actualitza
		if ((11.25 <= angle) && (angle < 33.75)) {
			cadena.setPixelColor(1, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((33.75 <= angle) && (angle < 56.25)) {
			cadena.setPixelColor(2, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((56.25 <= angle) && (angle < 78.75)) {
			cadena.setPixelColor(3, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((78.75 <= angle) && (angle < 101.25)) {
			cadena.setPixelColor(4, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((101.25 <= angle) && (angle < 123.75)) {
			cadena.setPixelColor(5, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((123.75 <= angle) && (angle < 146.25)) {
			cadena.setPixelColor(6, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((146.25 <= angle) && (angle < 168.75)) {
			cadena.setPixelColor(7, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if (((168.75 <= angle) && (angle <= 180)) || ((-180 <= angle) && (angle < -168.75))) {
			cadena.setPixelColor(8, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-168.75 <= angle) && (angle < -146.25)) {
			cadena.setPixelColor(9, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-146.25 <= angle) && (angle < -123.75)) {
			cadena.setPixelColor(10, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-123.75 <= angle) && (angle < -101.25)) {
			cadena.setPixelColor(11, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-101.25 <= angle) && (angle < -78.75)) {
			cadena.setPixelColor(12, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-78.75 <= angle) && (angle < -56.25)) {
			cadena.setPixelColor(13, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-56.25 <= angle) && (angle < -33.75)) {
			cadena.setPixelColor(14, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		if ((-33.75 <= angle) && (angle < -11.25)) {
			cadena.setPixelColor(15, 0, 0, 100);  // Pixel de color blau
			cadena.show(); // Actualitza
		}
		delay(100);
		for (int k=0; k<16; k++){
			cadena.setPixelColor(k,0,0,0);
		}
	}
}

 

 

 

En aquest web, les fotografies marcades amb [AF] són del web d'Adafruit, les marcades amb [SF] del web d'Sparkfun i les marcades amb [AU] del web d'Arduino.

 

 

 

 

 

 

 

 

 

 

Licencia de Creative Commons
This obra by Oriol Boix is licensed under a Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported License.