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

Never Ride Alone: Sistema Inteligente de Segurança para Ciclistas

Componentes e Materiais

LED 5mm Vermelho 2
GPS u-blox NEO-6M 1
Arduino MKR FOX 1200 1
Bateria 3.7V 1
Buzzer 1
Chave Pushbutton 12mm SparkFun 1
Chave Deslizante 1
Resistor 1k ohm 1
Sensor de Vibração Seeed Grove (SW-420) 1

Ferramentas Necessárias

Sobre o Projeto

Olá, sou Jesús Soriano, estudante de engenharia eletrônica, empreendedor... e ciclista!

Pedalo desde os 12 anos, geralmente sozinho. Durante treinos, tive muitas quedas, acidentes e imprevistos. Um dia percebi: se eu tivesse um acidente grave e perdesse a consciência, poderia morrer. Estava sozinho nas montanhas!

É mais fácil entender com um vídeo: imagine pedalando, curtindo a paisagem, e de repente um carro aparece e te atropela. Você cai numa ribanceira, o motorista foge. Você fica inconsciente, preso, invisível ao mundo.

Duas ou três horas depois, sua família começa a se preocupar. Serviços de emergência tentam localizá-lo, conseguem após 4-5 horas. Você provavelmente estará morto.

Pesquisei opções: Strava Summit (envia GPS para contatos em acidente), ANGi da Specialized (integrado ao capacete, pede ajuda em colisão). Mas todos precisavam de sinal de celular. Bateria, GPS e sinal móvel eram necessários.

Foi assim que nasceu o Never Ride Alone (NRA). Encontrei o Sigfox como solução para envio de dados nas montanhas, e quando descobri que existia um Arduino com módulo Sigfox... foi perfeito!

Como o NRA Funciona

O NRA funciona como um alarme invertido. Ao sair pedalando, você ativa o NRA pressionando um botão. LEDs piscam, melhorando também a visibilidade. Se o NRA detectar nenhum movimento por 30 segundos, ativa o modo emergência: começa a buzinar. Se ninguém para (você esqueceu de desligar), significa que você está ferido. Automaticamente, o GPS inicia e envia a localização via rede Sigfox para seus contatos (família/amigos).

Design Minimalista

Consultei muitos ciclistas e cheguei a um design minimalista. Ciclistas querem gadget fácil de usar e com boa bateria. Com NRA, só pressiona o botão e pedala. Após treino, para e carrega.

O gabinete é de plástico ABS, impresso em 3D na Universidade Politécnica de Valência.

Arquivos de design editáveis/baixáveis: Tinkercad

Componentes Utilizados

Configuração no Backend Sigfox

Quando o Arduino envia dados, o servidor converte dados brutos em informação. No meu caso, uso longitude, latitude e altitude. Com isso, envio e-mail para contatos configurados com link do Google Maps para localizar o ciclista ferido.

Montagem

  1. Módulo GPS: apenas positivo, negativo e fio de dados. Antena colada no quadro. Arduino por cima.
  2. Bateria conectada ao Arduino com chave liga/desliga.
  3. Conector de bateria para recarga (deve estar desligado durante carga). Usei carregador de bateria de drone – funcionou perfeitamente.
  4. Após fiação, antena sobre o Arduino. Montagem apertada mas viável com atenção.

Nesta versão, não usei o sensor de vibração. O NRA envia posição GPS a cada 10 minutos. Resultados bons. Testado em estradas – experiência muito positiva.

É realmente fácil de usar e dá a sensação de ter um bom gadget nas mãos.

Sustentabilidade

Da equipe Never Ride Alone, também tentamos melhorar o planeta. Durante testes, recolhemos todo lixo visto nas montanhas. Segundo Objetivos de Desenvolvimento Sustentável, tentamos remover todo lixo encontrado.

Percebemos que a maior parte do lixo nas montanhas vem de ciclistas! Plásticos de barras energéticas, géis e pneus. Agora, tentamos conscientizar ciclistas. Em provas, criamos pontos de coleta onde podem jogar lixo sem parar/perder tempo. Área delimitada, limpa ao final da prova.

Obrigado por ler, e pedale seguro :)

Código

NEVER RIDE ALONE V.0.1 Arduino

Código NRA. Não usa sensores. Envia todos os dados GPS a cada 10 minutos.

///// NEVER RIDE ALONE V.0.1 ///// 
//.............................// 
////AUTOR: JESUS SORIANO ADAM//// 
////////FECHA: 05/05/2019 /////// 
///////////////////////////////// 

#include <SigFox.h> 
#include <ArduinoLowPower.h> 
#include <TinyGPS.h> 

