Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Componentes y suministros

Arduino 101 × 1
Pilas AA + Portapilas 4×AA × 1
Accessory Shield (para Arduino) × 1
Sensor de presión BMP180 (Adafruit) × 1
GPS Ultimate Breakout (Adafruit) × 1
Sensor magnético 3 ejes (Adafruit HMC5883) × 1
Sensor de humedad AM2320 (Adafruit) × 1
Pilas botón CR2012 (para RTC) × 2
Resistencias 10 kΩ y 3.9 kΩ × 1 c/u

Herramientas y máquinas necesarias

Aplicaciones y servicios en línea

Sobre este proyecto

¿Qué es Hiking Tracker?

El Hiking Tracker es un dispositivo para detectar cambios en el entorno del senderista durante la caminata. La idea es observar variaciones de temperatura, presión, humedad, altitud, ubicación, dirección, etc. Ofrece información interesante sobre la ruta.

En montaña, donde hace frío, aire seco y baja densidad, cuesta respirar y algunos sufren irritación cutánea. Este dispositivo permite a los aficionados conocer sus límites. También está la diversión de alcanzar gran altitud; ¡poder saber la altitud es divertido!

No solo montañas: explorar pantanos, desiertos, bosques – cada uno con su perfil ambiental único – monitorizar el entorno en marcha ayuda a entender mejor la naturaleza.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Paso 1: Hardware – ¿qué para qué?

Hay mucha sensorización en este proyecto.

El Accessory Shield trae dispositivos I2C a bordo:

En el Arduino Uno (shield):

Paso 2: Modificando y conectando el hardware

Pocas modificaciones en el Arduino Uno. Se monta sobre el portapilas 4×AA con separadores roscados y silicona caliente.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería
Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Se instalan 4 pilas AA y CR1220 (para RTC) en sus portapilas.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería
Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Hay espacio entre el portapilas y la placa Arduino donde caben sensores de presión, humedad, magnético y GPS.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería
Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Los sensores I2C se sueldan juntos en una placa de pruebas y se colocan en ese espacio.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería
Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Estos sensores se conectan al Arduino desde la cara inferior:

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Se añade un divisor de tensión para medir el voltaje de las 4 pilas AA.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

La línea de medición de voltaje va al ADC A1:

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

El joystick del shield está mapeado al pin A1 a través de A5. Por eso se desuelda y retira.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Conectando pads en el Accessory Shield (ver esquema en referencias) con puentes de soldadura, se hacen disponibles D2 (reset suave), D3, D9, D10 en la interfaz XBee.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería
Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

La pila de componentes queda así:

Y las conexiones son así:

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Paso 3: Programando el dispositivo

Se usa Arduino IDE Build 1.8.5. Primero se incluyen/descargan todas las librerías necesarias mediante el gestor de librerías.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Escribiendo el nombre del sensor en la búsqueda aparecen las librerías adecuadas.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Algunas librerías del Accessory Shield (ver referencias) se añaden vía archivo .zip.

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Tras añadir librerías, se revisan los ejemplos de cada sensor para conocer sus APIs.

Luego se incluyen todos los headers en un sketch vacío.

Lista de headers

math.h, inttypes.h, Wire.h, lm75.h, ADXL345.h, ChainableLED.h,
U8glib.h, ds3231.h, Adafruit_Sensor.h, Adafruit_AM2320.h,
Adafruit_BMP085_U.h, Adafruit_HMC5883_U.h, Adafruit_GPS.h

Tras múltiples ediciones, compilaciones, depuración (incluyendo conexiones sueltas, donde descubrí que el BMP180 funciona sin Vcc por fuga de potencia en pines I2C) y subidas, el código quedó listo.

Las advertencias (caveats)

Alcance de mejoras

Mejoras en firmware para más funciones:

Mejoras en hardware:

Conclusión

Viajar y hacer senderismo es genial, y poder consultar los cambios del entorno lo hace más interesante. Especialmente ver altitud, humedad, presión y temperatura cambiar en horas de caminata. Este dispositivo te dice a qué altura sientes mal de altura, qué humedad reseca la piel, etc. Aunque hay margen de mejora en circuito y código para resolver las advertencias, ¡es genial tener un gadget así en la naturaleza!

