ラベル ADXL345 の投稿を表示しています。 すべての投稿を表示
ラベル ADXL345 の投稿を表示しています。 すべての投稿を表示

2018年1月24日水曜日

ストレートネック矯正デバイスw

パチDigiSpark。小さいよかわいいよ。

同僚さんからストレートネックから来る肩こりに困っているので何とかなりませんか?と依頼。さくっと作ってみました。
追記

■原理■

本当は加速度センサーを2個以上使って頚椎の屈曲ぐあいを計る必要があるんですが、簡易的に頭が前傾しすぎたら警告を発するようにしました。起動から5秒間の平均値を求め、それ以上前傾したらダメ!です。

今回のユーザはメガネさんなのでメガネにセンサーを取り付けることにして、ポケットに本体と振動モータと電池を入れられるようにしました。

■構成■

マイコンとしてATTiny85のDigiSpark、センサにはADXL345(オーバースペック)、通知には秋月の振動モータ、ドライブは2SC1815です。振動モータは振動モータにしておくのがもったいないブラシレスです。ドライブ回路内蔵なので、電流制限抵抗省略、多分クランプダイオードも入ってるだろ、ということで外付けは省略。気になる人はちっこいダイオード付けておきましょう。

電源はモバイルバッテリを使いましたが、アイドリング中の消費電流が小さいのでバッテリ側で勝手に電源をオフにしてしまいます。幸い、SANYO KBC-L3S(絶版)は微小な電流でも切れないので、今回はこれを使います。cheeroのIoT機器用バッテリもこういう用途に使えるはずなのですが、ずっと欠品のままで3ヶ月です。このまま発売停止なら何か作るんだけど…出るのかでないのかはっきりしてくれい>cheero

回路図途中まで書いたけどKeynoteとEagle混合だとうまくいかず挫折orz
(あかん)


ということで配線図。

DigiSparkADXL3452SC1815モータ
5VVcc+
GNDGNDE
PB0SDA
PB2SCL
SC→5.1k→5V
SDO→5.1k→GND
PB1B(1kΩでPB1接続)
C-

CSをプルアップ(1608使用)
SDOをプルダウン(でかい)

プラスに配線、マイナスにコレクタ、ベースに1kΩと緑、プラスに赤、エミッタに黒

■追記:続編■

モニタからの距離を測定するバージョンも作ってみました。

■制御プログラム■

探すと見つかるインターネット。まず、これでADXLとDigisparkがちゃんとつながっていることを確認します。y方向に傾けるとオンボードのLEDが着いたり消えたりすればOK。

以下、
  1. 起動したら0.1秒 x 5秒間、X軸方向の加速度(傾斜)を検出し平均値を求める
  2. 平均値取得が終わったら0.1秒振動モータを回す
  3. それ以降、平均値より前傾したら振動モータを回す

だけです。つまり、メガネのツルなどにこの装置のセンサー部分(ADXL345)を取り付けて、「これ以上首を傾けたらダメ」な状態でバイブレータが鳴るまで5秒間静止します。

その後は、普通にお仕事をして、鳴ったら姿勢を改める、という仕掛けです。

なお、傾斜スイッチと振動モータと電池だけでいいじゃん、というツッコミを禁止します。


2016年5月15日日曜日

Arduino+ADXL345で地震酔い対策


■地震酔いとは■

東日本大震災では東京はいくつかの施設を除いては被害を免れました。でも、頻繁に震度3-4の揺れを経験していると、そのうちふと揺れを感じているかのような錯覚を覚えることがあります。本当に揺れているのか錯覚なのかわからないんですよね。

これが地震酔いです。熊本では高頻度で強い揺れが続いているので、地震酔いの症状でお困りの方もおられるのではないかと思います。

ということで、Arduinoで「揺れたら点灯」なデバイスを作ってみました。机の上に置いて、「あれ?地震?」と感じた時に点灯していなければそれは気のせい、という感じに動いてくれればいいのですが(作ってから東京で大きな地震がないので未検証です)。

周波数成分ごとに色を変えたのですが、手に持っているとどんなに心を鎮めても赤(ゆっくりした揺れ)が消えてくれません。

アル中検出器を造ってしまったのかもしれません。

