はじめに
リモートワークや外出自粛で巣ごもり生活が多くなったので
運動不足解消にフィットネスバイク(エアロバイク)を買ってみましたが、
ご多分に漏れず長続きしなかったので、ArduinoでGoogleストリートビューと連動するアダプターを作ってみました。
先駆者「【フィットネスバイク】のインターネットを作る!!」の事例等では、
ペダルのフィードバックをインターネット経由でストリートビューの進行に反映しているが、
今回作ったアダプターはUSBキーボードとして機能するため、ダイレクトにデバイスに伝わるので、
Windows PCやMacはモチロンのこと、iPadやAndroidのデバイスでも動作し、
エアロバイクとデバイスに繋ぐだけの簡単セットアップで、気軽にエクササイズを開始できます。
ハンドルの舵取りはジョイスティックで操作します。
なお、USBデバイスとして動作させるにはATmega32u4搭載のArduinoを利用するのが手っ取り早いので、
今回の製作では該当コントローラーを搭載しているArduino Microを使っています。
イメージ
利用イメージ
アダプター
ダイソーの500円コインケースを加工して、Arduino Microとジョイスティックを組み込みました
加工したコインケースに配線前のArduinoを組み込んだ状態(左)と、iPadとフィットネスバイクに実際に繋いだ状態(右)
構成
システム全体の構成図です
- 利用しているフィットネスバイクは「ALINCO クロスバイク4417」
- ペダルの回転判定のメーターへの連動は、オーディオケーブルが使われている
- メーターへの接続直前にオーディオ分配ケーブルを割り込ませ、アダプターを接続できるようにする
- アダプターがストリートビューの進行を制御する
- ペダルの回転でストリートビューを前進する
- ハンドルの舵取りはジョイスティックで左右転回する
- Lightning端子のiOSデバイスは「Lightning - USBカメラアダプタ」を使いUSBケーブルへ接続する
- アプリ版のGoogleマップはキーボード移動に対応していないので、iPad/iPhone、Androidの場合でもブラウザ版を利用する
材料
部品 | 型番 | 個数 |
---|---|---|
マイコンボード | Arduino Micro ピンヘッダ無し | 1個 |
オーディオジャック | ステレオジャック 3.5mm | 1個 |
オーディオケーブル | ステレオ分配ケーブル 3.5mm (メス⇔オス×2) 0.2m | 1本 |
ジョイスティック | ジョイスティック モジュール | 1個 |
ケーブル(オーディオジャック接続) | ジャンパワイヤ(オス~オス) | 2本 |
ケーブル(ジョイスティック接続) | ジャンパワイヤ(オス~メス) | 5本 |
スペーサー | 絶縁POM(ポム)スペーサー 六角 M3×15mm [RoHS] | 4個 |
ネジ | EV型導通ビス M3×5mm | 8本 |
ケース | コインケース 500円玉 | 1個 |
回路図
部品 | 部品ソケット | Arduinoピン | ケーブル色 |
---|---|---|---|
オーディオジャック | RIGHT(RING) | GND | 黒 |
〃 | LEFT(TIP) | D4 | 白 |
ジョイスティック | VCC | D7 | 水色 |
〃 | VERT | A3 | オレンジ |
〃 | HORZ | A0 | 黄緑 |
〃 | SEL | 5V | 赤 |
〃 | GND | GND | 黒 |
ソースコード
link-pedal2key.ino
#define DEBUGLOG 0
#if DEBUGLOG
// definitions to log for debug when not to use 'keyboard.h'.
#define KEY_UP_ARROW 'U'
#define KEY_DOWN_ARROW 'D'
#define KEY_LEFT_ARROW 'L'
#define KEY_RIGHT_ARROW 'R'
#else
#include "Keyboard.h"
#endif
#define BIKE_PIN 4
#define LED_PIN 13
#define SW_PIN 7
#define X_PIN A0
#define Y_PIN A3
#define WAITING_MSEC 125
#define MAX_ROTATION 3
int rotation = 0;
boolean stat_p = false;
#define MAX_POS 1024
boolean stat_l = false;
boolean stat_r = false;
boolean stat_u = false;
boolean stat_d = false;
void printNumberOfRotation(int now, int max) {
Serial.print("The pedal has rotated ");
Serial.print(rotation);
Serial.print("/");
Serial.print(MAX_ROTATION);
Serial.println(" times.");
}
void printKeyboardEvent(String event, char key) {
Serial.print(event);
Serial.print(" keyboard [");
Serial.print(key);
Serial.println("]");
}
boolean ctrlStick2KeySmall(int pos, boolean stat, char key) {
if (pos < (MAX_POS / 5)) {
if (!stat) {
Keyboard.press(key);
stat = true;
printKeyboardEvent("Pressed", key);
}
} else {
if (stat) {
Keyboard.release(key);
stat = false;
printKeyboardEvent("Released", key);
}
}
return stat;
}
boolean ctrlStick2KeyLarge(int pos, boolean stat, char key) {
if (pos > (MAX_POS - MAX_POS / 5)) {
if (!stat) {
Keyboard.press(key);
stat = true;
printKeyboardEvent("Pressed", key);
}
} else {
if (stat) {
Keyboard.release(key);
stat = false;
printKeyboardEvent("Released", key);
}
}
return stat;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Keyboard.begin();
pinMode(BIKE_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(X_PIN, INPUT);
pinMode(Y_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
int pedal = digitalRead(BIKE_PIN);
if (pedal == LOW) {
if (!stat_p) {
rotation++;
printNumberOfRotation(rotation, MAX_ROTATION);
if (rotation >= MAX_ROTATION) {
Keyboard.press(KEY_UP_ARROW);
Keyboard.release(KEY_UP_ARROW);
digitalWrite(LED_PIN, HIGH);
delay(WAITING_MSEC);
digitalWrite(LED_PIN, LOW);
rotation = 0;
}
stat_p = true;
}
} else {
stat_p = false;
}
int x_pos = analogRead(X_PIN);
int y_pos = analogRead(Y_PIN);
stat_d = ctrlStick2KeySmall(x_pos, stat_d, KEY_DOWN_ARROW);
stat_u = ctrlStick2KeyLarge(x_pos, stat_u, KEY_UP_ARROW);
stat_l = ctrlStick2KeySmall(y_pos, stat_l, KEY_LEFT_ARROW);
stat_r = ctrlStick2KeyLarge(y_pos, stat_r, KEY_RIGHT_ARROW);
}
2
-
kon104
さんが
2021/03/28
に
編集
をしました。
(メッセージ: 初版)
-
kon104
さんが
2021/03/28
に
編集
をしました。
-
kon104
さんが
2021/03/28
に
編集
をしました。
-
kon104
さんが
2021/03/28
に
編集
をしました。
Opening
wi
2021/04/13
kon104
2021/04/14 Opening
tak
2023/05/01
kon104
2023/06/08
ログインしてコメントを投稿するこんにちはwiです。
興味があり質問させて頂きます。
クロスバイクの回転数(距離)とマップの距離はある程度シンクロされるのでしょうか?
よろしくおねがいします。
こんにちは、興味持っていただきありがとうございます。
正直言うとシステム的に厳密なシンクロはできておりません。
3kmを走るのに必要としたペダル回転数とストリートビューの遷移数を、
全国いくつかの箇所でサンプルを取ったところ、だいたい3ペダル漕ぐとストリートビューが一つ遷移の状況でした。
その統計より、ペダル3回転すると一つストリートビューを遷移する様にプログラムを実装しており、
ソースコードでは「#define MAX_ROTATION 3」の定数がストリートビューを遷移させるペダル回転数の閾値となっております。
(将来的には、MAX_ROTATIONの定数も、ダイヤルなどで可変的にできると汎用性が増すな。とか、ふと思いつきました)
こんにちは。
興味を持ち、リストアップされた商品を購入し、初めて電子工作をしています。
kon104さんはフィットネスバイクの信号を利用して
ストリートビューに反映させていますね。
私の場合、ロードバイクが家にあり、新たにフィットネスバイクを買い足すのは
部屋が狭くなるので嫌だなと思いました。
そこで用意したものは
・キャットアイ(CAT EYE) サイクルコンピュータ VELO9 CC-VL820 有線式
https://www.amazon.co.jp/gp/product/B007NE348Q/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&th=1
・ミノウラ ローラー台 LR760
http://www.minoura.jp/japan/trainer/unavailable/tire-drive/lr760.html
です。
ブログ記事と同じ工作で、ストリートビューを使えますか?
また、初めてArdunio IDE でプログラミングを行いました。
書き込みを行い、「コンパイル完了」が出たのち、しばらくすると
「書き込み中」と出続けています。
このままうまくいくのかわからない状態です。
ちなみに、現況は
Ardunio Micro をmicro USB タイプBでPCに接続し、
ブラウザでストリートビューを開いた状態でジョイスティックを動かしても
何も反応しない状態です。
Ardunio microの基盤は青点滅と 黄緑点滅を繰り返しています。
ご回答いただければ幸いです。
よろしくお願いいたします。
こんにちは、興味持っていただきありがとうございます。
サイクルコンピュータの仕様が把握できていないので正確なことは言えませんが、
恐らく難しいかと思います。
今回利用している「ALINCO クロスバイク4417」では、
ペダルを漕ぐとメーターに繋いでいるオーディオケーブルに電気信号が流れてくるようになっており、
その電気信号の動きをオーディオジャックのRIGHT、LEFT、GNDの3つの端子で、
https://msp.c.yimg.jp/images/v2/tpvPBYOX1wpNVI1UoNSgEkk11uGn0VaIL7P_hOn9d2UXQ4IGJWl42VGDEZP4qukbXRetAQkxVtesqU_CXbiATIME5UysgunvQasYTTBjzUL7aHQxeTnjNde1s6GeEsI9GKKE3xj58As2BTAP_6eqyVDC89SnC7J-BRSHS1Q625s=/4p3a.png
LEFT端子がLOWになるとべダルが漕がれた状況であるため、
それを判断して動作するプログラムとなっております。
と言うように、
かなり「ALINCO クロスバイク4417」の動作仕様に依存したソースコード実装となっていますので、
難しいのではないかと考えております。
恐らくですが、
Arduino IDEとArduino実機の接続がうまくいっていない気がしております。
まずは、以下サイトのLチカの様な単純なプログラムで環境準備から開始頂くのが良いと思っております。
https://romly.com/archives/2017/10/arduino_led_blink.html