Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Componentes e Materiais

Ferramentas Necessárias

Software

Sobre o Projeto

O Que é o Hiking Tracker?

O Hiking Tracker é um dispositivo para detectar mudanças no ambiente ao redor do caminhante durante a trilha. A ideia é observar variações de temperatura, pressão, umidade, altitude, localização, direção etc., fornecendo insights interessantes sobre a caminhada.

Em montanhas, onde o ar é frio, seco e rarefeito, muitas pessoas sentem dificuldade para respirar ou irritação na pele seca. Este dispositivo permite que entusiastas conheçam seus limites. Também é divertido saber a altitude atingida!

Não só montanhas: explorando pântanos, desertos, florestas — cada um com perfil ambiental único — monitorar o ambiente em tempo real é uma forma melhor de entender a natureza.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Passo 1: Hardware – Para Que Serve Cada Item

O Accessory Shield já traz vários dispositivos I2C a bordo:

No Arduino Uno (via shield):

Passo 2: Modificando e Conectando o Hardware

O Arduino Uno é montado sobre o suporte de 4 pilhas AA com espaçadores e cola quente.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria
Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Pilhas AA e CR1220 (RTC) instaladas.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria
Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Há um espaço entre o suporte de pilhas e o Arduino onde cabem os sensores de pressão, umidade, magnético e GPS.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria
Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Sensores I2C soldados juntos em uma placa de perfuração e colocados nesse espaço.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria
Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Sensores conectados ao Arduino pelo lado inferior.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Divisor de tensão para medir voltagem das 4 pilhas AA.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Linha de leitura da bateria vai para ADC A1.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

O joystick do shield usa o pino A5, por isso foi dessoldado e removido.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Ponte de solda no shield libera pinos D2 (soft reset), D3, D9, D10 na interface XBee.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria
Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Empilhamento final:

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Passo 3: Programando o Dispositivo

Usado Arduino IDE 1.8.5. Bibliotecas incluídas ou instaladas via Gerenciador de Bibliotecas.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Buscando pelo nome do sensor no gerenciador, as bibliotecas aparecem.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Bibliotecas do Accessory Shield (ver referências) adicionadas via .zip.

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Após adicionar, exemplos de cada sensor foram revisados para obter as APIs. Todos os headers incluídos em um sketch vazio.

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

Após múltiplas edições, compilações, depuração (incluindo conexão solta onde descobri que o BMP180 funciona sem Vcc por vazamento nos pinos I2C) e upload, o código ficou pronto.

Ressalvas (Caveats)

Escopo de Melhorias

Firmware:

Hardware:

Conclusão

Caminhadas e trilhas são legais, mas quando você pode conferir as mudanças no ambiente, fica mais interessante. Especialmente ver altitude, umidade, pressão e temperatura mudando em poucas horas. Este dispositivo mostra em que altura você sente mal de altitude, qual umidade resseca a pele, etc. Embora haja espaço para melhorias no layout e código, ainda é legal ter um gadget assim na natureza!

Recursos Externos

Waveshare Accessory Shield Wiki

Hardware Recomendado para Versão Melhorada

Kit de Prototipagem Rápida

Código

Hiking_Tracker.ino (C/C++)

/*/////////// NOTE ///////////
 D2 permite soft reset via código
 D3,D9,D10 disponíveis via interface XBee (pinos 12,13,16)
 D4, D13 não acessíveis
/////////////////////////////*/

//// HEADER FILES /////
#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>

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

///////////////// Variáveis Acelerômetro ///////////////
float X=0.0, Y=0.0, Z=0.0, Gravity=0.0;

///////////////// Variáveis Magnetômetro ///////////////
float Xm=0.0, Ym=0.0, Zm=0.0;

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

////////////////////// Potenciômetro ///////////////////
int pot = 0;

////////////////////// Bateria/Alimentação ////////////
float Vbatt = 0.0;

////////////////////// Termômetro /////////////////////
float temp = 0.0;

////////////////////// Umidade ////////////////////////
float humid = 0.0;

////////////////////// Pressão ////////////////////////
double prsr = 0.0;

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

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

////////////////////// Bússola ////////////////////////
float heading = 0.0;

////////////////////// Outras /////////////////////////
int mstime = 0;
int sensor_selector = 1;

