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.