Recursos externos

https://www.waveshare.com/wiki/Accessory_Shield

Hardware recomendado para una versión mejor

Kit de prototipado rápido

Código

Hiking_Tracker.ino

/*/////////// NOTE ///////////
 D2 permite soft reset desde código
 D3,D9,D10 disponibles en interfaz XBee (pines 12,13,16)
 D4, D13 no accesibles
///////////////////////////*/

//// HEADER FILES FOR LIBRARY /////
#include <math.h>
#include <inttypes.h>
#include <Wire.h>
#include <lm75.h>
#include <ADXL345.h>
#include <ChainableLED.h>
#include "U8glib.h"
#include "ds3231.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_AM2320.h"
#include <Adafruit_BMP085_U.h>
#include <Adafruit_HMC5883_U.h>
#include <Adafruit_GPS.h>

///////////////////// RTC Variables ///////////////////
uint8_t time[8];
struct ts t;
int s, m, h, dy, mo, yr;

///////////////// Accelerometer Variables /////////////
float X=0.0, Y=0.0, Z=0.0, Gravity=0.0;

///////////////// Magnetometer Variables //////////////
float Xm=0.0, Ym=0.0, Zm=0.0;

//////////////////// RGB LED Variables ////////////////
const int rgb_pwr = 12;
const int clk_pin = 6;
const int data_pin = 5;
float hue = 0.0;
boolean up = true;

//////////////////// Potentiometer ////////////////////
int pot = 0;

//////////////////// Batt/Supply Vin //////////////////
float Vbatt = 0.0;

////////////////////// Thermometer ////////////////////
float temp = 0.0;

///////////////////// Humidity ////////////////////////
float humid = 0.0;

//////////////////// Air pressure /////////////////////
double prsr = 0.0;

//////////////////// Altitude /////////////////////////
float alt = 0.0;

//////////////// Lat, Long ////////////////////////////
float lat = 0.0, lon = 0.0;

///////////////// Compass Heading /////////////////////
float heading = 0.0;

///////////////// Other Variables /////////////////////
int mstime = 0;
int sensor_selector = 1;

//////////// ENUM // I2C Device type Object ////////////
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0); // OLED I2C
TempI2C_LM75 termo = TempI2C_LM75(0x48, TempI2C_LM75::nine_bits); // Temp I2C
ADXL345 accelerometer; // Accel I2C
ChainableLED leds(clk_pin, data_pin, rgb_pwr, 1); // RGB LED I2C
Adafruit_AM2320 am2320 = Adafruit_AM2320(); // Humid I2C
Adafruit_BMP085_Unified bmp180 = Adafruit_BMP085_Unified(10085); // Press I2C
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); // Compass I2C

// Descomenta las 2 líneas siguientes para activar GPS
// Serial Debugging no estará disponible
// HardwareSerial mySerial = Serial;
// Adafruit_GPS GPS(&mySerial);

void setup(void) {
  // 1.1V Internal Analog Ref (opcional)
  // analogReference(INTERNAL);

  // Señales para OLED en Accessory Shield
  // Puentes de soldadura en shield necesarios para D2,D3,D9,D10
  pinMode(2, OUTPUT); // self reset D2 a RST
  pinMode(3, OUTPUT); // salida en XBee int 12
  pinMode(9, OUTPUT); // salida en XBee int 13
  pinMode(10, OUTPUT); // salida en XBee int 16
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);

  // 10k POT en A0
  // Vin Batt/Supply en A1 (3.91k/21.76k)

  // Serial Comm para Debug (opcional)
  // Serial.begin(9600);

  // Accel Init Waiting
  if (!accelerometer.begin()) delay(50);

  // RTC Interrupt enabling
  DS3231_init(DS3231_INTCN);

  // Buzzer Init
  pinMode(11, OUTPUT);
  digitalWrite(11, LOW);
}