//////////// ENUM / Objetos I2C ///////////////
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; // Acel I2C
ChainableLED leds(clk_pin, data_pin, rgb_pwr, 1); // RGB LED
Adafruit_AM2320 am2320 = Adafruit_AM2320(); // Umidade I2C
Adafruit_BMP085_Unified bmp180 = Adafruit_BMP085_Unified(10085); // Pressão I2C
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); // Bússola I2C

// Descomente para habilitar GPS (Serial debugging não estará disponível)
// HardwareSerial mySerial = Serial;
// Adafruit_GPS GPS(&mySerial);

void setup(void) {
  // Referência analógica interna 1.1V
  // analogReference(INTERNAL);

  ///// Sinais para OLED no Accessory Shield /////
  // Ponte de solda no shield necessária para D2,D3,D9,D10
  pinMode(2, OUTPUT); // self reset D2 -> RST
  pinMode(3, OUTPUT); // saída no XBee int 12
  pinMode(9, OUTPUT); // saída no XBee int 13
  pinMode(10, OUTPUT); // saída no 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 no A0
  // Vin Bateria no A1 (divisor 3.91k/21.76k)

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

  ///// Init Acelerômetro /////
  if (!accelerometer.begin()) delay(50);

  ///// RTC Interrupt Enable /////
  DS3231_init(DS3231_INTCN);

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

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

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

  ///// Temperatura /////
  temp = termo.getTemp();
  delay(5);

  ///// Pressão /////
  if (sensor_selector == 0) {
    if (!bmp180.begin()) delay(11);
    sensors_event_t event;
    bmp180.getEvent(&event);
    if (event.pressure) {
      prsr = event.pressure / 10; // hPa para kPa
      delay(50);
    }
  }

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

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

  ///// Umidade /////
  if (sensor_selector == 1) {
    am2320.begin();
    delay(50);
    humid = am2320.readHumidity();
    delay(50);
  }

  ///// Aceleração /////
  Vector norm = accelerometer.readNormalize();
  X = norm.XAxis; Y = norm.YAxis; Z = norm.ZAxis;
  Gravity = sqrt(X*X + Y*Y + Z*Z) - 0.3; // offset

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

  ///// Potenciômetro /////
  pot = analogRead(A0) * 5 / (10 * 3);
  delay(2);

  ///// Tensão Bateria /////
  // 1.1V é 1.08 neste chip
  Vbatt = (1.08 * analogRead(A1) / 1023) / 3.91 * ((3.91 + 21.76));
  delay(2);

  ///// Bússola /////
  if (sensor_selector == 2) {
    if (!mag.begin()) while(1);
    delay(70);
    sensor_t sensor2;
    mag.getSensor(&sensor2);
    delay(70);
    // Declinação depende da localização (use GPS para calcular)
    sensors_event_t event2;
    mag.getEvent(&event2);
    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; // graus
  }

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

  ///// LED RGB /////
  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;
  }

  ///// Auto 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.setPrintPos(40, 25); 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.setPrintPos(40, 25); 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 interno de nivelamento
  u8g.drawCircle(18, 34, 10, U8G_DRAW_ALL); // círculo externo fixo
  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
}

Bibliotecas

Descompacte e adicione os zips individuais ao Gerenciador de Bibliotecas do Arduino.

Esquemático

Rastreador de Trilha Avançado com Arduino: GPS, Sensores e Bateria

Processo de manufatura

  1. Entendendo o Sensor de Oxigênio (O2): Função, Localização e Sinais de Falha
  2. Controle um LED com Sensor de Movimento PIR no Raspberry Pi
  3. Construa um Sensor de Umidade do Solo de Baixo Custo para Irrigação Inteligente com Raspberry Pi
  4. Monitore o Exercício Diário do Seu Hamster com Rastreador de Fitness Raspberry Pi
  5. Testando o Sensor de Temperatura DS18B20 no Raspberry Pi
  6. Construa Monitor de Temperatura Doméstico com Raspberry Pi, MCP9808, InfluxDB e Grafana
  7. Monitor de Higiene de Vaso Sanitário com Walabot
  8. Sensor de Emoção & EEG: Hardware de Baixo Custo para Detecção de Emoções em Tempo Real
  9. Enviando Dados do IMU Adafruit 10DOF do Raspberry Pi 2 ao Azure Event Hubs com Windows 10 IoT Core
  10. Rastreamento Preciso de RSSI WiFi para Sensores na ISS