| Per començar | Elements d'entrada | Programació CircuitPython | Recursos CITCEA | |
| Elements no electrònics | Elements de sortida | Programació Arduino | ||
| Projectes | Elements de control | Dades pràctiques | Inici |
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 Neo Pixel ring de 16 LED
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:

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.


A continuació tenim el llistat del programa:
//biblioteques #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.

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.