見出し画像

単3ニッケル水素電池1本で動くSlimeVRトラッカーを作ったという話 -XiaoESP32C3完成編-

この構成で動いたよって話
電気電子的知識はぼくに無いので参考程度にしてもらえたらと
あと前編は日記なので読まなくていいよ
↓いちおう前編

前編には作るに当たって~みたいな話が書いてある
知識ゼロからどうやって公式と違う構成で作ったか~みたいな
本稿では構成とFWについて書いた



材料


マイコン

Xiao ESP32C3を使ってる
消費電流も少ないし小さくていいね!https://akizukidenshi.com/catalog/g/g117454/


昇圧DCDCコンバーターモジュール

ストロベリーリナックスのTPS61201 超低電圧DC-DCコンバータモジュール(3.3V出力専用)ってやつ
出力段のコンデンサをデカくすればもっと安いモジュールを使っても多分動くと思う(君の目で確かめてくれ!(Vジャンプbooksの攻略本並感))
https://strawberry-linux.com/catalog/items?code=61201


IMUモジュール

GY-BNO08Xを使ってるよ!
安くするために他のモジュールを使っても良いかもしれないけどめんどくさいからこれ以外には基板を対応させてない(君の目で
https://ja.aliexpress.com/item/1005005531979695.html


ニッケル水素電池

ぼくはFDKのやつ使ってるけどアマゾンの2400mAhのが安くてデカくてよさそう

↓リンク汚いけどアフィじゃないからゆるしてなんかamazonの短いリンクだとサムネが表示されないねんnoteをゆるすな


電池ケース

これ
逆電圧印加防止形状(防止できるとは言ってない)だし面実装だしガッチリハマるからいい感じ
書くのわすれてたけど裏にポッチがあるよ
基板には穴あけしてないからポッチはカッターとかで平面にしといて
別に大して強度に影響は無い
https://ja.aliexpress.com/item/4000915211179.html


電源スイッチ

多分SK12D07VG3ってやつだとおもう(少なくともピンとシルクは合ってる)
ここで買った


コンデンサ

680uFあれば十分だと思うけど2200uFを使ってる
ちなみに基板のパターンは多分変えなくてもがんばれば6.3x7.7サイズ実装できると思うよ(未検証)
ちなみにコンデンサ無くても起動はできたけど安定するかなと思って2200uF入れてる
基板のスペース空いてたし
UCM0J222MNL1GS Nichicon | コンデンサ | DigiKey
EMZR6R3ARA681MF80G Chemi-Con | コンデンサ | DigiKey

軽くしたいとか面積抑えたいならタンタルコンを使えばいいんじゃない?と思う 容量も2200uFなんていらないと思うし
燃えたら嫌だからぼくは使わないけど知識がある人なら十分選択肢に入ると思う


基板であり外装

こんな感じのをつくってみました
使ったcadはEasyEDAなのでEasyEDAで開くといいかもしれない
boothで公開するので好きにしていいよ

名付けとかがcopycopycopyみたいな感じでやばいのは気にすんな

回路図
メイン基板あーとわーく
ふたあーとわーく v2.0bのbはバカのb
2nd_IMU基板あーとわーく
できあがったメイン基板とふた基板
できあがった2nd_IMU基板

メイン基板とただの蓋基板を作ってそれを10mmのスペーサーを使ってM3の低頭ネジで止める感じ
TPS61201のモジュールがピンヘッダを付けたXiaoの下にピッタリフィットするので二階建てにしてる
整備性は最悪 ミスは許されない 一撃で仕留めろ
ちなみにぼくは泣きながら基板をフライパンで焼く羽目になった

メイン基板のパターンの作りとか汚いからちゃんと見ないで
ちゃんと見たなら糞だなつってちゃんと笑ってくれるとうれしい

2nd_IMU用の基板(?)も作った
コネクタにしたほうがよかったなぁ…とも思う 配線でつながってるものがプランプランしてるのは精神衛生上よくない

ちなみに蓋なんだけどJLCPCBのビューだとなんか穴が空いてないことになる
ガーバーデータはちゃんと穴になってるので
「右側のでけぇ穴はプレビューだと穴になってないけどちゃんと穴あけてほちぃ」
って英語で書いたらちゃんと穴開けてくれた
なんも書かなかった場合どうなるかはしらん

なんで.jpg

メイン基板は厚さ1.6mm
蓋基板と2nd_IMU基板は厚さ1mmで作った 軽いほうがいいかなって
蓋は1.2mmのほうがもしかしたらいいかも
でもまあ別に現状別に割れちゃいそうってほどでもない

その他

ピンヘッダ
どうでもいいけど最近のピンヘッダってめっちゃ折りやすくない?

M3低頭ネジ

M3の10mmスペーサー

リボンケーブル
これは10ピンなので半分に割いて使ってる

固定用のバンド
のびるし滑り止めもあってえらい!

2nd_IMU固定用マジックテープ
貼り付け強度は十分だと思う そのために2nd_IMU基板はミニマルにしてる

貼り付け強度確認動画

ついった埋め込めないのでサムネ的なあれ 3つめのメディアが動画になってるよ

https://twitter.com/mmtg03/status/1774008125349400701?s=20


組み立て

ばかだからXiaoを実装する前の写真撮り忘れちゃった(あへ)
ピンヘッダのスペーサーを2連にして高さを調節してる

(机きれいにするのがだるかったから下にキッチンペーパー敷いたけどなんかトイレットペーパーみたいでなんか…)

出来上がったものがこちらです
xiaoのアンテナは蓋に貼り付けてる
どうでもいいけどアンテナのコネクタめっっっっっちゃ嵌めにくいからきをつけて
こんだけつくるとけっこうつかれる
usb-cの下のほうから若干見えるのがDCDCのモジュール 見づらくてごめん…
ピンヘッダのスペーサーを2連でつければクリアランスは全然問題ない
DCDCの放射ノイズ?うるせ~~~~~~しらね~~~~~~~
ちゃんとうごいてるからおっけ~~~~

※ちなみにDCDCのモジュールはVカットのバリを取ってピンヘッダ実装済みのXiaoの下を通してみてちゃんと確認したほうがいいよ
クリアランスはほぼゼロだから

2nd_IMU用のリボンケーブルは基板の穴に二回通して強度を確保してる
たぶん…切れないと…おもう…たぶん…おそらく…
実際強度が出てるふんいきはある!しらん!(あへ)

こんなん
あとそんな基板の細いとこ通して折れないの?って思うかもだけどこれも結構強度ある
つけるとこんなん 足って結構可動範囲あるからもうちょっと線を長くすればよかったかなと思う
2nd_IMUの基板は上にテープ貼ってモジュールが引っかからないようにしてる
デザインの敗北


FWの変更点

ニッケル水素電池+XiaoESP32C3を使ってるのでいろいろ変更してる部分がある

Platformio.ini

[env:seeed_xiao_esp32c3]
platform = espressif32
board = seeed_xiao_esp32c3
framework = arduino
build_flags = 
  ${env.build_flags}
  -DESP32C3

esp32c3だとbuild_flags=~~~が要るらしい

defines.h

#define IMU IMU_BNO085
#define SECOND_IMU IMU_BNO085
#define BOARD BOARD_CUSTOM
#define IMU_ROTATION DEG_90
#define SECOND_IMU_ROTATION DEG_90

#define PRIMARY_IMU_OPTIONAL false
#define SECONDARY_IMU_OPTIONAL true

#define MAX_IMU_COUNT 2

#ifndef IMU_DESC_LIST
#define IMU_DESC_LIST \
    IMU_DESC_ENTRY(IMU,        PRIMARY_IMU_ADDRESS_ONE,   IMU_ROTATION,        PIN_IMU_SCL, PIN_IMU_SDA, PRIMARY_IMU_OPTIONAL,   PIN_IMU_INT) \
    IMU_DESC_ENTRY(SECOND_IMU, SECONDARY_IMU_ADDRESS_TWO, SECOND_IMU_ROTATION, PIN_IMU_SCL, PIN_IMU_SDA, SECONDARY_IMU_OPTIONAL, PIN_IMU_INT_2)
#endif


// For XiaoESP32C3, these pins not be use
// D6(21) D8(8) D9(9)
// Ref.:(https://lab.seeed.co.jp/entry/2023/04/03/120000)


#define PIN_IMU_SCL 3 //D1
#define PIN_IMU_SDA 4 //D2
#define PIN_IMU_INT 5 //D3
#define PIN_IMU_INT_2 6 //D4

#define LED_PIN LED_OFF //OFF

#define PIN_BATTERY_LEVEL 2 //D0/A0
#define BATTERY_MONITOR BAT_EXTERNAL
#define BATTERY_SHIELD_RESISTANCE 0


#define BATTERY_SHIELD_R1 100
#define BATTERY_SHIELD_R2 100

#define BATTERY_SHIELD_R1 100
#define BATTERY_SHIELD_R2 100
はべつにいらないとおもう
ちなみにこれはIMU2個の時のファイル
1個のときは#ifndef IMU_DESC_LIST~とかの部分を1個の場合のやつに書き換えないといけないとおもうたぶん

batterymonitor.cpp

//45行目#endifの後
analogSetAttenuation(ADC_6db);

なんとなくいちおうADCのアッテネーションを6dbにしてる
線形性が良いらしい ここで宣言していいのかはしらん
参考:

ESP32C3でもそうなのかはしらないけどまぁアッテネーションは少ないほうがいいんじゃない?わからん!

//84行目(83行目)のブロック
            #if ESP32 && BATTERY_MONITOR == BAT_EXTERNAL
                // voltage = ((float)analogReadMilliVolts(PIN_BATTERY_LEVEL)) / 1000 * ADCMultiplier; //Original
                voltage = ((float)analogReadMilliVolts(PIN_BATTERY_LEVEL) / 1000);
            #endif

直接電池の+とADCピンを繋いでいるからADCMultiplierは要らないのでけしけし

//104行目くらい?(あへ)のブロック
            if (voltage > 0) //valid measurement
            {

                // Original-----------------------------------------------------
                // // Estimate battery level, 3.2V is 0%, 4.17V is 100% (1.0)
                // if (voltage > 3.975f)
                //     level = (voltage - 2.920f) * 0.8f;
                // else if (voltage > 3.678f)
                //     level = (voltage - 3.300f) * 1.25f;
                // else if (voltage > 3.489f)
                //     level = (voltage - 3.400f) * 1.7f;
                // else if (voltage > 3.360f)
                //     level = (voltage - 3.300f) * 0.8f;
                // else
                //     level = (voltage - 3.200f) * 0.3f;

                // level = (level - 0.05f) / 0.95f; // Cut off the last 5% (3.36V)

                // if (level > 1)
                //     level = 1;
                // else if (level < 0)
                //     level = 0;
                // Original-----------------------------------------------------

                // Estimate battery level, 0.85V is 0%, 1.4V is 100% (1.0)
                if (voltage > 1.27f)
                    level = (voltage * 1.538f) - 1.154f;
                else if (voltage > 1.2f)
                    level = (voltage * 8.571f) - 10.086f;
                else if (voltage > 1.12f)
                    level = (voltage * 1.250f) - 1.300f;
                else if (voltage > 1.0f)
                    level = (voltage * 0.417f) - 0.367f;
                else
                    level = (voltage * 0.500f) - 0.450f;

                if (level > 1)
                    level = 1;
                else if (level < 0)
                    level = 0;

                networkConnection.sendBatteryLevel(voltage, level);

電池の残量表示の部分
ニッケル水素電池の放電特性を線形に近似した感じのに変更
元のアルゴリズムよりめっちゃ汚いけどゆるして
嫌だったらじぶんでなおして😭そしてぼくにおしえて😭😭😭

debug.h

//72行目
// #define BATTERY_LOW_VOLTAGE_DEEP_SLEEP false //Original
#define BATTERY_LOW_VOLTAGE_DEEP_SLEEP true
// #define BATTERY_LOW_POWER_VOLTAGE 3.3f // Voltage to raise error //Original
#define BATTERY_LOW_POWER_VOLTAGE 0.88f

電池の電圧が低くなったときにDeep sleepに落とすやつ
ほんとは1.0V以下になるまで使うのは良くないけどたぶん平均~V以下でdeep sleepみたいなのは無い(とおもうし、作るのはめんどくさい)ので0.88V以下になったらDeep sleepするようにしてる(なってると思ってる)
もしかしたら0.88Vになる前に電流が足りなくなって落ちてるかもしれん
まだちゃんと検討してない

wifihandler.cpp

//76行目、wifi network setupの中、wifihandlerloggerの後
    WiFi.setTxPower(WIFI_POWER_MINUS_1dBm); //Power Saving(?)

省消費電流のためにWifiの出力強度を最低にしてる(なってると思ってる)
ここで宣言していいのかわからんしこの後で変更される処理が入ってるかもしれない
ぼくがなんとなくで眺めた感じではこの後出力が変更される処理は特に無い…とおもう…よくわかんない…
少なくともこれを追加してもwifi受信強度には問題発生していない

ぼくのトラッカー設計はこれでおわり

ちゃんとうごいたよ

https://twitter.com/mmtg03/status/1774441967637917949?s=20

体が固くてガニ股な真冬ちゃん かわいそうだけどうれしそうだね

トラッカーを作るのが楽しそうで始めたことだけど
わりとフルトラ楽しんでる
お前もフルトラになれ…

評価

動作時間

実動作時間(実際に使って連続稼働できる時間)についてはまだ充電し直してない新品の電池を入れて使ってるとこだから正確なところはわからないけど6~7時間くらいかな?
わかったら追記するかも
追記--------------------------------------------------------------------------------
わかった
実動作時間は…5時間半!
ちなみにこれは2nd_IMU有りでずっと立ったり座ったりして動いてるときの一番最初に電池が無くなったものの値
原因としては2nd_IMUが消費する電流量があるってのとその接続に使ってるリボンケーブルの抵抗分でちょっとロスかなぁ~って感じ
リボンケーブルは5本で接続してるけどGNDとVCCを2本で繋いでやるとちょっとだけ良い結果になるかもと言う感じ
まあその改善ではおそらく誤差レベルかな
電池を1900mAから2400mAに変えた場合だと理論値で6時間50分くらいか
そっちのほうがダイレクトに効くとおもう
追記以上---------------------------------------------------------------------------
まあでもそれくらい保てばあとは無くなったら電池を交換すればいいだけかなとも思ってる
なんせ電池駆動なんだから

重量

おうちにはかりないんだ… ごめんね
まあべつに…ってくらいの重さ

形状、堅牢性

やっぱり単3の長さはどうしようもないから若干縦に長い気もする
あと蓋とかがおふとんとか自分の足とかにこすれると若干不安になる
引っかかって割れないかなぁって
強度はあると思うんだけど…まあ思いっきり踏んづけたら壊れるだろうねって感じ

既知の問題点注意点イマイチな点 まとめ

USB挿してるときってDCDCコンバーターにかかる電圧とかってどうなるの?

わかんね~~~
ついでに言うとUSB挿してるときに電池入れて電源入れたときの挙動もわかんね~~~一応しないようにはしてる~~~
まあ…まだ壊れてはないよ…?

USBを挿した後すぐ起動すると稀にIMUがエラーを吐く

多分コンデンサがデカいからマイコンが止まった後、コンデンサに充電されてる分でIMUが動いたり動かなかったりしてエラーになるんだと思う
解決方法?電源切ってコンデンサの端子をショートさせて電荷を抜け
そんなことして大丈夫なのかって?
まあ…まだ壊れてはないよ…?

これマイコンをDeep SleepにしてもIMUへの電源供給は切れてなくない?

…うん

二階建て構造

省スペースでいいんだけど整備性はカス
まあどっちにせよモジュールを基板実装した時点で取り外しはかなりキツイのでまあ…まあ…と思ってる
実際うまく行ったからおっけ~

あとクリアランスは割とあるにしてもDCDCコンバーターの上にマイコンを配置してるってことでノイズによってI2Cがおかしくなる可能性を懸念してたけどいちおうちゃんと動いてる
セオリーとして例えばI2Cとかの信号線はDCDC(特にインダクタ?)の下を通してはいけないとかがある
…ってでじきーのゆーちゅーぶでおっちゃんがゆってた!


10x10のコンデンサって高さ10mmには絶対実装できないので10mmのスペーサーだとコンデンサ天面が蓋と干渉してる

若干弓なりになる健気な蓋くん

あとほんとはコンデンサ天面って蓋とかでゼロ距離で塞いじゃダメ
(ショートや過電圧逆電圧印加時に防爆弁が作動せず爆裂する可能性があるため)
今回はコンデンサアルミケースよりも蓋のほうが弱いと思うのでコンデンサ内部ショート時は先に蓋が壊れるだろう、電流も少ないから異常時は気付けるだろう、よって爆発四散しないだろう、という想定で塞いじゃってる
まあクリーンな設計ではない
しかしコンデンサが突っ張ることにより蓋の強度が若干上がっているというのも事実
う~ん まあ いっか!

蓋を外さないとベルトがうまく着脱できない

あちゃ~
まあメンテするときしかベルト外さないし
メンテするならどうせ蓋は外すから…
まぁ…まぁ…

Xiao ESP32C3のUSB接続が安定しない

なんで?
まあ困るのは最初のSlimeVRでwifi接続するところくらいなんだけど結構USBが途切れて時間がかかる
最初だけだから…う~ん まあ いっか!ってことにしてる
もしかしたらFWのフラッシュが91%とかになってたのでそれが原因なのかなぁと思ったり思わなかったり
例によって検証はしてない 何回もやればそのうち繋がる

アートワークがイマイチ

なんとなく電源周りだけは抵抗値が下がるように設計してみたつもりだけどどうなのかな?4層基板とかにしてもっと配線の面積(体積)大きくすればよかったかな~なんて
ビアの数とかも特に理論に裏付けされてない適当な感じなのでもっと打ったほうがよかったかなぁ足りてるかなぁって思ってる

DCDCもっと安いやつでもイケるんじゃない?

ま~どうなのかな
この構成だとSlimeVRの表示で0.95Vくらいまで動作するしコンデンサデカいの積んでるからDCDCコンバーターの出力電流はもうちょっと少ないやつでもイケる可能性はある
ただ出力電圧が下がれば出力電流が増えるわけでそしたら電池の内部抵抗の支配度が上がるわけで突発的な電流が要求されると更にキツくなるわけで…
しかもそうなると配線の抵抗値も支配的になってくる
机上はおろか空中配線での検討もなかなか難しいんじゃないかなぁなんて思ってる
これ以上の検討は知識が無いぼくには無理かなって

自作トラッカーっていつかは完成するらしい

開発期間2ヶ月!トラッカー作成 これにて閉幕!
かまってくれた霧雨さんやめんたいさん
そして先人の方々に感謝!
ほんとうにありがとう!

フルトラになり姿勢が悪すぎることがバレる人の図


この記事が気に入ったらサポートをしてみませんか?