void loop(void) {
  // Picture loop
  u8g.firstPage();
  do { draw(); } while (u8g.nextPage());

  // Switch entre sensores I2C
  sensor_selector++;
  if (sensor_selector >= 3) sensor_selector = 0;

  ////// Temperature Fetch API //////
  temp = termo.getTemp();
  delay(5); // °C

  /////// Pressure Fetch API ////////
  if (sensor_selector == 0) {
    if (!bmp180.begin()) delay(11);
    sensors_event_t event;
    bmp180.getEvent(&event);
    if (event.pressure) {
      prsr = event.pressure / 10; // hPa a kPa
      delay(50);
    }
  }

  ////////////// GPS Init //////////
  // GPS.begin(9600);

  /////// Altitude Fetch API ////////
  if (sensor_selector == 0) {
    sensors_event_t event;
    bmp180.getEvent(&event);
    alt = bmp180.pressureToAltitude(1013.25, event.pressure);
    delay(50); // metros
    // bmp180.end();
  }

  ////////////// Humidity Sensor Init ///////
  if (sensor_selector == 1) {
    am2320.begin();
    delay(50);
    humid = am2320.readHumidity();
    delay(50); // % RH
    // am2320.end();
  }

  ////// Acceleration Fetch API //////
  Vector norm = accelerometer.readNormalize();
  X = norm.XAxis; Y = norm.YAxis; Z = norm.ZAxis;
  Gravity = sqrt(X*X + Y*Y + Z*Z) - 0.3; // offset
  // m/s^2

  ///// Time Fetch API //////
  DS3231_get(&t);
  s = t.sec; m = t.min; h = t.hour;
  dy = t.mday; mo = t.mon; yr = t.year;

  ///// Pot Position Fetch //////
  pot = analogRead(A0) * 5 / (10 * 3);
  delay(2);

  ///// VBatt/Supply Fetch //////
  // 1.1 es 1.08 para este chip
  Vbatt = (1.08 * analogRead(A1) / 1023) / 3.91 * ((3.91 + 21.76));
  delay(2);

  ///////// Compass Heading ////////
  if (sensor_selector == 2) {
    if (!mag.begin()) { while(1); }
    delay(70);
    sensor_t sensor2;
    mag.getSensor(&sensor2);
    delay(70);
    // Ángulo declinación depende de geolocalización
    // Usar Lat/Lon GPS para calcular
    sensors_event_t event2;
    mag.getEvent(&event2);
    delay(70);
    float declination = 0.0;
    heading = atan2(event2.magnetic.y, event2.magnetic.x);
    heading += declination;
    if (heading < 0) heading += 2*PI;
    if (heading > 2*PI) heading -= 2*PI;
    heading = heading * 180 / M_PI; // rad a grados
    // mag.end();
  }

  ///// Buzzer Control //////////
  if (pot > 80) digitalWrite(11, HIGH); else digitalWrite(11, LOW);

  ///// RGB Addressable LED Control ///////////
  if (pot > 40) {
    leds.pwr_set(PWR_ENABLE);
    for (byte i = 0; i < 1; i++) leds.setColorHSB(i, hue, 1.0, 0.5);
    if (up) hue += 0.025; else hue -= 0.025;
    if (hue >= 1.0 && up) up = false;
    else if (hue <= 0.0 && !up) up = true;
  }

  ////////// Self Reset ///////////
  // digitalWrite(2, LOW);
}

