工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Never Ride Alone:サイクリストのためのスマート安全システム

必要な部品と材料

部品数量
5mm LED:赤2
u-blox Ublox neo 6m GPS1
Arduino MKR Fox 12001
バッテリー、3.7V1
ブザー1
SparkFun プッシュボタンスイッチ 12mm1
スライドスイッチ1
抵抗 1kオーム1
Seeed Grove - 振動センサー (SW-420)1

必要なツールと機械

プロジェクト概要

こんにちは、私はヘスス・ソリアーノ、電子工学の学生、起業家……そしてサイクリストです!

Never Ride Alone:サイクリストのためのスマート安全システム

12歳から自転車に乗っていて、通常は一人でトレーニングしています。これまでにたくさんの転倒、事故、その他のトラブルを経験しました。ある日、激しい事故で意識を失ったら、私は死ぬかもしれないと気づきました。山の中で一人きりだったのです!

少し動画で想像してみてください。自転車に乗って景色を楽しんでいると、突然車が現れて轢かれる。斜面を転落し、運転手は逃走。あなたは意識を失い、閉じ込められ、世界から見えない存在になります。

2〜3時間後、家族が心配し始める。救急隊があなたを特定しようとするが、4〜5時間後にようやく発見。その時点ではおそらく手遅れです。

そこで調査を始め、いくつかの興味深い選択肢を見つけました:まず、Strava Summitというアプリ。事故時にGPS位置を友人に送信できます。SpecializedのAngiも選択肢でした。ヘルメットに統合され、衝突時に助けを呼べます。しかし問題がありました。これらすべてのシステムは**モバイル電話の電波**が必要です。バッテリー、GPS、モバイル電波のすべてが必要だったのです。

それが「Never Ride Alone(NRA)」誕生のきっかけです。データ送信のソリューションとしてSigfoxを見つけ、ArduinoにSigfoxモジュールがあることを知ったとき、これは素晴らしいと思いました!

Never Ride Alone:サイクリストのためのスマート安全システム

NRAは「逆アラーム」のように動作することにしました。サイクリングに出かけるとき、ボタンを押してNRAを起動。LEDが点滅し、視認性も向上します。30秒間動きが検出されない場合、緊急モードを発動。ブザーが鳴り、誰も止めない場合(危険ではなく、単にオフし忘れただけなら)は怪我をしていると判断。自動的にGPSモジュールが作動し、Sigfoxネットワーク経由でGPS位置情報をすべての友人/家族に送信します。

Never Ride Alone:サイクリストのためのスマート安全システム

多くのサイクリストにヒアリングし、ミニマルなデザインにたどり着きました。サイクリストは使いやすく、バッテリー持ちの良いガジェットを求めています。NRAなら、ボタンを押してペダルを漕ぐだけ。トレーニング後は止めて充電するだけです。

NRAのケースはABSプラスチック製。バレンシア工科大学提供の3Dプリンターで作成しました。

Never Ride Alone:サイクリストのためのスマート安全システム

NRAの設計ファイルはここで編集/ダウンロードできます:

https://www.tinkercad.com/things/fmkE685dNfP-nra-v01

このビルドでは、Arduino MKR1200、Neo 6-m GPS、ボタン、2つのLED、1kオーム抵抗、ブザー、振動センサー、3.7V 150mAhバッテリーを使用します。

Never Ride Alone:サイクリストのためのスマート安全システム

ArduinoとSigfoxの設定を開始しました。これがSigfoxバックエンドページでの私の設定です:

Never Ride Alone:サイクリストのためのスマート安全システム

Arduino MKR1200がデータを送信すると、このサーバーが生データを情報に変換します。私の場合、経度、緯度、高度を使用。この情報で、設定したすべての人(友人、家族など)にメールを送信し、Google Mapsのリンクをクリックすれば負傷したサイクリストの位置がわかります。

Never Ride Alone:サイクリストのためのスマート安全システム

すべてのコンポーネントがケースに収まる様子:

Never Ride Alone:サイクリストのためのスマート安全システム

まずGPSモジュール。プラス、マイナス、データ転送線のみ必要。アンテナはフレームに接着。Arduinoがその上に配置されます。

Never Ride Alone:サイクリストのためのスマート安全システム

バッテリーをArduinoに接続し、スイッチも追加。これでオン/オフ可能です。

Never Ride Alone:サイクリストのためのスマート安全システム