なお、「酔い」と言っても色々あります。上記のように「揺れているように感じる」程度なら、物理的に揺れていないことを確認することが一種の認知療法的な効果につながると思いますが、「常時揺れているように感じて気持ちが悪い」という状態であれば、内耳に作用するタイプの乗り物酔い止めが有効です。こういう症状では「どこの医者にかかって良いかわからない」と思うんですが、メマイや酔いなどについては耳鼻咽喉科に相談してみるのがよろしいです。3.11の時、かなり深刻な症状を訴える同僚もいましたが、でも今はみんなすっきり治っています。不快な症状を我慢しないで、医師に相談しましょう。

■ハード■

Arduino nano+加速度センサーADXL345+マイコン内蔵LED WS2811です。以前、「キーボードを強く叩き過ぎたら、警告する」ってのを作りましたが、その流用です。

Arduino接続先
3.3v出力ブレッドボードの+ライン
GNDブレッドボードの-ライン
5v出力マイコン内蔵LEDのVdd
D2マイコン内蔵LEDのDin
A4ADXL345のSCL
A5ADXL345のSDA


ADXL345接続先
SCLArduino A4
SDAArduino A5
SDOGND
CS3.3v
Vs3.3v
GNDGND
Vdd3.3v

■ソフト■

加速度センサーから読み取った値を3軸分合成してからFFTにかけて、ノイズ分を除外した値が一定値を超えたら帯域ごとのパワーにわけてRGB LEDを点灯します。

当初割り込みを使って連続的に計測するプログラムを書いたのですが、インタラプト処理ルーチンでI2Cを読んだ瞬間にフリーズする、という現象を解決できなかったので、諦めて単純な逐次処理にしました。ただ整数処理のFFTを使っているので、計測漏れはそれほど大きくないです。

ADXL345に限らず3軸加速度センサーには重力加速度が常時計測されます。ので、その影響を取り除く必要があります。また、体感する揺れは三軸の合成ベクトルなので、三軸分のスカラー値を求めて、そこから重力加速度分を引き、感度を高めるためにちょっと掛け算してます。read345というルーチンでは、その後、ムダなdual buffer処理をしていますが、これは最初に書いたように当初割り込みで処理しようとしていた名残です。書き換えるの面倒なのでそのままにしています。

ノイズ処理は単に「静かにしていてもFFTからの出力が0-2程度出ているので、2以下はノイズとしてカット。それを超えた分だけ集計して、集計値が一定値を超えたら、有効と判定」というごく単純な処理です。

FFTには整数型FFTを使いました(Topic: Modified 8bit FFT in c)。ありがとうございます。ただ、開発されてから時間が経っているので、いくつか修正が必要です。まず、include文で「WProgram.h」となっている箇所は「Arduino.h」に置換します。また、データタイプの定義が変わっているので、fix_fft.cppの頭の方に
#ifndef prog_int8_t
#define prog_int8_t int8_t
#endif
を貼っておいてください。

ADXL345のライブラリはAdafruitの新しいunifiedライブラリ版を使いましたが、unifiedなインタフェース(センサーが違っても、重力加速度としての値域に変換して返すなど、センサーごとの差異をわりといい感じに吸収してくれるライブラリ群)は使わずgetX, Y, Zで取ってます。FFTが整数ですし。

WS2811は特に問題ないと思います。


■感謝■

FIX_FFTの作者の方、およびADXL345/WS2811ライブラリを公開してくださったAdafruitに感謝申し上げます。ありがとうございました。

2015年11月11日水曜日

「机ドン!」検出デバイス改良@Arduino


■暫定仕様でした■

前バージョンは「とりあえず動けばいいや」で、各軸どれかがボリュームでセットした値を超えたら2段階の明るさでランプを明滅させる、という安易な仕様でした。

これだと一度、例えば閾値ギリギリの信号で点滅が始まるとその後に強い衝撃が来ても無視されてしまいます。幸い、滅多にそういうケースはないのですが、可能性としては排除できません。

■改良版■

まず、加速度を各軸ごとの値ではなくスカラー値として処理します。各軸値自乗の総和の平方根ですね(sqrt(x*x + y*y + z*z))。スカラー値はセンサーの向きが変わっても一定のはずなので、起動時に値を保持しておけば、あとは初期スカラー値と瞬間のスカラー値の差をとれば、どの方向であれ掛かった加速度の大きさがわかります。なお、255を超える値を自乗した時に整数だとオーバーフローしてしまうので、floatに直しています。

