산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Never Ride Alone: 스마트 자전거 안전 시스템

부품 및 소모품

5mm 적색 LED 2
u-blox NEO-6M GPS 모듈 1
Arduino MKR Fox 1200 1
3.7V 리튬 배터리 1
부저 1
푸시버튼 스위치 12mm 1
슬라이드 스위치 1
1kΩ 저항 1
Seeed Grove 진동 센서 (SW-420) 1

필요 도구

프로젝트 개요

안녕하세요, 전자공학도이자 창업가, 그리고 사이클리스트인 Jesús Soriano입니다.

12살부터 자전거를 탔고 주로 혼자 훈련합니다. 그동안 수많은 낙차와 사고를 겪었습니다. 어느 날 깨달았습니다. 심한 사고로 의식을 잃으면 구조 요청을 할 수 없고, 산속에서 혼자라면 죽을 수도 있다.

기존 솔루션의 한계

산악 지대에서는 휴대폰 신호가 안 터지는 경우가 많습니다.

Never Ride Alone (NRA) 탄생

Sigfox 네트워크를 발견했습니다. 저전력 광역 통신으로 휴대폰 신호 없이도 데이터 전송 가능. Arduino MKR FOX 1200(Sigfox 모듈 내장)을 알게 되어 바로 개발 시작.

NRA 작동 방식 - 역방향 알람

  1. 라이딩 시작 시 버튼 눌러 NRA 활성화. LED 점멸 (후방 시인성 향상)
  2. 30초간 움직임 없음 감지 시 → 비상 모드 진입
  3. 부저 울림. 사용자가 끄지 않으면(단순 깜빡임이 아님) 부상자로 판단
  4. 자동으로 GPS 작동 → Sigfox 네트워크로 위도/경도/고도 전송
  5. 등록된 지인/가족에게 이메일 발송 → 구글맵 링크로 위치 확인 가능

디자인 철학

다수 사이클리스트 인터뷰 결과: 사용이 간편하고 배터리 오래 가는 미니멀한 기기 원함. NRA는 버튼만 누르면 끝. 라이딩 후 정지 버튼 누르고 충전만 하면 됨.

케이스는 ABS 플라스틱, 발렌시아 폴리테크닉 대학 3D 프린터로 제작. 설계 파일: Tinkercad에서 편집/다운로드 가능

하드웨어 구성

Sigfox 백엔드 설정

콜백 설정으로 원시 데이터를 위도/경도/고도로 변환. 이메일로 구글맵 링크 자동 발송.

조립 과정

  1. GPS 모듈: VCC, GND, 데이터선만 연결. 안테나는 프레임에 접착
  2. 아두이노를 GPS 위에 적층
  3. 배터리 + 슬라이드 스위치 연결 (전원 ON/OFF)
  4. 배터리 충전 커넥터 추가 (충전 시 OFF 상태)
  5. 드론 배터리 충전기로 충전 테스트 완료
  6. 안테나를 아두이노 위에 배치, 모든 부품을 케이스에 수납

테스트 결과

환경 보호 활동

테스트 라이딩 중 발견한 쓰레기 수거. 지속가능발전목표(SDGs) 실천. 산악 쓰레기 대부분이 사이클리스트 것(에너지바 포장지, 젤, 타이어 튜브)임을 발견. 대회 중 '클린 포인트' 운영으로 쓰레기 버리기 편하게 하고 경기 후 일괄 수거.

안전 라이딩 하세요! :)

코드 (NRA v0.1)

///// NEVER RIDE ALONE V.0.1 /////
#include <SigFox.h>
#include <ArduinoLowPower.h>
#include <TinyGPS.h>

#define WAITING_TIME 10
#define GPS_PIN 2
#define GPS_INFO_BUFFER_SIZE 128

bool debug = true;
const int backlights = 4;
const int pulsador = 5;
const int audio = 3;

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

struct gpscoord { float a_latitude; float a_longitude; float a_altitude; };
float latitude = 0.0f, longitude = 0.0f, altitud = 0;

void Wait(int m, bool s) {
  if (debug) { Serial.print("Waiting: "); Serial.print(m); Serial.println(" min."); }
  digitalWrite(LED_BUILTIN, LOW);
  int seg = s ? m * 30 : m * 15;
  for (int i = 0; i < seg; i++) {
    digitalWrite(backlights, HIGH); delay(500);
    digitalWrite(backlights, LOW); delay(500);
  }
}

void SendSigfox(String data) {
  if (debug) { Serial.print("Sending: "); Serial.println(data); }
  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("No transmission"); else Serial.println("Transmission ok");
  } else { SigFox.endPacket(); }
  SigFox.end();
}

String ConvertGPSdata(const void* data, uint8_t len) {
  uint8_t* bytes = (uint8_t*)data; String cadena;
  for (uint8_t i = len - 1; i < len; --i) {
    if (bytes[i] < 12) cadena.concat(byte(0));
    cadena.concat(char(bytes[i]));
  }
  return cadena;
}

String GetGPSpositon() {
  int messages_count = 0; String pos;
  if (debug) Serial.println("GPS ON");
  digitalWrite(GPS_PIN, HIGH); Wait(1, false);
  while (messages_count < 5000) {
    while (Serial1.available()) {
      int GPS_info_char = Serial1.read();
      if (GPS_info_char == '$') messages_count++;
      if (gps.encode(GPS_info_char)) {
        gps.f_get_position(&latitude, &longitude);
        altitud = gps.altitude() / 100;
        gpscoord coords = {altitud, longitude, latitude};
        if (debug) { /* 상세 출력 생략 */ }
        digitalWrite(GPS_PIN, LOW);
        return ConvertGPSdata(&coords, sizeof(gpscoord));
      }
    }
  }
  return "No Signal";
}

void setup() {
  pinMode(4, OUTPUT); pinMode(backlights, OUTPUT);
  pinMode(pulsador, INPUT); pinMode(audio, OUTPUT);
  if (debug) { Serial.begin(9600); while(!Serial); Serial.println("Serial Connected"); }
  Serial1.begin(9600); while(!Serial1); if (debug) Serial.println("GPS Connected");
  pinMode(GPS_PIN, OUTPUT);
  if (!SigFox.begin()) { Serial.println("Shield error!"); return; }
  if (debug) SigFox.debug(); else SigFox.end();
}

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

CAD 파일

MKR1200, 배터리, 버튼, LED, GPS, 부저 수납 가능: nra_v_0_1_qCsc7I6QvO.zip

회로도

회로도 이미지 참조 (아두이노 사진은 MKR1200 아님)

제조공정

  1. 집적 회로(IC): 현대 전자제품을 구동하는 작고 강력한 칩
  2. C# switch 문 마스터하기: 문법, 예제, 모범 사례
  3. 아두이노 디지털 주사위: LCD 기반 랜덤 넘버 제너레이터 만들기
  4. 스마트 홈 연동을 위한 다중 위치 온도 센서 시스템
  5. DIY 아두이노 USB 게임 컨트롤러 - 나만의 고성능 게임패드 만들기
  6. 아두이노 나노로 테트리스 게임 만들기: DIY 16×8 LED 매트릭스
  7. MotionSense: 아두이노와 ESP8266으로 만드는 스마트 침입 감지 시스템
  8. MOSMusic 프로젝트 키트: MOSFET, 아두이노로 음악 동기화 조명 제어
  9. 드릴링 머신 필수 구성 요소 종합 개요
  10. 내연기관 핵심 부품 완벽 가이드: 구조와 기능