バッテリーコネクターもあり、これでNRAを充電できます。充電時はオフにしておく必要があります。

Never Ride Alone:サイクリストのためのスマート安全システム

このプロジェクトではドローン用バッテリー充電器でNRAを充電しました。完璧に動作しました。

Never Ride Alone:サイクリストのためのスマート安全システム

配線後、アンテナをArduinoの上に配置。すべてのコンポーネントをこのシェルに収めるのは少し複雑ですが、注意深くやれば可能です。

Never Ride Alone:サイクリストのためのスマート安全システム

このビルドでは振動センサーは使用しませんでした。この場合、NRAに電源が入ると10分ごとにGPS位置を送信し続けます。結果は良好でした。

道路沿いでもNRAをテストしました。非常に良い経験でした。

Never Ride Alone:サイクリストのためのスマート安全システム

本当に使いやすく、手元に信頼できるガジェットがあるという安心感があります。

Never Ride Alone:サイクリストのためのスマート安全システム

これがNever Ride Aloneの歴史です。常にあなたを見守るガジェット。いつライドしても、事故の際には必ず位置が特定されるので安心です。

Never Ride Alone:サイクリストのためのスマート安全システム

Never Ride Aloneチームは地球環境の改善にも取り組んできました。すべてのライドテスト中、山で見かけたゴミをすべて拾いました。持続可能な開発目標(SDGs)に従い、ライド中に見つけたすべてのゴミを除去しようとしました。

Never Ride Alone:サイクリストのためのスマート安全システム

拾ったゴミを見て、山のゴミの大半がサイクリスト由来だと気づきました!エナジーバーの包装、ジェル、タイヤなどを大量に回収。今、すべてのサイクリストへの啓発活動を行っています。レース中に「クリーンポイント」を設置し、タイムをロスせずにゴミを捨てられるようにしています。このエリアは区切られており、レース終了後にすべて清掃されます。

Never Ride Alone:サイクリストのためのスマート安全システム

お読みいただきありがとうございました。安全にライドしてください :)

コード

NEVER RIDE ALONE V.0.1 Arduino

NRAコード。センサーは未使用。10分ごとにすべてのGPSデータを送信。