それと、少し簡略版ですが、加速度の最大値でランプのピークの明るさを決めるようにしました。ピークかどうかを検出するのは、一定の時間ごとにサンプルした今回の値が前回の値よりも下がったら前回がピークだった、ということになります。本当ならそのピーク値が前回のピーク値より上かどうかを調べれば、大きな山から下っていくところに出来た小さなピークを誤認することがなくなるのですが、今回は「ドン!」という比較的単純な衝撃の検出なのでそこまで凝ったことはしませんでしたm(_ _)m 

この辺は本当にこり始めるとキリがないですし、味付けというか装置の賢さを感じる要素だったりするんですが…とりあえず週末までに何か考えます。

なお、ハードウェアには一切手を加えていません。

■結果■

以下2点の問題が解決しました。

  • 水平に置いて起動した後、傾けて置いても点滅しっぱなしにならない。
  • 大きな衝撃を与えた場合にきっちり強くランプが点灯する。

■ソース■


2015年11月8日日曜日

「机ドン!」検出デバイス@ESP-WROOM版



■ESP版■

というわけで前回のArduino版をESP-WROOM-02でも動かしてみました。

AdafruitによるWS2811最新版ライブラリはESP8266にも対応しています。

ただ、うちのWS2811がNeoPixelではなく安物なのがいけないのか、指示した通りに光ってくれません。Greenだけは良い感じなんですが、Red/Blueについては意図した信号になっていません。トランジスタで3.3->5vへのレベルコンバータをはさんでみたのですが変わりませんでした。うーん。

400khzに切り替えても同じ。うーん。

光り方をみていると最上位ビットがズレているような感じ。

ということでLEDの点滅が意図したパターンとは違いますが、ESPでも動作させることができました。加速度センサーの値に応じてLEDを点滅させるところまではArduino版と同じですが、1分ごとにThingSpeak.comあてに各軸ごとの最大加速度を送信するようにしました。

■配線など■

相変わらずプルアップ/プルダウン/GND接続が多くて面倒くさい。

ESP-WROOM-02接続先
3V33V3
GND(すべて)GND
EN10kΩ経由で3V3
IO14ADXL345のSCL
IO12WS2811のDin
IO13N.C.
IO1510kΩ経由でGND
IO210kΩ経由で3V3
IO010kΩ経由で3V3 およびISPスイッチ※
IO16N.C.
TOUTN.C.
RST10kΩ経由で3V3 およびRSTスイッチ※
IO5N.C.
TxdFTDIのRxへ
RxdFTDIのTxへ
IO4ADXL345のSDAへ

※ISPスイッチ/RSTスイッチはノーマリーオープンのタクトスイッチで、他方をGNDにつないでください。これによりRSTとISPは常時Highレベルでスイッチを押した時にLowレベルになります。

レベル変換回路はこちらのページ(3.3V 5V レベル変換)に記載されていた「3.FETによる3.3V 5Vレベル変換」と「4.トランジスタによる3.3V 5Vレベル変換」回路を試しました。このページ上の写真にうつっているのはトランジスタによる回路です。なお、WS2811の場合は流れ込む電流が多いのか5V側のプルアップ抵抗は10kΩでは電圧が上がらなかったので1kΩを使いました。出力側の回路に応じて使い分ける必要があります。

それとFTDIを接続する際には、GND同士の接続をお忘れなく。

ADXL345接続先
SCLESPのIO14
SDAESPのIO4
SDOGND
CS3.3v
Vs3.3v
GNDGND
Vdd3.3v

WS2811接続先
DinESPのIO12
Vcc5V
GNDGND
DoutN.C.

M78AR033-0.5接続先
Vin5V
GNDGND
Vout3V3ライン

この他、ESPの3V3近くとADXL345のVccに0.1μFのパスコン、WS2811のVccとGNDの間に470uFのアルミ電解コンデンサを入れてます。

■ADXL345ライブラリの修正■

Android Citiさんのライブラリは Wire.begin(); でI2Cを初期化しているので、これを接続したピンに合わせて Wire.begin(4, 14); に変えます。ただそのままだと後日このライブラリをArduinoで使った時に動かなくて苦しみそうなので、
#ifdef ESP8266
  Wire.begin(4,15);