#define WAITING_TIME 10 // tempo de espera entre mensagens (min) 
#define GPS_PIN 2 // (pino transistor, para economia de energia. não usado agora) 
#define GPS_INFO_BUFFER_SIZE 128 

bool debug = true; 

const int backlights = 4; 
const int pulsador = 5; 
const int audio = 3; 

TinyGPS gps; 

// Variáveis GPS 
int year; 
byte month, day, hour, minute, second, hundredths; 
unsigned long chars; 
unsigned short sentences, failed_checksum; 
char GPS_info_char; 
char GPS_info_buffer[GPS_INFO_BUFFER_SIZE]; 
unsigned int received_char; 
bool message_started = false; 
int i = 0; 

// Estrutura coordenadas GPS, 12 bytes em plataformas 32 bits 
struct gpscoord { 
  float a_latitude;  // 4 bytes 
  float a_longitude; // 4 bytes 
  float a_altitude;  // 4 bytes 
}; 

float latitude = 0.0f; 
float longitude = 0.0f; 
float altitud = 0; 

//////////////// Função Espera //////////////// 
void Wait(int m, bool s) { 
  // m = minutos para esperar 
  // s = pulso lento do LED 
  if (debug) { 
    Serial.print("Aguardando: "); 
    Serial.print(m); 
    Serial.println(" min."); 
  } 
  digitalWrite(LED_BUILTIN, LOW); 
  if (s) { 
    int seg = m * 30; 
    for (int i = 0; i < seg; i++) { 
      digitalWrite(backlights, HIGH); 
      delay(500); 
      digitalWrite(backlights, LOW); 
      delay(500); 
    } 
  } else { 
    int seg = m * 15; 
    for (int i = 0; i < seg; i++) { 
      digitalWrite(backlights, HIGH); 
      delay(500); 
      digitalWrite(backlights, LOW); 
      delay(500); 
    } 
  } 
} 

/////////////////// Função Envio Sigfox //////////////// 
void SendSigfox(String data) { 
  if (debug) { 
    Serial.print("Enviando: "); 
    Serial.println(data); 
    if (data.length() > 12) { 
      Serial.println("Mensagem muito longa, apenas primeiros 12 bytes serão enviados"); 
    } 
  } 
  
  SigFox.begin(); 
  delay(100); 
  SigFox.status(); 
  delay(1); 
  if (debug) SigFox.debug(); 
  delay(100); 
  
  SigFox.beginPacket(); 
  SigFox.print(data); 
  
  if (debug) { 
    int ret = SigFox.endPacket(true); 
    if (ret > 0) Serial.println("Sem transmissão"); 
    else Serial.println("Transmissão OK"); 
    Serial.println(SigFox.status(SIGFOX)); 
    Serial.println(SigFox.status(ATMEL)); 
    if (SigFox.parsePacket()) { 
      Serial.println("Resposta do servidor:"); 
      while (SigFox.available()) { 
        Serial.print("0x"); 
        Serial.println(SigFox.read(), HEX); 
      } 
    } else { 
      Serial.println("Sem resposta do servidor"); 
      Serial.println("Verifique cobertura Sigfox na sua área"); 
      Serial.println("Se em ambiente interno, verifique cobertura 20dB ou aproxime de janela"); 
    } 
    Serial.println(); 
  } else { 
    SigFox.endPacket(); 
  } 
  SigFox.end(); 
} 

//////////////////// Conversão GPS //////////////////// 
/* Converte dados float GPS para Char */ 
String ConvertGPSdata(const void* data, uint8_t len) { 
  uint8_t* bytes = (uint8_t*)data; 
  String cadena; 
  if (debug) { 
    Serial.print("Tamanho: "); 
    Serial.println(len); 
  } 
  for (uint8_t i = len - 1; i < len; --i) { 
    if (bytes[i] < 12) { 
      cadena.concat(byte(0)); 
    } 
    cadena.concat(char(bytes[i])); 
    if (debug) Serial.print(bytes[i], HEX); 
  } 
  if (debug) { 
    Serial.println(""); 
    Serial.print("String a enviar: "); 
    Serial.println(cadena); 
  } 
  return cadena; 
} 