void draw(void) {
  u8g.setFont(u8g_font_7x13);
  u8g.drawHLine(37, 0, 62);
  u8g.setPrintPos(41, 12); if (h < 10) u8g.print(0); u8g.print(h); u8g.drawStr(54, 12, ":");
  u8g.setPrintPos(62, 12); if (m < 10) u8g.print(0); u8g.print(m); u8g.drawStr(75, 12, ":");
  u8g.setPrintPos(83, 12); if (s < 10) u8g.print(0); u8g.print(s);
  u8g.drawHLine(37, 14, 62);
  u8g.setFont(u8g_font_5x8);
  u8g.drawVLine(37, 0, 14);
  u8g.setPrintPos(0, 7); if (dy < 10) u8g.print(0); u8g.print(dy); u8g.drawStr(11, 7, "/");
  u8g.setPrintPos(17, 7); if (mo < 10) u8g.print(0); u8g.print(mo); u8g.drawStr(0, 16, "/");
  u8g.setPrintPos(6, 16); u8g.print(yr);
  u8g.drawVLine(99, 0, 14);
  u8g.drawStr(104, 7, "BATT");
  u8g.setPrintPos(102, 15); u8g.print(Vbatt); u8g.drawStr(123, 15, "V");

  u8g.print(round(temp)); u8g.drawStr(55, 25, "'C");
  u8g.setFont(u8g_font_5x8);
  u8g.setPrintPos(15, 40); u8g.print(round(X));
  u8g.setPrintPos(60, 40); u8g.print(round(Y));
  u8g.setPrintPos(100, 40); u8g.print(round(Z));
  u8g.setPrintPos(95, 22); u8g.print(Vbatt); u8g.drawStr(123, 22, "V");
  u8g.drawVLine(37, 18, 36);
  u8g.drawStr(39, 24, "AIR TEMP: "); u8g.setPrintPos(85, 24); u8g.print(temp); u8g.drawStr(118, 24, "C");
  u8g.drawStr(39, 34, "HUMIDITY: "); u8g.setPrintPos(85, 34); u8g.print(humid); u8g.drawStr(118, 34, "%");
  u8g.drawStr(39, 44, "PRESSURE: "); u8g.setPrintPos(85, 44); u8g.print(prsr); u8g.drawStr(118, 44, "hP");
  u8g.drawStr(39, 54, "ALTITUDE: "); u8g.setPrintPos(85, 54); u8g.print(round(alt)); u8g.drawStr(118, 54, "m");
  u8g.drawHLine(0, 56, 128);
  u8g.drawStr(19, 64, "LAT:"); u8g.setPrintPos(39, 64); u8g.print(23.57); // Demo
  u8g.drawStr(69, 64, "LONG:"); u8g.setPrintPos(94, 64); u8g.print(90.36); // Demo
  u8g.print(round(temp)); u8g.drawStr(55, 25, "'C");

  int r = round(sqrt(X*X + Y*Y));
  u8g.drawStr(0, 22, "heading");
  u8g.drawCircle(18, 34, r, U8G_DRAW_ALL); // círculo interior nivelación
  u8g.drawCircle(18, 34, 10, U8G_DRAW_ALL); // círculo exterior fijo
  u8g.setPrintPos(0, 53); u8g.print(heading); // 0/360=N, 90=E, 180=S, 270=W

  if ((heading > 315) | (heading <= 45)) u8g.drawLine(18, 34, 8, 34); // N
  if ((heading > 45) && (heading <= 135)) u8g.drawLine(18, 34, 18, 24); // E
  if ((heading > 135) && (heading <= 225)) u8g.drawLine(18, 34, 28, 34); // S
  if ((heading > 225) && (heading < 315)) u8g.drawLine(18, 34, 18, 44); // W
}

Librerías

Descomprime y añade los .zip individuales al Gestor de Librerías de Arduino.

Esquemáticos

Rastreador de senderismo avanzado con Arduino: GPS, sensores y batería

Proceso de manufactura

  1. Controle un LED con Sensor PIR de Movimiento en Raspberry Pi
  2. Construya un Sensor de Humedad de Suelo de Bajo Coste para Riego Inteligente con Raspberry Pi
  3. Registre el Ejercicio Diario de su Hámster con un Rastreador de Actividad Raspberry Pi
  4. Prueba del Sensor de Temperatura DS18B20 en Raspberry Pi
  5. Monitor de temperatura casero con Raspberry Pi, MCP9808, InfluxDB y Grafana
  6. Monitor de higiene de inodoro con Walabot
  7. Sensor de Emociones y EEG: Hardware de Bajo Coste para Detección de Emociones en Tiempo Real
  8. Envío de Datos IMU Adafruit 10DOF desde Raspberry Pi 2 a Azure Event Hubs con Windows 10 IoT Core
  9. UnifiedWater v1 – Kit completo de sensor de calidad de agua con Arduino
  10. Entendiendo el sensor de oxígeno (O2): función, ubicación y señales de fallo
  11. Seguimiento preciso de RSSI WiFi para sensores de la ISS