#else
  Wire.begin();
#endif
と書いておきます。

■ソース■

Arduino版との違いはボリューム読み込みをしていないのとThingSpeak.comへの送信処理を行っている点です。ThingSpeakへは1分ごとにその間の最高値を送るようにしています。

ESPからThingSpeak.comへの送出には鳩退治デバイスに使ったsendなどの処理をほぼそのまま使ってます。楽だわー。


2015年11月7日土曜日

「机ドン!」検出デバイスw


■追記■

ESP-WROOM-02にも対応しました(リンク)。

■原因はWindows/Excel■

どっちも嫌い。Excelは使い慣れているGoogle SpreadsheetやNumbersと比べてUI特にモード遷移が不自然で違和感の塊だし、ASCIIキーボード愛用マカーなので日本語切り替えキーが変なところにあるのもイヤ。

そんなこんなで職場でのイライラは募るばかり。

そのせいか、ついついキーボードを「バン!」と叩いていたようで、同僚氏からクレームが来ましたです。辛く当たってごめんよ、Apple Wireless keyboard(自腹購入)。

しかし、気をつけていても直らず。

ということで、振動を検出・通知するデバイスを作りました。

■仕様■

手っ取り早くArduino nanoと加速度センサーADXL345マイコン内蔵LEDを使う。

一定以上の衝撃を検出したら、各軸に対応した色のLEDをペカペカ点滅させる。「一定以上」の値についてはボリュームで設定する。

手持ちで単純なRGB入りLEDもあるのでシリアルRGBを使う必要はないんだけど、当初ピンの少ないESP8266上で動かそうとしていたのです。しかしArduino用ライブラリでは動いてくれないので挫折、nanoにしました。

初めての秋月版、きれいにまとまったのに
なお、上の写真でADXL345(赤い基板)のハンダがすごく汚いですが、これは電子工作を再開した直後に作ったもの。隣の秋月ESPに免じて許してやってください。少しはきれいになったのは昔の勘を取り戻したというのもあるけど、大きなものでもルーペ使ってハンダ付けするようになったのが大きな要因だと思います。

■接続など■

Nano接続先
3.3v出力ブレッドボードの+ライン
GNDブレッドボードの-ライン
5v出力マイコン内蔵LEDのVdd
D2マイコン内蔵LEDのDin
A4ADXL345のSCL
A5ADXL345のSDA
A610KΩ半固定抵抗の真ん中

ADXL345接続先
SCLArduino A4
SDAArduino A5
SDOGND
CS3.3v
Vs3.3v
GNDGND
Vdd3.3v

その他、半固定抵抗の一端をGND, 他端を3.3v、マイコン内蔵LEDのGNDをGNDに接続します。あ、またパスコン入れ忘れた。

標準のArduinoだとA6って使えないんでしたっけ。その場合はA0-A3どれでも結構です。そしてソース上のanalogReadで指定しているピン番号をそれに合わせて変えてください…A0の場合は14です。

nanoではなくnanoパチ

■ソフトについて■

ADXL345のライブラリはAndroid Citiさんのライブラリ、マイコン内蔵LEDについてはAdafruitさんのライブラリを使用させていただきました。ありがとうございます。

あ、そろそろ年末だからAdafruitさんに何か注文しなきゃ(注:いつも同社が提供しているライブラリを他社製品でばかり使っているので、年に一度お礼代わりに何か買うことにしています)。

コードはsetupで各デバイスを初期化、点滅に必要なサインカーブ用テーブルを用意、装置の傾きなどを補正するために各軸からの値の平均値を取ってます。loopはぐるぐる回りながら加速度を読み込んで初期値との差分が一定値を超えていたら点滅用のカウンタをセットし、あとはカウンタをインクリメントしながら各軸の値をテーブルに従って変えています。無駄な演算多いけど許してください。

うーん、本当は「ドン!」のピーク値を算出し、それを元にして最大照度などを決定すべきなんですが・・・面倒くさいからやってません。また、現在は加速度で検出していますけど、重力加速度の影響で傾けたりしても誤動作してしまいます。それこそ毎度お馴染みFFTを実行して数Hz以上の加速度成分が一定値を超えたら作動する…って処理にすれば完璧だと思いますが・・・・面倒すぎるのでやってません。