//////////////////// Obter Posição GPS //////////////////// 
String GetGPSpositon() { 
  int messages_count = 0; 
  String pos; 
  if (debug) Serial.println("GPS LIGADO"); 
  digitalWrite(GPS_PIN, HIGH); // Liga GPS 
  Wait(1, false); 
  
  while (messages_count < 5000) { 
    while (Serial1.available()) { 
      int GPS_info_char = Serial1.read(); 
      if (GPS_info_char == '$') messages_count++; 
      
      if (debug) { 
        if (GPS_info_char == '$') { 
          message_started = true; 
          received_char = 0; 
        } else if (GPS_info_char == '*') { 
          for (i = 0; i < received_char; i++) { 
            Serial.write(GPS_info_buffer[i]); 
          } 
          Serial.println(); 
          message_started = false; 
        } else if (message_started == true) { 
          if (received_char <= GPS_INFO_BUFFER_SIZE) { 
            GPS_info_buffer[received_char] = GPS_info_char; 
            received_char++; 
          } else { 
            message_started = false; 
            received_char = 0; 
          } 
        } 
      } 
      
      if (gps.encode(GPS_info_char)) { 
        gps.f_get_position(&latitude, &longitude); 
        altitud = gps.altitude() / 100; 
        
        gpscoord coords = {altitud, longitude, latitude}; 
        gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths); 
        
        if (debug) { 
          Serial.println(); 
          Serial.print("Lat/Long: "); 
          Serial.print(latitude, 5); 
          Serial.print(", "); 
          Serial.println(longitude, 5); 
          Serial.print("Data: "); 
          Serial.print(day, DEC); Serial.print("/"); 
          Serial.print(month, DEC); Serial.print("/"); 
          Serial.print(year); 
          Serial.print(" Hora: "); 
          Serial.print(hour, DEC); Serial.print(":"); 
          Serial.print(minute, DEC); Serial.print(":"); 
          Serial.print(second, DEC); Serial.print("."); 
          Serial.println(hundredths, DEC); 
          Serial.print("Altitude (m): "); 
          Serial.println(gps.f_altitude()); 
          Serial.print("Rumo (graus): "); 
          Serial.println(gps.f_course()); 
          Serial.print("Velocidade (km/h): "); 
          Serial.println(gps.f_speed_kmph()); 
          Serial.print("Satélites: "); 
          Serial.println(gps.satellites()); 
          Serial.println(); 
          digitalWrite(backlights, HIGH); 
          delay(500); 
          digitalWrite(backlights, LOW); 
          delay(500); 
        } 
        
        gps.stats(&chars, &sentences, &failed_checksum); 
        if (debug) Serial.println("GPS desligado"); 
        digitalWrite(GPS_PIN, LOW); 
        pos = ConvertGPSdata(&coords, sizeof(gpscoord)); 
        return pos; 
      } 
    } 
  } 
  pos = "Sem Sinal"; 
  return pos; 
} 

//////////////////// SETUP //////////////////// 
void setup() { 
  pinMode(4, OUTPUT); 
  pinMode(backlights, OUTPUT); 
  pinMode(pulsador, INPUT); 
  pinMode(audio, OUTPUT); 
  
  if (debug) { 
    Serial.begin(9600); 
    while (!Serial) {} 
    Serial.println("Serial Conectado"); 
  } 
  
  // Serial1 pinos 13-14 para conexão 3.3V ao GPS 
  Serial1.begin(9600); 
  while (!Serial1) {} 
  if (debug) Serial.println("GPS Conectado"); 
  
  pinMode(GPS_PIN, OUTPUT); 
  
  if (!SigFox.begin()) { 
    Serial.println("Erro no shield ou não presente!"); 
    return; 
  } 
  
  if (debug) { 
    SigFox.debug(); 
  } else { 
    SigFox.end(); // Sono profundo 
  } 
} 

////////////////////// LOOP ////////////////////// 
void loop() { 
  String position_data; 
  position_data = GetGPSpositon(); 
  SendSigfox(position_data); 
  Wait(WAITING_TIME, false); 
}

Peças Personalizadas e Gabinetes

Cabe o MKR1200, bateria, botão, LEDs, GPS e buzzer.

Arquivo: nra_v_0_1_qCsc7I6QvO.zip

Esquemáticos

Nota: a foto do Arduino na imagem não é o MKR1200.

Diagrama disponível no projeto original.

Processo de manufatura

  1. Circuitos Integrados (CIs): Chips Compactos e Poderosos Impulsionando a Eletrônica Moderna
  2. Dominando a Instrução Switch em C#: Sintaxe, Exemplos e Boas Práticas
  3. Dados Digital com Arduino: Gere Números Aleatórios 1-6 em LCD 16x2
  4. Sistema Multi-Posição de Sensores de Temperatura para Integração em Casa Inteligente
  5. Controle USB para Jogos DIY com Arduino – Construa Seu Próprio Gamepad de Alto Desempenho
  6. Construa um Jogo Tetris com Arduino Nano em Matriz LED 16×8 DIY
  7. MotionSense: Detecção Inteligente de Intrusão com Arduino e ESP8266
  8. Kit MOSMusic: MOSFET, Arduino e Mais - Iluminação Sincronizada com Música
  9. Componentes Essenciais de uma Máquina de Furar: Visão Geral Completa
  10. Principais Componentes de um Motor de Combustão Interna