編集履歴一覧に戻る
yukimiruthiのアイコン画像

yukimiruthi が 2024年01月31日11時19分21秒 に編集

初版

タイトルの変更

+

ランナーのためのカスタムペースメーカー:デザインから実装まで

タグの変更

+

SPRESENSE

+

LEDテープ

+

LED

+

spresense

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

Lチカの変更

Lチカが設定されました

本文の変更

+

**はじめに** == 今回私はSpresenseを用いたランニング用のペースメーカーを作成することにチャレンジしました。 結果としては、基本的なソースコードの作成と技術テストが完了しています。当初は、画像認識を用いてタイムを計測し、ELTRESを使用してSpresense同士を連携させ、区間ごとのタイムを正確に計測することを目標としていました。しかし、カメラのフレームレートの制限により、画像認識を使用してタイムを計測することが困難であることが判明したため、計画を変更しボタンを用いたタイム計測とLEDへの反映を新たな目標としました。 ペースメーカーの概要 == 自己タイムを計測しLEDライトで自己タイムを視覚化することができます。そのため過去の自己タイムをと競うことができるとともに他者のタイムとも競うことが可能になります。 **使用した機材&ソフト** Spresenseメインボード 拡張ボード フルカラーLEDテープ(5m)×4本 ブレッドボード 押しボタンスイッチ モバイルバッテリー プログラミングソフトウェア(Arduino IDE) 設計と開発プロセス == **ステップ1**: アイデアの発案 日本陸上競技連盟が電子ペーサーの導入のためのクラウドファンディングを実施し導入に300万円が必要であると知り、このシステムをより低コストで簡単に実現できないかと考えました。また、過去の文献を参考に、個人でもグループでも楽しめるように、手軽で効果的なトレーニングシステムの開発を目指し、このプロジェクトが開始しました。 **ステップ2**: spresenseと使用する機材の選定 spresenseを基礎として実装するための機材を調べ、集めました。 **ステップ3**: 電子部品の組み立て SpresenseとブレッドボードにフルカラーLEDテープを接続し、バッテリーで動作させる設計を行いました。 **ステップ4**: プログラミング Arduino IDEを使用して、Spresenseボードにボタンでランニングペースを計測し、LEDに表示するためのコードを書きました。このコードは走者の速度を疑似的に再現を行います。 **ステップ5**: 試験運用 簡易的にタイムを計測しLEDテープに表示し実際に走りました。 *※当初はカメラを使用した画像認識を使用する予定でしたがボタンによる計測に変更しました。* [実際に走っている映像](https://youtu.be/lvtHsdRzigU) 以下は、Spresenseでボタンを用いてタイムを計測しLEDを光らせるソースコードです。 ```arduino:ソースコード #include <Adafruit_NeoPixel_Spresense.h> #define LED_PIN 8 #define LED_COUNT 600 #define BUTTON_PIN 9 #define DEBOUNCE_TIME 50 Adafruit_NeoPixel_Spresense strip(LED_COUNT, LED_PIN); unsigned long startTime = 0; unsigned long previousTime = 0; int buttonClicks = 0; int lastButtonState = HIGH; int currentLed = 0; void setup() { Serial.begin(19200); strip.begin(); strip.show(); // Turn off all pixels strip.setBrightness(60); pinMode(BUTTON_PIN, INPUT_PULLUP); Serial.println("Setup complete."); } void loop() { int buttonState = digitalRead(BUTTON_PIN); if (buttonState == LOW && lastButtonState == HIGH && millis() - previousTime > DEBOUNCE_TIME) { previousTime = millis(); buttonClicks++; if (buttonClicks % 3 == 1) { // Start timing startTime = millis(); Serial.println("Timer started."); currentLed = 0; // Reset } else if (buttonClicks % 3 == 2) { unsigned long elapsedMillis = millis() - startTime; float elapsedSeconds = elapsedMillis / 1000.0; Serial.print("Timer stopped. Time: "); Serial.print(elapsedSeconds, 2); Serial.println(" seconds"); lightLedsSequentially(elapsedMillis); } else { // Turn off the LED strip strip.clear(); strip.show(); Serial.println("LED strip turned off."); } Serial.print("Button clicks: "); Serial.println(buttonClicks); } lastButtonState = buttonState; // Save the last button state } //20m用 void lightLedsSequentially(unsigned long time) { int delayTime; if (time > 11227) { // タイムが11227ミリ秒より長い場合、全てのLEDを点灯 delayTime = abs(static_cast<long>(time) - 11227) / 600; for (int i = 0; i < 600; i++) { strip.setPixelColor(i, strip.Color(230, 128, 0)); strip.show(); delay(delayTime); strip.setPixelColor(i, strip.Color(0, 0, 0)); } } else { // タイムが11227ミリ秒以下の場合、1つおきのLEDを点灯 delayTime = abs(static_cast<long>(time-37.423)) / 600; for (int i = 0; i < 600; i += 3) { strip.setPixelColor(i, strip.Color(250, 0, 0)); strip.show(); delay(delayTime); strip.setPixelColor(i, strip.Color(0, 0, 0)); } } } ``` LEDの点灯時間と実際のタイムの誤差 == 今回のプログラムではシリアルモニターにボタンを押して計測したときの実際の測定タイムが表示されます。 しかし、その測定されたタイムとLEDが光りきるまでの時間にはLEDテープの長さによって誤差が生じることがわかりました。その結果をLEDテープの長さを変えてそれぞれ10回タイムを測定し、以下の表とグラフにまとめます。 ![キャプションを入力できます](https://camo.elchika.com/275cc1fd9b6e085ee6166bc9b5b141234728d05f/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f63316233613466652d306430352d343264622d626232372d3863313439346337363936382f62346230366335352d306462362d343764302d393731662d303561663366343238323534/) ![キャプションを入力できます](https://camo.elchika.com/0549618bbc0fe6dd9bbd8a916fedc5d44f43520b/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f63316233613466652d306430352d343264622d626232372d3863313439346337363936382f64663865383764342d373335342d343165382d623936642d663031333538656531613935/) グラフは縦軸は誤差、横軸は計測回数を表しています。5mの誤差は0.5から0.7ms、10mの誤差は2.6から2.9ms、15mの誤差は6.0から6.5ms、20mの誤差は10.9から11.55msとなっています。 このことからLEDテープの長さが長くなるほど誤差が大きくなることがわかりました。 そこで、今回は20mで実験を行うことを想定して、計測したタイムが平均誤差の11.23秒より長い場合は、平均誤差をLEDの総数(今回は600)で割った値を1つ1つのLEDが光るタイムの間隔から引いた時間で光らせるように変更しました。 また、11.23秒より短い場合はLEDを1つ飛ばしで光らせることにより、計測したタイムの近似値で動作することができました。 [計測中の映像](https://youtu.be/T-Ae_cL8OH0) まとめ = 今回得られた成果としては主に計測タイムのLEDテープライトへの可視化です。計測タイムとLEDライトの到達時間を計りそれぞれの誤差や傾向を得ることができました。また課題としてはLEDの信号の伝達速度の問題や本来の画像認識による動作ができなかったことがあげられました。今後はタイムが短い場合のLEDテープライトへの信号伝達の誤差を少なくしてより実用性を高める方針です。 今回は主に計測タイムのLEDテープライトへの可視化を実装できました。さらなる完成度を高めるため開発を継続し来年度のコンテスト出場を目指していきたいと思います。 参考文献 == >過去の走行を再現するように光るLEDテープを利用した短距離走練習方法 https://cir.nii.ac.jp/crid/1050294045368290048 日本の陸上を一歩前へ。目標記録達成のために電子ペーサーの導入を! https://readyfor.jp/projects/distance2023