///// NEVER RIDE ALONE V.0.1 /////
//.............................//
// ////AUTOR: JESUS SORIANO ADAM////
// ////////FECHA: 05/05/2019 ///////
/////////////////////////////////
#include <SigFox.h>
#include <ArduinoLowPower.h>
#include <TinyGPS.h> // TinyGPSをインクルード
#define WAITING_TIME 10 // メッセージごとの待機時間(分)
#define GPS_PIN 2 // (トランジスタピン、省電力用。現在は未使用)
#define GPS_INFO_BUFFER_SIZE 128
bool debug = true; ////////DEBUG/////
const int backlights = 4;
const int pulsador = 5;
const int audio = 3;
TinyGPS gps; // GPSオブジェクト
// 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;
// GPS座標構造体、32ビットプラットフォームで12バイト
struct gpscoord {
  float a_latitude; // 4バイト
  float a_longitude; // 4バイト
  float a_altitude; // 4バイト
};
float latitude = 0.0f;
float longitude = 0.0f;
float altitud = 0;
// 待機関数
void Wait(int m, bool s) {
  // m分待機
  // s: 遅いLEDパルス
  if (debug) {
    Serial.print("Waiting: ");
    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);
    }
  }
}
// Sigfoxデータ送信関数
void SendSigfox(String data) {
  if (debug) {
    Serial.print("Sending: ");
    Serial.println(data);
    if (data.length() > 12) {
      Serial.println("Message too long, only first 12 bytes will be sent");
    }
  }
  // EOL削除
  // data.trim();
  // モジュール開始
  SigFox.begin();
  // 初回設定後少なくとも30ms待機(前回は100ms)
  delay(100);
  // すべての保留割り込みをクリア
  SigFox.status();
  delay(1);
  if (debug) SigFox.debug();
  delay(100);
  SigFox.beginPacket();
  SigFox.print(data);
  if (debug) {
    int ret = SigFox.endPacket(true); // バッファをSIGFOXネットワークに送信し、レスポンスを待機
    if (ret > 0) {
      Serial.println("No transmission");
    } else {
      Serial.println("Transmission ok");
    }
    Serial.println(SigFox.status(SIGFOX));
    Serial.println(SigFox.status(ATMEL));
    if (SigFox.parsePacket()) {
      Serial.println("Response from server:");
      while (SigFox.available()) {
        Serial.print("0x");
        Serial.println(SigFox.read(), HEX);
      }
    } else {
      Serial.println("Could not get any response from the server");
      Serial.println("Check the SigFox coverage in your area");
      Serial.println("If you are indoor, check the 20dB coverage or move near a window");
    }
    Serial.println();
  } else {
    SigFox.endPacket();
  }
  SigFox.end();
}
// GPSデータ変換関数
/* GPS浮動小数点データを文字データに変換 */
String ConvertGPSdata(const void* data, uint8_t len) {
  uint8_t* bytes = (uint8_t*)data;
  String cadena;
  if (debug) {
    Serial.print("Length: ");
    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 to send: ");
    Serial.println(cadena);
  }
  return cadena;
}
// GPS位置取得関数
String GetGPSpositon() {
  int messages_count = 0;
  String pos;
  if (debug) Serial.println("GPS ON");
  digitalWrite(GPS_PIN, HIGH); // 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]); // 完全受信後、PCにメッセージ出力
          }
          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.println();
          Serial.print("Latitud/Longitud: ");
          Serial.print(latitude, 5);
          Serial.print(", ");
          Serial.println(longitude, 5);
          Serial.println();
          Serial.print("Fecha: ");
          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("Altitud (metros): ");
          Serial.println(gps.f_altitude());
          Serial.print("Rumbo (grados): ");
          println(gps.f_course());
          Serial.print("Velocidad(kmph): ");
          Serial.println(gps.f_speed_kmph());
          Serial.print("Satelites: ");
          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 turned off");
        digitalWrite(GPS_PIN, LOW); // GPSオフ
        pos = ConvertGPSdata(&coords, sizeof(gpscoord)); // データ送信
        return pos;
      }
    }
  }
  pos = "No Signal";
}
// セットアップ
void setup() {
  pinMode(4, OUTPUT);
  pinMode(backlights, OUTPUT);
  pinMode(pulsador, INPUT);
  pinMode(audio, OUTPUT);
  if (debug) {
    Serial.begin(9600);
    while (!Serial) {} // シリアルポート接続待ち。ネイティブUSBポートのみ必要
    Serial.println("Serial Connected");
  }
  // Serial1ピン13-14で3.3V接続GPS用
  Serial1.begin(9600);
  while (!Serial1) {}
  if (debug) {
    Serial.println("GPS Connected");
  }
  pinMode(GPS_PIN, OUTPUT); // GPSスイッチピン
  if (!SigFox.begin()) {
    Serial.println("Shield error or not present!");
    return;
  }
  // デバッグLED有効化、自動ディープスリープ無効化
  if (debug) {
    SigFox.debug();
  } else {
    SigFox.end(); // モジュールを最深スリープへ
  }
}
// ループ
void loop() {
  String position_data;
  position_data = GetGPSpositon();
  SendSigfox(position_data);
  Wait(WAITING_TIME, false);
}

カスタムパーツとエンクロージャ

MKR1200、バッテリー、ボタン、LED、GPS、ブザーが収まります。MKR1200、バッテリー、ボタン、LED、GPS、ブザーが収まります。nra_v_0_1_qCsc7I6QvO.zip

回路図

Arduinoの写真はMKR1200ではありません(注意)

Never Ride Alone:サイクリストのためのスマート安全システム

製造プロセス

  1. 集積回路(IC):現代エレクトロニクスを支える微小強力チップ
  2. Arduinoデジタルダイス: LCD表示の乱数ジェネレーター自作
  3. スマートホーム連携向けマルチポジション温度センサーシステム
  4. DIY Arduino USBゲームコントローラー - 高性能ゲームパッドを自作
  5. 自作16×8 LEDマトリックスでテトリスゲーム:Arduino Nano実装
  6. MotionSense: ArduinoとESP8266で作るスマート侵入検知システム
  7. Arduino MKRバンドルで作るセキュアIoTパズルボックス:ステップバイステップガイド
  8. MOSMusicプロジェクトキット: MOSFET、Arduinoで音楽同期照明制御
  9. ボール盤の主要構成部品と機能:ベースからモーターまで完全解説
  10. 内燃機関の主要コンポーネント:構造と機能
  11. C# switch 文をマスターする:構文、例、ベストプラクティス