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

2021年1月13日水曜日

受託開発事例:24桁 7セグメントLED表示基板

クラウドワークス案件です。提案が4人の方とコンペになりましたが、短納期と提案内容が要望にフィットしていたことと、スイッチサイエンス様などで製品を販売している実績をご評価くださった、とのことです。実際契約は12月25日、年末年始を挟んで、先方への到着は1月8日でしたから丁度2週間です。

クリスマス?正月?なにそれ。

1.ご相談内容

Arduino nano + DIPのMAX7219 x 3個で24桁の7セグメントを駆動する基板を作って欲しい。

2.提案・契約内容

ブレッドボードで回路の検証をした上で基板を設計・発注し、1枚をサンプルとして実装して動作確認した上で、動作確認基板1枚と生基板5枚を納品する。24桁のLEDは等間隔で並び、ネジ穴は50mmピッチ。1Uラックマウントのため高さ40 x 幅410mm。Arduino unoとMAX7219は裏面にいずれもソケットを介して実装。

要求仕様にはなかったのですが、DCジャックを追加できるパターンを基板上に追加しておきました(過去の経験からUSB経由だと電源足りなくなることがあるので)。

納期は発注から4週間、納品で動作確認できたら検収、その後メッセージで2ヶ月程度のサポート期間を設ける、という条件でご契約いただきました。

費用は、えーと、ホテル一泊分ぐらいでしょうか(GoToなしで)。

3.設計

まずブレッドボードで動作確認です。3個直列にしたMAX7219でも信号波形などに乱れがないことなどを確認します。

でかいので右側省略

設計は例によってEagleです。1辺の長さ410mmというのは私としては過去最長です。回路設計ができたところで顧客に送って確認してもらいます。その間にアートワークです。

DIPですし実装密度も低いので、電源をドーンと引いてから高速の信号線を貼り、それ以外は自動配線で調整しました。銅箔勿体ないので裏表GNDベタ貼りでベタが入らないところはVIAでコツコツと潰していきます。配線数少ないのですが、Eagleの自動配線って面積に比例するんですね……最適化=HIGHだと、開始してから食事に出てもまだ終わっていなくてびっくりしました。そしていつも思うけどネジ穴邪魔だわ。倉橋屋では顧客からいらないと言われない限りネジ穴を開けるのですが……部品と比べてデカいんですよね。

でかいので略

できあがったところでPCBWayに発注。今回他の案件とまとめたので送料が少しは安くなったのですが、それでも基板10枚と送料で約8000円でした。それでも24時間で出荷されるから大したもんです。DHLで深圳から5日で到着。ちなみに同じ日にDigiKeyにも注文を出したのですがアメリカから3日で届いて現代文明とても怖い。

4.実装確認

届いた基板、でかくて重いです。銅箔35μ両面ってこんなに重いんですね……。はんだ付けして動作確認します。当然一発動作。各所の信号をシンクロで確認して十分な動作マージンがあることを確認します。


それにしてもデカイ。でかいけど、これだけ並ぶとかっこいいですわ。

5.納品と動作確認

納品したものをクロネコヤマトで発送して動作確認していただき、検収となりました。

中身がでかいと箱もでかい。手元にたまたま丁度良いヨドバシの箱があったのですが……これが80サイズを1センチ越えてしまって……泣きながら送料を払ったのは良い思い出です ^ ^

冒頭に書きましたように、12月25日にご契約いただき、1月8日に先方に到着しました。

以上です。

以上、技術的な難易度は何もありませんし、MAX7219とLEDを組み合わせた基板はaitendoなどでも安く売っているのですが、左右に耳がついていて密着できなかったりで制約があります。

こういう技術的には難しくないけども、市販にないサイズ・形態のものが欲しい、という場合は比較的低価格で提供可能ですのでぜひご相談ください。

ココナラは手数料が高い(25%)のでクラウドワークス(20%)またはTwitter @TareObjects へご相談いただけると嬉しいです。

ココナラ    :倉橋のプロフィール / 製作相談

クラウドワークス:倉橋のプロフィール

--

この他に、「電子工作のキットなどをきちんとはんだ付けして組み立てます」っていうサービスも提供しているのですが、何故か現在故障修理品の依頼が多いです……私ら電子工作勢の家にはハンダゴテがゴロゴロしていますけども、普通のおうちにはないですもんね。折れた端子をちょこっとはんだ付けして送り返すだけなら、メーカーのサービス窓口よりも安く直せると思いますので、ご相談ください。

「ラズパイで使いたいけど拡張基板のピンヘッドだけはんだ付けして欲しい」なんてのも大歓迎です。慣れないと、はんだ付けが悪くて動かないのかソフトに問題があって動かないのか切り分けに苦労しちゃいますけども……少なくともうちでははんだ付け不良ゼロで組み立てますので、ソフト技術者の方はソフト開発に集中していただけます。

自動噴霧器:費用感からの案件相談→設計製造受託

【追記2021年3月1日】

おかげさまで、ココナラ プラチナランクを獲得しました。

今後ともどうぞよろしくお願いいたします。

【追記ここまで】

 私こと倉橋屋では、ココナラ / クラウドワークスを使って電子デバイスの製作相談を受け付けています。

なにか装置が必要な場合に、それが1万円でできるのか、それとも100万円かかってしまうのか、まったく見当がつかないと業者さんにお話をするのにも不安です。

そこで、ココナラでは実現可能性も含めておおよその実現方法と費用感、あと簡単な仕様書をお作りするサービスを行っています。仕様書を作成してから、実際の製造につながることも多いです。先日完了した案件を例にご紹介させてください。

1.可能かどうかの相談

まずこちらのページの「見積・カスタマイズの相談をする」から、どういうことをやりたいか、おおよそのお予算感をご相談ください。

マイコン応用製品の開発相談受け付けます

この段階では、実現可能性についてお答えします。この段階で技術的・あるいは予算的に難しい案件については、ここでの無料相談のみで終わりとなります。無料なのでどうぞお気軽に。

可能性のある案件についてはサービスをご購入ください。5000円です。

■実例:相談■

Arduinoを使って一定の時間ごとに噴霧する装置を作りたい。ソフトはある程度わかる。回路設計と基板製作とソフトをお願いするにはいくらぐらいかかるでしょう?

■回答■

市販の電池式噴霧器を改造するのが良いと思います。数万円、1ヶ月程度で対応可能です。

2.相談サービスご購入

電源の供給方法、噴霧の方法(頻度、噴射時間、最大回数など)、表示方法(LEDの点滅で待機中・噴霧中・噴霧回数超過などを表示)、最大回数などの設定方法をメッセージでやりとりしながら決めていきます。

最終的に提示した設計書がこちらです。


自動噴霧デバイス外見仕様書

作成者:Koichi Kurahashi(倉橋浩一)

作成日:2020年11月19日 v1.0

定義:

本装置は市販の電池式噴霧器を駆動して自動的に消毒液を噴霧する。装置全体を自動噴霧器と呼び、制御部分を制御基板と呼ぶ。装置全体=電池式噴霧器+制御基板+モバイルバッテリ+配線にて構成される。噴霧には電池式噴霧器に改造を加えたものを使用し、本装置から約5V 1A程度の電流を一定時間供給することで噴霧器に内蔵されたモーターを駆動する。人感センサーを搭載し、人を検知しているときには噴霧しない。

納品成果物:

  • 自動噴霧デバイス外見仕様書(本書)
  • プログラムソースコード
  • 制御基板ハードウェア回路図、同プリント基板設計図、同部品表(Autodesk Eagleを使用)
  • プリント基板10枚、うち1枚は実装し動作確認済
  • サンプルバッテリー1個
  • 上記の部品調達、組み立て、プログラムを修正するためのアドバイス
  • 納品物には電池式噴霧器は含まれません。

納期・保証期間

  • 受注確定後6週間以内に試作品と基板を納入
  • ただし想定外の仕様や調達上の問題により遅れが生じそうな場合には双方協議の上対応する
  • 故障等
    • 納入後3ヶ月間の開発側の問題による破損はセンドバックによる無償修理。
    • 納入後3ヶ月間の利用側の問題による破損は基板1枚を送り返してもらい3000円で1台製造して返送。
    • 原則として修理ではなく新品を1個製造する形で対応します
    • 納入後3ヶ月経過後は「製造依頼」として別途お見積りとさせていただきます。
    • 物品送付における送料は双方元払い
  • サポート
    • 納入後3ヶ月間はココナラのメッセージにて対応します。

担当外

  • 電池式噴霧器の調達、選定および改造はご自身でお願いします。
    • あまり大型のものはモバイルバッテリの性能を越えてしまうので単3電池4本タイプをお勧めします。

外部との接続

  • モバイルバッテリ:USB - DCプラグ内径2.1mmケーブル
  • 噴霧器:ターミナルアダプタ2P(+とー)の導線を接続
  • 人感センサー:ピンヘッダ3P(5V, GND, 信号)にセンサーを直接または約0.7mm単芯導線にてセンサーを接続。
  • 状態表示LED:ピンヘッダ2P(+とー)にLEDを直接または約0.7mm単芯導線にてLEDを接続

基板上の要素

  • ・マイコンモジュール(Arduino Nano互換品を使用)
    • USBレセプタクルとUSBシリアル回路と保護回路
    • PCとUSBを接続してプログラム書き換えが可能
    • 自動噴霧器としての動作中はUSBでモバイルバッテリを接続して電源供給する
  • 改定前・噴霧時間設定スイッチ
    • ロータリーDIPスイッチにより設定する。
  • 改定後・噴霧時間・強度スイッチ:
    • ロータリーDIPスイッチにより設定する。
    • 1-5 : 2秒で強度1-5、6-0 : 4秒で強度1-5】
  • 噴霧間隔設定スイッチ:ロータリーDIPスイッチにより設定する。
  • 追記・噴霧回数設定スイッチ:ロータリーDIPスイッチにより設定する。
  • 噴霧器駆動回路と保護回路と接続端子
  • 人感センサー駆動回路と接続端子
  • 改定前
    • 補充ボタン
      • リセットボタン兼用・押すと再起動して噴霧回数をリセットする
  • 改定後
    • リセットボタン……注記:補充は動作確認ボタンの長押しにて実施】
  • 動作確認ボタン(押すと即座に噴霧する)
  • LED駆動回路(電池切れ / 噴霧回数超過警告ランプ)

制御要素

  • 電源接続で自動的に動作を開始する。噴霧回数を読み取り保持する。噴霧1回ごとにカウントする。
  • 動作中のLED表示は以下の通り
    • 噴霧回数に余裕がある場合:3秒ごとに0.1秒間LEDを点灯させる。
    • 噴霧回数が設定を越えた場合:1秒ごとに0.1秒間LEDを点灯させる。
    • なお噴霧回数が設定を越えても噴霧動作は通常通り続ける。
  • 噴霧間隔スイッチから時間間隔を読み取り一定時間ごとに噴霧を開始する。
    • 動作中に変更した場合には常時スイッチを読み取り、設定秒数がその時点での噴霧間隔を下回ったら随時噴霧する。
    • 噴霧を開始時刻になったら人感センサーを読み取り、もし反応があれば開始を遅らせる。
  • 噴霧開始時には噴霧時間設定スイッチから秒数設定を読み込み、その秒数だけ噴霧器への電源供給を行う。
  • 動作確認ボタンを押すと人感センサーを無視して噴霧する。
    • ちょい押し - 設定秒数だけ噴霧モーターを駆動する
    • 長押し - 押している間だけ噴霧モーターを駆動する【加筆:同時に噴霧回数カウンターをリセットする】

以上、簡単なものですが、一応、他の業者さんに依頼しても作れるような仕様書を作成しますが、本件はそのまま私のところにご依頼いただけることになりました。なお、加筆箇所は仕様合意後に発生した不明点のすり合わせの結果、変更された仕様です。

3.実際の製作依頼

再び マイコン応用製品の開発相談受け付けます の「見積・カスタマイズの相談をする」から案件名とお送りした仕様書ファイルを添付していただきます。

ここで改めて納期と金額をこちらからご提案させていただき、合意いただいたらサービスをご購入いただきます。今回は、お見積金額から上の相談料5,000円を差し引いた金額でご契約しました。契約額は、えーと、ホテル一泊分くらいでしょうか ^ ^

ココナラは手数料が高い(約27%)ので、お客様側で購入可能なものは購入して送っていただくこともできますし、こちらで揃えることもできます(その場合は手数料が加算されます)。また、完成後の製品については、着払いで発送させていただいております。

さて、あとは進捗報告や不明な点を確認しながら設計を進めます。今回はお客様自身が実装されるとのことなので比較的大きな部品を中心にしました。基板はEagleを使って設計し、今回は中国深圳のPCBWay社に依頼しました。シルクもきれいで出図から24時間以内出荷なので最近愛用しています。私みたいな週末メイカーだと土日に設計して次の土日に物が届いているのはとてもありがたいです。

動作確認用に届いた基板に実装します。ここで使っているArduino nanoはmicro USBのついた中国製互換品です。


噴霧時間、強度と間隔、最大噴霧回数などはロータリースイッチから設定します。リセットスイッチはArduinoのリセット、テストスイッチは押している間だけ噴霧して、例えば噴霧強度を設定することができます。モータードライバに短絡保護などが内蔵されており、バリスタで逆起電力を吸収していますが、モーターの加減速はPWMでスロープ制御にしています。手前のLEDは動作表示、PIRは人が近くにいるときには噴霧しないようにするためです。プログラム的には状態遷移を1個のモードフラグで制御し、10mSecのループでタイミングを制御しています。インタラプト / インターバルは使っていません。

現在何回噴霧したかはEEPROMに記録していますので、電源を切った後でもカウントが失われることはありません。

鉛フリーはんだを使用して手ハンダ実装です。動作テストはこんな感じで。一応USBからも給電できますが、200/500mAしか取れないのでモーターには不向きです。ACアダプタから7-12Vの電源を供給することもできます。

ああっ 写真にも抜け毛がっ

4.納品

動画で動作を確認していただいた後、この完成基板と未実装基板10枚をセットにして発送しました。またファイルとしてEagleのschとbrd、PCBWay向けのガーバー一式、プログラムのソースを添付ファイルとしてココナラ経由で納品。到着後1ヶ月のサポート期間中に組み立てや変更に関する質疑応答を承ります。

こんな感じです。マイコンでちょっと制御したいものがある方、どうぞお気軽にご相談ください。

上の装置は1台のモーターを一定間隔で自動的に動かすのに手頃で便利かと思います。噴霧器以外の用途に使いたいという方はココナラ(倉橋のプロフィール)もしくはクラウドワークス(倉橋のプロフィール)もしくはTwitter @TareObjects まで、お気軽にご相談ください。

2018年11月16日金曜日

Arduinoでカラスを追い払う…1



ハト対策が一段落したので、ハト対策に使った装置(PIRで体温を検知すると2つのNeoPixelsが激しく点滅する、だけ)をゴミ集積場に設置してみたところ、いつもは朝7:30ぐらいには盛大なパーティーを開いているカラス2羽がゴミを荒らすことはありませんでした。

すぐに「危険性がない」と舐められるような気がしますが、とりあえずは1勝ですw



2018年11月16日
06:00ごろPIR検知のNeoPixelsを設置。被害ゼロ。

〜2018年11月27日
火曜と金曜に設置、被害ゼロ。近所にたくさん似たような集積所があるのでわざわざヤバいところに行かなくてもいいんじゃね?的な判断なのだろうか。なおご近所の散らかりっぷりは変わらず。

2018年11年30日
設置停止したが被害ゼロw とりあえず被害が再発するまで停止するわ。

2018年12月11日
被害再発しました。ただ、9Fから私が顔を出しただけでカラスが逃げる。装置ではなく私が危険認定されている可能性。




2018年10月25日木曜日

ESP-IDF+Arduinoで書いたプログラムをバイナリ配布する


LGPLなライブラリを使用している場合、当該ライブラリが静的リンクなら製品のソースを配布しなければならない等いろいろありますが、少なくともArduino coreを使用している場合には、ユーザ自身の環境でビルドしてライブラリのバージョンアップなどに対応できるようになっていればソース公開の必要はないとされています(※下記FAQの記載ですが実際に利用する際には弁護士などに確認してください)。

個人の開発であれば、面倒なのでgithubでソース公開しちゃえば良いのですが、企業での製品開発だとソース公開ができない場合も多いです。

そこでESP-IDFを利用している場合に製品のバイナリだけ配布する方法を調べてみました。試行錯誤でずいぶん手間取ってしまったのですが…結果としてはとても簡単です。コンポーネントはlib〜.aとしてまとめられるので、これをcomponent.mkで指定してmakeするだけです。通常はlibmain.aですが、componentsに自身で書いたコードが置いているときには、lib+コンポーネント名のlibができます。

  1. esp-idfでmake
  2. build/main下にあるlibmain.aをプロジェクトディレクトリに移動
  3. その他の自作コンポーネントがあれば同様にlib〜.aを移動
  4. main下のcomponent.mkに
    COMPONENT_ADD_LDFLAGS := libmain.a
    を追加する。他の自作コンポーネントがあればスペース区切りで列挙
  5. main下および自作コンポーネントのソース(.c, .cpp, .h)を消す
  6. buildディレクトリなど不要な要素を消す

これだけです。makeでビルドできるはずです。ビルドが確認できたら、component.mkへの追加事項などビルドに必要な情報を記載したreadmeとlib〜aを配布すれば、ライセンス要件をカバーできます(くれぐれも弁護士さんに確認してから実施することをおすすめします)。

ライブラリを追加すれば良いのはわかっていたのですが、COMPONENT_ADD_LDFLAGSで追加するという方法を見つけるまでさんざん苦労しました…お役に立てば幸いです。

2018年2月24日土曜日

PmodMTDSループ



ちょっとマルチタッチ液晶ディスプレイでデモを作りたくて、PmodMTDSを物色

→事前にArduinoのサンプルがビルド通ることを確認。ソースを見ても他CPUへの移植はそんなに難しくなさそうだなと判断して注文

買ったのはShield版ではないですがArduino unoで動きました。

デモを動かすには別途microSDカードが必要です。

配布されているFAT32でフォーマットしたSDカードにダウンロードしたArduino版ツールを解凍するとDocumentation, Libraries, Resources, Sketchesフォルダがあります。

Resources下にある2つのフォルダごと画像をコピーしてmicroSDのルートにコピーして、MTDSにセットします。

もしArduino IDEが起動していたら終了し、Arduinoのlibraryフォルダの下にMTDSというフォルダを作り、その中にLibraries下の2つのフォルダの中身をコピーします。

Sketches下の.pdeを.inoにrenameしてダブルクリックすればArduino IDEが起動します。念のためですが、結線前のArduino unoにコードをダウンロードしておいてから結線します。

MyDispDemo1は表示だけ、2は読み込み後☆をタップすると画像が変わる、3は待ち時間wheelを表示した後でボタンをタップすると画像が変わる。3にはチェックボックスっぽいボタンが表示されているのでいろいろ期待しちゃうんだけど、ただのデモみたいっすね。

あmicroSD上の画像の処理はぜんぶPmodMTDS上で行われます。でも画像の書き換えは遅いですね。書き換えているところが目に見えます。MTDS上のCPUはPIC32なのでそんなに遅くないはずなんですが。

あとでArduinoより速いCPUでも試してみようと思ってRaspberry pi用のPmodHATも注文してしまったんですが、無駄になっちゃいましたね…。

以下はPmodMTDSとArduino unoとの結線図。

PmodMTDSArduino uno
P1 : ~CSdigital 10
P2 : MOSIICSP4 : MOSI
P3 : MISOICSP1 : MISO
P4 : SCLKICSP3 : SCK
P5 : GNDGND
P6 : VCC3V3
(下段 : NC)


2018年2月10日土曜日

ArduinoでSG90をゆっくり滑らかに動かしたい(失敗)



サーボSG90を20度/秒ぐらいで滑らかに動かしたいと思ったのですが、どうも難しいです。割り箸をホットボンドで接着するといういかにも共振したりハンチング起こしそうな条件ではありますが。

試行錯誤としては、
  • Arduino標準のServoライブラリのexample
  • 同じく、値を変えるごとにdetachしてdelayし再度attach
  • ESP32のLEDCを使って15bit PWM
  • ESP32 / Arduino unoでdelayMicrosecondsを使って正確なパルスを出す
などを試みたのですが、いずれも動画のようなブルブルっぷりでした。強いて言えばLEDCを使ったものが一番良かったですが、やっぱり震えます。今回使ったのはSG90のパチ品です。本物あるいはもっと高価なサーボを使えば滑らかに動いてくれるのでしょうか?

うーむ。

一応LEDC版のソースです。delayは「次のPWMパルスが出そうなところでledcWrite命令を出すとパルス列がコケるのではないか?」ということで一つだけ出るようなタイミングにしてみたりPWM周期を変えてみたりしましたが特に大きな変動は見られません。

こっちはdelayMicroseconds版。

2018年2月5日月曜日

Arduino nanoで肩こり対策デバイス・その2


■原理■

同僚さんから、「肩こりがひどいので電子工作で何かできないか」というご相談をいただいて作ってみたシリーズ第二弾です。第一弾は首肩の傾斜で振動するパターンでした。

今度は「ふと気がつくとモニタに近づきすぎている。近づいたら警告を」というデバイスです。モニタの上端に貼り付けて使います。

距離計測は超音波とToFを試してみたのですが、超音波は人間の顔だとあまりうまいこと検出できず、手持ちのToFは計測レンジが微妙に遠くてNG。シャープの赤外線距離測定デバイスを使うことにしました。

■製作■

Arduino nanoのパチを使いました。

距離センサー

表示にはNeoPixels / WS2812b的なLED

回路は、それぞれのGND同士をつなぎ、ArduinoのVinとセンサーとNeoPixelsの電源同士をつなぎます。距離センサーは最大約2.8vのアナログ出力なのでアナログ入力A0、ArduinoのA1とNeoPixelsのDinをつなぎます。

今回、0.19mmのエナメル線で配線しました。ワイヤリングペンも作ったので、GND-GND-GNDとつながるような場所が大変楽です…と言いたいところですが、所要時間的には架橋ポリエチレン被覆線とあんまり変わらなかったです。



ワイヤリングペン、シャープペンに通すのに例によって30cmほどに切ったワイヤを先端から差し込んで後ろの本体と接合して引っ張り出す作戦を取りました。が、前回は0.3mmだったので突き合わせでハンダ付けできたのですが、今度は0.19mm、さすがに細くて無理だったので、瞬間接着剤使いました。この時期は空気が乾燥しすぎていてなかなか固まらないので困ったもんです。今度、接着促進剤ってのを使ってみたい。

見た目は悪いけど使い勝手は良いですw


■プログラム■

起動したら、5秒間距離を計測して平均値を取ります。これが基準値で、これより近づいたら=値が大きくなったらLEDを点灯させます。

loop()ではanalogReadからの値を簡易的な移動平均処理で測定誤差をツブして無駄なチラツキを減らしています。距離センサーからの値は最大で500ぐらいなので、上記の平均値と500との中間点までは黄色、それを越えて近づいたら赤で点灯するようにしました。


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秒間静止します。

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

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


2017年9月23日土曜日

鳩対策:Arduino + サーボで振り払う

我ながら雑だ

■再来■

えー、また鳩害対策の話ですが……廊下側の給湯器排気筒の上に来て大量の糞を落とすようになってしまいました。

当初ぐるぐるまいた鉄条網を設置したらしばらく来なかったのですが、ある日ふと見ると上に鎮座してやがりました。鉄条網ぐらいの短い針じゃあんまり効果無いですね。



■検出して振り払う■

ということで、電子工作的に対応しました(キリッ


電源はダイソーのモバイルバッテリを使いました。ボタン押さなくても給電開始してくれるのでこういう用途にばっちりです。

別にカメラ付けなくても良いんですが、やっぱ「装置が働いたことによって排除することが出来た」ってのを確認したいじゃないですかw



今回使ったAdafruitのmini spy cameraは、micro SDカードをセットして電源をつなげば、あとは信号を0.5秒以下GNDに落とすと静止画、それ以上だと動画録画を開始しもう一度落とすと止まる……という仕様です。間違って買ってしまったんですが、イマイチ使いにくいっす。

サーボはSG90のパチ物です。本物は180度動くみたいですが、これは120度しか動いてくれないし安定性もイマイチです。でも1個100円なので、こういう用途には十分です。

ソフト的にはPIRが検知したら撮影を開始し、ちょっと待ってから数秒間サーボの腕(割り箸をサーボホーンにホットグルーで接着)をぶんぶん振り回し、撮影を止める……というたわいないものです。

サーボはタミヤのプラスチックアングルに固定し秋月のこれで給湯器に貼り付けました。以前にも書きましたが、コレの接着テープは非常に強力でキレイな面に貼るとちょっとやそっとでは剥がれません。ご注意下さい。ケースはレーザー加工したMDF箱が大量に余っているのでそれを流用し、ネオジム磁石のフックで吊りました。

我ながら雑です。

雑ですが、設置期間中は鳩の糞はありませんでした。そして、spy cameraにも鳩らしいものは写っていませんでした。ははははははorz

■そして物理障壁設置へ■

というわけで、一応効果のある装置でしたが、公団に文句を言い続けてたら対策してくれました。



物理障壁強い。横から入りそうで少し心配な形状ではありますが。

【追記2018年8月29日】
今日まで書き忘れていましたが、今年になってからまた来るようになりました。廊下全体にテグスが設置されているわけではないので、まぁ当たり前ですよね。糞を掃除するのにも疲れましたので、またぞろ対策します。

2017年2月26日日曜日

Arduinoで実用品:ポンプ駆動装置・3 【ケース編】

ソフト編をまだブログにまとめていませんが、いよいよ完成です(オイ)。

苦労しましたー。

ただ、レーザー加工という技術を知らないままだったら、たぶんお引き受けできなかったと思います。手近なレーザー加工レンタルあるいは手頃なレーザー加工業者さんが見つかったことが大きいです。

■まず概要設計■

ユーザさんから利き手や手の大きさ、作業時の姿勢などをヒアリングします。長時間操作する必要のあるボタンなどは腕を上げた状態だと辛いので、テーブルに腕を置いた状態で指の動きだけで操作できるようにします。

最初の提案ではボタン類はすべて正面に置いていたのですが、机の上に手を置いた状態で自然に操作できるよう左右に振り分けました。

右側にstartボタンと緊急stopボタン、左側にパラメータ設定用ダイアル。正面下にディスプレイを設定しました。実際にテーブルに手を置いて、自然に指を伸ばすと机から50-70mm、などと実際に測定することも大事です。

3D CADなどの使える人は、ACアダプタ、モーター、基板、スイッチなどの各要素を大雑把な立体(直方体や円錐)で表現して、配置を考えます。私のように3D CAD使えない派は、紙に三面図を書いてその上に並べてみるのが一番です。その際、部屋の模様替えでやったように主要な部品を切り抜いた紙で作っておくと捗ります。

なお、其の場合、本体から飛び出してくるコードのことを忘れないようにしましょう。ネジ穴などを開けちゃった後にDCアダプタを入手したら、当初想定していたDCプラグより遥かにご立派なものがついていたので、配線の余裕が減ってちょっと苦労しました。

今回ギリギリのサイズではないので助かりましたが、「小さくして」は常に要望として出て来ることなのでやっぱり3D CADなどで干渉しないかチェックできるようになりたいですねぇ・・・。

できたら一度図面を清書して、主要な寸法を書き込んでおきましょう。また、各部品のネジ穴サイズと位置なども計測して記載しておきましょう。

■設計準備■

外寸をベースにして、MakerCase.comでFinger Jointのケースを定義しました。

アクリルは圧縮性がほとんどないので木材のようにごまかしがききません。ホゾを組み合わせる面が狭すぎれば入らないですし、広いと接着剤の泡が目立ちます。またレーザー加工機ではビームの太さの分だけ素材が消滅しますので、切断時にはその分を織り込んでおく必要があります。

レーザー加工機ごとにビームの太さが違いますので、工場にビームの太さを尋ねます。だいたい100-200μm(0.1 - 0.2mm)です。

MakerCase.comでは、データの詳細設計ページに各種パラメータを設定できます。Vector Cuttingでは切断線の太さを色を指定します。多くの加工機で0.01ptの#FF0000を指定することが多いのですが、ここではちょっと練習として2mmの#FF0000を設定し、Laser Cutting Kerfタブの「Laser Cutting Kerf - beamwidth」というパラメータをいじってみます。0を入力するとこうなります。


一見ピッタリあっているように見えますが赤の部分は消えてなくなってしまうので、太さの分だけスッカスカになってしまいます。次にkerf:0、ビームの太さの1/2=1ということで本来-1を入力すべきかと思うのですが1を入力します。するとビームの太さの分だけ溝の大きさが変わって、切断した残りが上下左右ともぴっちり合わさることがおわかりいただけるかと思います。


つまり、ここのパラメータは値が小さいとスカスカ、大きいとキツくなり、レーザービームの太さの1/2を超える値を入れると組み立て不可能・・・ということになります。

アクリルをファブスペース三鷹とElecrowで切断した経験(どちらもビーム径は0.2mm)では、ここのパラメータは0.06ぐらいが一応の目安かと思います。ミストラルさんの場合3mmのMDFでは0.04mmはかなりゆるゆるで持ち上げると板が外れる状態(でも接着剤が断面に入りやすいので作業はラク)、0.08mmはきつくて叩かないと板がはまらない状態でした。もうちょっとキツくすれば水がもれないようになるのだろうか?と思っていますがまだ試していませんw

いずれにしてもレーザー加工機によって大きく異なります。厚い板ほど顕著に症状が出やすいので、予行演習として5mm厚のアクリル板から50mmの立方体を作るデータをギャップごとに数種類用意して業者に送って切ってもらい、実際に組み立ててみるのが良いかと思います。おかげで私の部屋はMDF板の焦げるにおいと、使い道の分からない木箱とアクリル箱がゴロゴロしております(笑)。

■設計■

手順としては、MakerCase.comで箱データを出力し、Illustratorで穴あけデータを加える、ということになります。

上記の通りMakerCaseデータは各パーツが隙間なく密着していますが、これはレーザー加工機にとってよくないので、Illustratorで適当に離します。

穴あけは内寸外寸を間違えないように相対指定やらグループ指定やらを駆使して正確な位置に丸や長方形、角丸などを配置していきます。昔、スイッチの回転防止の切り欠きをアルミシャーシの上に作るのは大変だったなー、などと昔話に逃げると切りがないのでやめます。でもドリルとニッパーとヤスリで小一時間かけて開けたスイッチ取り付け穴が線描くだけで寸分の狂いも怪我もなく仕上がるのだから素晴らしい。

■カット■

今回、いろんな都合により、2箇所のレーザー加工機の合作となりました。材料を買ってあったので、ファブスペース三鷹へ行ったのですが、以前書いた通り加工機が途中でオーバーヒートして4枚しか切れませんでした。再度三鷹に行ったりしましたが、結局うまくいかず、急遽ミストラルさんで切って送っていただきました。

それぞれビーム太さが違うのでちゃんと組み上がるか心配でしたが、問題ありませんでした。

■接着■

UVレジンでの接着などいろいろ練習しましたが、強度優先でアクリサンデー接着にします。ここからは、なるべくホコリや指紋がつかないよう「品質管理用手袋」を着用します。

筐体の内側になる面の保護シートを剥がして、底+後+左+右を組みます。指組でないふつうの直線接合なら2枚ずつ接着していくのですが、指組の場合は一箇所が0.1mmずれただけで他の板が永遠にはまらなくなってしまうので3-4面を組んだ状態で「直角」を確保する必要があります。

組み立てたら、ここでもう一度、接着面にゴミやホコリが挟まっていないか確認して、ハタガネでスキマがあかないように軽く固定しておいてから、マスキングテープで接着面の外側を止めます。テープでしっかり固定できたらハタガネは外します。外す際にスキマが広がるようならテープでの固定が十分ではなかったということなのでやりなおしです。なおハタガネを外してから接着しないと接着剤でアクリルが解けてどんどんめり込んで行ってしまいます(経験者談)。また、テープでしっかり固定しないとスキマが大きすぎて接着強度が出ません。

さて、心を落ち着かせて接着です。アクリルサンデーを工作用注射器に入れ、一番細い針を取り付けます。そして、奥から手前に引くように接合ラインに接着剤を流していきます。毛細管現象で吸い込まれていきますが、吸い込まれるときれいに透明になるので、それ以上は注がないようにしつつ、一定の速度で静かに静かに。底面の3辺について接着が終わったら、指で左右から押して見てスキマがないかを確認します。特に奥と左右の板をつなぐ箇所が緩んでいないかをチェックします。アクリル接着剤は数秒で固まりますが、やはり数十分放置しておいた方が接着面に曇りなどが入らず良い仕上がりになると思います。

で、奥と左右の接着ですが、前述の通り、縦に接着剤を流すのは難しいので、箱を横倒しにし、奥の面を下にして接着剤を流します。

今回、メンテナンス性を考えて前面と上面は接着しません。上面はポンプの自重で固定されますし、前面は指組でがっちりハマってます。

■組み立て■

部品を取り付ける前に、もう一度、エアダスターでホコリを飛ばしてからマイクロファイバーで念入りに掃除します。

奥にあるACアダプタをテグスで縛ります。結び目は外科結びにして、UVレジンで固めます。

基板は貼り付けボスで固定します。これの両面テープは異常に強力なので、一発で位置を決めてください。相手がアクリルの場合は張り付いたら傷を付けずに剥がすのはまず不可能です。ボスと基板には3mmのタッピングビスで止めます。

OLEDはスペーサーとプラスチックネジを取り付けてネジにセメダインBBXを塗り、アクリル板の穴に差し込みます(その前に外側にマスキングテープを貼っておくこと)。BBXはゴムのような粘着系なので、それほど機械的強度の必要ないものを止めておくのに便利です。

フットスイッチの配線を通し、一回結び目を作って外から引っ張られても基板コネクタに力が伝わらないようにしてから基板に接続します。あとはコネクタの順や配線の取り回しなどを配慮しながらスイッチ類を固定していきます。スイッチ類は基本的にコネクタで接続していきますが、ロータリーエンコーダーとゲームスイッチははんだ付けなので、引っ張られて断線しないようにこれらもUVレジンで固めておきます。

ポンプは別の機種への交換がありうるとのことなので、レジンでは固定しないでおきます。基板側はターミナル接続なので、引っ張られて断線しないようにテグスで結んでおきました。天板とポンプの固定は、ステンレスのM4ネジです。ポンプの寸法図にネジの長さがわかる数字が記載されていなかったので少し長目のものを注文したのですが・・・長かったです。両側にステンレスワッシャーを入れて、ステンレスナットで固定します。

ネジ類はモノタロウがラクで安いんですが、この先の人生で多分使い切ることのでできないであろう300個のM4ステンレスワッシャーとどう暮らして行けばいいのでしょうかw

フロントパネルとポンプのついた天板を乗せて完成です。

まずポンプに何もつないでいない状態で電源を入れて試運転。動きました。次に、薬剤タンク、ポンプ、注入ボトルをテスト用のシリコンチューブでつないで運転してみます。チューブが柔らかすぎて吸入側が潰れますが、何とか吸い込んでくれて動作しました。実際に使用する際にはもう少しかたいチューブを選ぶ必要があります。表示やロータリーエンコーダでのパラメータ設定も問題なし。一応本業はソフト屋ですので、UIはしっかり作りました(自画自賛)。

完成です。


横出しのコネクタにしたりケーブルの色を揃えたりすればもうちょっと見た目きれいになったと思うのですが、うーん。あとフットスイッチの色が渋いっすね。

■失敗リスト■

本体はともかく、プラグ類が想定よりもでかくて固くて対応に困った
→特にACアダプタ。手元にある24V1Aので設計したら、24V2Aのはご立派でした。

部品を取り付ける穴は忘れなかったけどケーブル通す穴を忘れていた
→追加で加工

ネジ穴のない重量物(ACアダプタ)をどうやって固定するか悩んだ。
→底板に追加で穴を開けてテグスを外科結び+UV接着剤で固めた

MakerCase.comの「内寸指定モード」にバグがあって意図した寸法ではなかった
→試作MDF板で気づいたのでダメージは少なかった


2016年12月28日水曜日

Arduinoでロータリーエンコーダー

[追記]「この書き方だと、メインルーチンの方で値を読み込もうとしている間にインタラプトが入って値が桁上り時などにとんでもない値に変わってしまう可能性がある」とのご指摘をいただきました。

Z80アセンブラやCP/M上でBDS-Cなんていじってた当時はそういうのに気遣うのは当たり前だったんですが、すっかり高級言語で安逸な暮らしをしておりました……いかんですね。

記事はこちらです。

ご指摘感謝します[追記終わり:2022年3月11日]

写真:まさにバラック配線w

「ロータリエンコーダーなんて懐かしいブツのためにライブラリ使うこともないわなー」

…と考えていたこともありました。さがすより作った方が速いわw …なんて。

いえ、結局自分で作ったんですけどね…ちゃんと動くまで2時間ぐらいかかりました。

■原理■

あちこちで書かれているので簡単にまとめると、ロータリーエンコーダは位相の90度ずれた2つのスイッチからの信号を元にして、どっち向きにどのぐらい回転したかを検出するデバイスです。まぁ回転とは限らないのですが、ほとんど回転物で使われます。

2つのスイッチからの信号を2ビットのデータとみなした場合、正回転だと値 0▶1▶3▶2 と変化します。逆回転だと 2▶3▶1▶0 ですね。0123あるいは3210と変化してくれればまだ簡単なのですが、これは一種のグレイコードというもので状態の変化(この場合は回転)で一度に1ビットずつしか変わらないようにしているものです。1ビットしか変わらないので、チャタリングが起こっても値がどったんばったんすることがないというスグレモノ。

なので、今回はこれを読んだ値>順番値に変換します
int readEncoder() {
  const byte gray[] = {0, 1, 3, 2};
  return gray[(digitalRead(EncoderA) << 1) | digitalRead(EncoderB)];
}
これでめでたく0,1,2,3の値が返ってきます。

あとは、両方のピンに対して割り込みを指定し
void attachEncoder() {
  attachInterrupt(digitalPinToInterrupt(EncoderA), encoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(EncoderB), encoder, CHANGE);
}
割り込みを受け付けるルーチンではこんな感じに増分と繰り上がりを処理します。
void encoder() {
  detachEncoder();
  delay(10);

  prevGray = currentGray;
  currentGray = readEncoder();
  if (currentGray == prevGray + 1 || (currentGray == 0 && prevGray == 3)) {
    encoderValue++;
  }
  if (currentGray + 1 == prevGray || (currentGray == 3 && prevGray == 0)) {
    encoderValue--;
  }

  attachEncoder();
}
delayはチャタリング対策。普通は1mSecぐらいで良いんですが、粗悪品なのでこれでやっと安定しましたw ただ、delay大きすぎると応答が鈍くなるので高速回転するものには使えません。1秒100パルスを超えるようなものについてはフォトインタラプタを使うかコンデンサ+シュミットトリガでハード的なチャタリング対策をしましょう。

あと初期化と定義部分です。
const int EncoderA = 2;
const int EncoderB = 3;
volatile char prevGray;
volatile char currentGray;
volatile int encoderValue = 0;
void setupEncoder() {
  pinMode(EncoderA, INPUT_PULLUP);
  pinMode(EncoderB, INPUT_PULLUP);
  prevGray = currentGray = readEncoder();
  attachEncoder();
}


値はメインループで
int prevValue = -1;
void loop() {
 
  if (prevValue != encoderValue) {
    Serial.println(encoderValue);
    prevValue = encoderValue;
  }
  delay(100);
}
などと使えばOKです。あ、setupEncoderはsetupから呼び出してください。

[追記]冒頭の追記に関する部分ですが、この当時のこのブログの文字修飾方法が古すぎてソースを編集できないので加筆します。

void loop()と最初の行の間に
  noInterrupts();
  int copyValue = encoderValue;
  interrupts();
として、copyValueを使うようにしてください。値をコピーする間インタラプトを止めて、コピー後にインタラプト再開しています。こうすればご指摘いただいたような現象は回避できます。また、ARMやESP32などでは4バイトのうちの一部が変わって、というような現象は起きないですが、後続処理中に値が変わったら困る場合には上記のような処置が必要です。

しかし5年前の記事か……最近はインタラプト使わずノンプリエンプティブマルチタスクのFreeRTOSで安直な人生を送っております(遠い目)[追記終わり2022/03/11]

いやー…実は機械式ロータリーエンコーダを扱うのはこれが生まれて初めてでした。IoTとかで上流ばっかり見てないで、たまには足元のあれこれもいじらないといかんですね。

なお、試作なのでジャンク使っていますが、納品用にはちゃんとアルプス製を使いますからご安心ください>お客様

ああ…ロータリーエンコーダーの操作の通りにスムーズに回転/逆転するモーター。気持ちがいい…w

余談ですが写真で赤く光っているフジソク 照光式押ボタンスイッチ CLP44-L2-2はすごく良いですね。無接点(赤外線インタラプタ)なので安心して使えて120円。昔こういうスイッチって1000円ぐらいしたんだよなぁ…と遠い目をしておしまい。

秋月のサイトから

■(久々の)ハマりポイント■

  • え!Arduinoって全ピンでInterrupt使えないの?
    配線して動かしても全然反応がありません。他のプラットフォーム同様、attachすれば全部イケるのかと思ってたんですが…Arduino nano / unoの場合にはD2, D3しかインタラプトに使えないんですね…はっはっはっはっは。

  • Encoderの仕様書がなくてピンを間違う
    aitendoで買ったほぼジャンクのエンコーダで試しています。このタイプのエンコーダには3本の端子がA-GND-Bと並んでいるものと、A-B-GNDのものがあります。今回、事前にテスターで調べてA-B-GNDだと判断したのですが、しばらく動かしてどうもおかしい。ネット上に上がっているプログラムでも正しく動かない。改めてテスターで調べたら前者ではなく後者だったという落ち。
  • prevの処理
    前回読み込んだ値と、今回読み込んだ値を比較するために、今回の値をprevGrayに保存しておくべきなのですが。忘れてました。何その致命的ボケorz

  • やけにノイズが規則的だなある程度動くようになってから、シャフトのクリック感に合わせて動かすと4,8,12,16....16,12,8,4と4の倍数ずつ増減します。たまに数字が飛ぶので、チャタリング豪快だなwと思ってしまったんですが…単にクリック間に4パルス出てた、という落ちでした。普通そう考えるだろ…。
ああ恥ずかしい…。

2016年12月22日木曜日

Arduinoで実用品:ポンプ駆動装置・1 【ハード編】


■概要■

ご依頼をいただいて、24Vギヤードモータ付きチューブポンプ駆動装置をArduino nanoで作っています。

Arduino nanoを選んだのは、今回スイッチと表示機とモータードライバを駆動するのでGPIOがたくさん必要、WiFi不要、安価、5V仕様…など。

チューブポンプはツカサ電工のPT-FP1-550-KA,24V。定格24V600mAで1分間の吐出量550mlです。

モータードライバはモータードライバー TB6643KQ、今回逆転は必要ないのですが、一応汎用性を考えて選びました。保護回路などを考えるとバラのMOSFETで作るより安いですし。

表示器には電子工作業界標準(笑)のOLED 0.96を使います。

入力は、スタートボタン、内照付きストップボタン、フットスイッチ、設定用ロータリーエンコーダ。

ケースはアクリル板で作ります。このためにDraftSightという2D CADを習得して図面引きました。最初CADの操作感がわからず、いくつか穴の開いた長方形のアクリル板を描くのに2時間ぐらいかかりましたが、チュートリアルを終えた今、もうサクサクです(当社比)。Illustratorより性に合っている感じ。その後またIllustator派に鞍替えしましたw

当初アクリル板を仕入れてファブスペースみたかのレーザーカッターでカットしようと思っていたのですが…45分の使用料2160円+施設使用料1080円の合計3240円。ちょっと1枚カットしてくるだけだとちょっと痛いなぁ…と思ってElecrowさんのアクリル板加工サービスの見積を取ってみたら、送料を含めても未加工アクリル板を日本で買うよりも安かったので、お願いしてみようと思ってます。試作は近所で手軽に、完成品は海外で。おおメーカーっぽい(笑)。

■回路■



ACアダプタから24vを供給してモータードライバ経由でモーター、Arduinoは三端子DC/DCで9Vに落としてVinに供給します。モータードライバは1個でいいのですが、基板上がガラ空きだったので、2個付けられるようにしました。前述の各種スイッチの端子などもそれぞれコネクタ出し。それでもまだ大量にGPIOが余っているので、一応PADとして引き出しておきました。

なおEagle Libraryとしてインターネット上で見つけたArduino nanoを使ったのですが、ピン番号が間違っていたので書き直し。いやー、公開されているライブラリを信じるな、ってのはJava業務アプリなんかだと当たり前の話なんですが、部品でも同じっすね。

 Arduino nanoをソケットで実装する形にしています。お客様が遠いのでソフトをアップデートする必要があるときには、プログラムを書き込んだnanoをお送りして差し替えていただく想定です。

廉価版(prototype)だけど、きれいな仕上がり@Elecrow

なお、基板はご希望があれば送料込みサポートなし1枚1,000円でお分けします。 info@kurahashi-ya.com までメールください。

■ケース(仮)■

アクリル板で作りますが、アクリルは高いのでプロトタイプをMDFで作りました。

レーザーカッターでMDFを切断してスイッチなどを取り付けてみたら、こんな感じです。CADは無料のDraftSight Mac版を使いR2010形式で保存したものをIllustratorで整えて、Univarsalの30W炭酸ガスレーザーカッターを動かしました。

不器用でアルミシャーシをまっすぐ切断できなかったワタクシとしてはネジ穴などがビシっと合うのは嬉しいですw

仮組みというか乗っけただけですw

切断面が黒いのはレーザーカッターによるもの。MDFは木材の繊維を樹脂で固めたものなので、切断面は溶けた(燃えた?)樹脂で固まっていて触っても手に汚れがつくことはありません。布で強くこするとうっすら汚れが付く程度で、アルコールティッシュなどで拭き取っておけば大丈夫です。

しかしツマミが昭和なデザインだなorz ポンプ位置は少し手前にして全体の高さを低くし、ボタンももうちょっと右かな…。

というわけで、次回ソフト編に続きます。その後、ケース編で完結の予定です。

年内にはちょっと無理かな…。無理でした(2017-02-26)

2016年11月16日水曜日

ポンプを動かす

ver 1.0.3

ご相談をいただいて考えてみました。

目的としては、液体をタンクから小瓶に一定量移し替えること。方法は2つあります。

  1. 一定時間ポンプを動かす。
  2. 重量センサーを用いて測定しながらポンプを動かす。

1.の場合はポンプの時間あたりの吐出量が常に一定であることが必要です。簡単ですが、タンクの容積変化や液体の粘度の違いに対応する必要があるので精度は出ないですね。タイマーの代わりにArduinoを使えば、ゆっくり起動して終了時間前にゆっくり減速する、という駆動も可能なので単純なタイマーよりも使い勝手はよくなると思います。

2.については、重量センサーで計りながらポンプを動かします。チューブポンプは脈動なのでピタリと止めるのは少し難しいかもしれませんが、1よりは精度が出ます。

今回は2の方法で考えてみますが、2で作っておけばそのままの装置で1にも適応可能です(重量センサーは不要になります)。

使い方としては、重量センサーの上に瓶を置いて重量リセットボタンを押します。チューブをセットしてからスタートボタンを押すと、自動的にポンプが起動して一定量になったところで止まる、というイメージです。UIとしては、

  • OLEDディスプレイ:手軽で視認性が高くてい安い:-)
  • プッシュボタン☓5:重量リセット、重量+、重量-、開始、停止。

使うポンプはツカサ電光株式会社のチューブポンプ。チューブポンプとは成分献血や人工心肺装置でおなじみのチューブをゴリゴリと押しつぶしながらローラーが回転して、その容積変化により吸入・吐出を行うものです。ローラーポンプとも呼ばれます。でかいのはセメント圧送車なんかにも使われていますね。

吐出量550〜1800ml/minのFタイプを見てみます。とりあえず電子工作的に重要なのは消費電流、600-1500mAまでの各種タイプがあるので、定格10A程度のパワーMOSFETを使います。

OLEDとの接続はI2C。

プッシュボタンはGPIO。

ポンプの駆動はGPIOからトランジスタ経由でMOSFETを制御します。

重量センサーは高価なので圧力センサーを使います。センサーと接する面積が一定でないと誤差が出てしまいますので、センサーの上に例えばコインのようなものを置いて、その上に瓶を置く、というような使い方が必要になります。

重量センサーの校正も必要ですが、重量センサーに1円硬貨を一つずつ置いていき、そのときの値をArduino内蔵のEEPROMに記録します。ただ、重量センサーは経年変化や温度の影響を受けるので、時々校正しなおす必要があります。

電源は24vとのことなので、24V2A程度のスイッチング型ACアダプタを用います。

ということで必要な要素は

  • ACアダプタ
  • Arduino
  • OLED
  • プッシュボタンx5
  • P-ch MOSFET
  • 2SC1815
  • 圧力スイッチ
  • ポンプとの配線
  • 基板など
でだいたい5000円ぐらい。作ってくださいと言われたら、うーん、部品代+工賃で1万5千円でしょうか。圧力センサー不要のタイマー版なら1万円ぐらいかなぁ(いずれもポンプとケースなしの状態で)。

ご興味のある方は info@kurahashi-ya.com までご相談ください。

2016年6月21日火曜日

450円でESPでもArduinoでも使える高精度RTC

電子工作でRTCっていうとDS1307 / 1302あたりが定番だと思うんですが、秋月で売ってるRX-8025NBって、なかなか良いと思うんです。TXCO使ったものだともっと精度の高いものもあるんですが(NXPのPCF2129など)、450円で月差13秒程度ってのはなかなかのバランスだと思います。

秋月電子のサイトから

ずっと以前に買ってあったものの使う機会がなくて部品沼に沈んでましたが、在庫リストを見ていたら出てきたので使ってみました。

配線は、SDA - SDA, SCL - SCL, Vcc - Vcc, Gnd - Gndで何のひねりもありません。動作電圧範囲が広いのでmbedでもArduino / ESP8266/ ESP-WROOM-02どれでもそのまま使えます。

欠点としては、バッテリバックアップのラインが別になっていないので、電池やスーパーキャパシタをつなぐときにはSBRダイオードなどで一手間かかってしまいます。

この点、VddとVbatが分かれているDS1307+とかPCF2129は便利なんですよね。

余談ですが、こないだPCF2129で基板を作ったんですが動作しなくて泣いています。その辺の顛末はまたいつかブログに書きます。

■ソース■

こちらの記事を参考にさせていただきました。ありがとうございます。

RTCに多いんですが、年月日時分秒すべて60進数のBCDです。通常の10進をそのままセットするとまともな値が返ってこないので、セット前 / 読み出し後に変換してやる必要があります。fromClockFormatはBCD(60進)から10進、toClockFormatは10進からBCDへの変換を行ってます。

time_t(unix時間:1970年1月1日 00:00:00.000からの経過ミリ秒)とグレゴリアン歴との変換は標準関数で済ませてしまいました。テヘペロ。

起動するとWiFiに接続してsntpから時間を取得してRTCにセットし、あとはRTCから読み込んでは時間を表示しているだけです。

このRTCにはアラームをセットして割り込みを掛けたりする機能もあるのですが、使っていません。ESP-WROOM-02でRSTにつないでやると、deep sleepの後に指定した時刻に立ち上がる、なんてこともできると思います。



いい感じで動いているからあと何個か買っておこう。

…秋月にアフィリエイトがないのが残念です(笑)。

2016年6月18日土曜日

Arduino:関数への構造体渡しで大ハマリ

■訂正訂正訂正■

またまた電子工作部で教えていただきました。ダメなのはstruct typedefです。typedefをやめてstructなら問題ありません。

誤った情報を流してしまい申し訳ありませんでした。

出典のブログ主さんにもコメント欄から訂正をお願いしました。

Arduino(4) ブロック崩しを作ってみる(1)

記事より引用:
しかし残念なことに、「構造体を引数とする関数」はスケッチの中では定義できません。
これを行うには、構造体を別ファイルで定義する必要があるようです。

「原典に当たる」という基本を疎かにしたため、誤報を流布してしまいましたことをお詫び申し上げます。


■typedef渡しでエラー■

このコードをコンパイルしてみてくださひ。ESPの人はそのまま、Arduinoなら最初の3行をコメントアウトして。

extern "C" {
#include "user_interface.h"
}

typedef struct {
  float temperature;
  float humidity;
  float pressure;
  float airQuality;
} OneData;

void func(OneData *inData) {

}


void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}

そうすると…

Arduino:
Arduino_Function_Sample.ino:7:11: error: variable or field 'func' declared void
Arduino_Function_Sample.ino:7:11: error: 'OneData' was not declared in this scope
Arduino_Function_Sample.ino:7:20: error: 'inData' was not declared in this scope
variable or field 'func' declared void

ESP-WROOM-02:
Arduino_Function_Sample.ino:2:11: error: variable or field 'func' declared void
Arduino_Function_Sample.ino:2:11: error: 'OneData' was not declared in this scope
Arduino_Function_Sample.ino:2:20: error: 'inData' was not declared in this scope
variable or field 'func' declared void

こんなエラーが出ます。

で、どちらでもエラーとして表示されていないLine 14-16のvoid funcをコメントアウトするとビルド通ります。

なんじゃそりゃあああ

■答え■

Arduino言語ではスケッチ中で関数の引数として構造体を渡すことはできない

そうです(出典:Arduino(4) ブロック崩しを作ってみる(1))。

今まで知りませんでした…。ヘッダなどで定義してC言語としてコンパイルすれば通りますが、うーん、dependencyが…。

しかし…どーしよう。上のソースは28行しかないけど、久しぶりに気合入れてコーディングしちゃったです。300行ぐらい…構造体渡し使いまくりで…。void *で渡してキャストすればいいけど、事故の元だしなぁ…。でもglobalでベターっと書くよりマシかなぁ…。

どーしましょw

スケッチではstructのtypedefを関数の引数として構造体に渡すことができない

仕様だそうです。上記の定義を以下のように書き換えるとコンパイル通ります。

struct DneData_t {
  float temperature;
  float humidity;
  float pressure;
  float airQuality;
};

void func(struct OneData_t *inData) {

}

良かった良かった。でも、書いてたコードはもうtypedef渡しではなくGlobal仕様に書き換えちゃったんですよね…まぁ動いてるからいいけど…今後は気をつけます。

今週はやることなすことうまくいかない。

ちゃんと勉強してから使えって話なんですけどねorz

2016年6月12日日曜日

100円のデジタル温度センサー+Arduino


初めてこれを見つけた時には、あんまり安いので何かの間違いかと思いました。デジタル式の温度センサーで1個100円(高精度12ビットI2C接続デジタル温度センサ STTS751)。しかも5個買えば1個80円。ってんで、5個買いました。電源3.3vですが、I2Cピンは5vにも対応しているので3.3v電源ならばArduino, mbed, ESP8266, ラズパイなど幅広く対応可能です。とりあえず温度だけ測定したいという用途に向いてます。

秋月のサイトから
基板は以前買ったSOT23オペアンプ用がまだ手元に残っているのでそれ流用します。この基板にはオペアンプのピンに合わせてパスコンのパターンもついているのですが、STTS751とは合いません。普通に「SOT23変換基板 金フラッシュ」を使う方がいいと思います。

秋月のサイトから
で、これをホットプレートでリフロー。ピン間隔狭いので横一列にペーストを塗って乗せただけです。まとめて3個、作っておきました(基板の在庫が3枚しかなかった)。



Arduinoは標準のWireライブラリだと内部でプルアップするのでプルアップ抵抗外付けは不要です。チップは3.3v電源なのですが、SDA/SCLについては5.5vまで対応可能なので、Arduinoでも問題ありません。

仕様書p27から

Arduino nanoパチで試しました。

Arduino nanoSTTS751
A46 SDA
A54 SCL
3v33 Vdd
GND2 Gnd

余談ですが…うちにはつい衝動買いしたArduino nanoパチが大量にあるのですが、Arduino nanoパチは附属のピンヘッダよりもピンソケットの方が使いやすいのではないかと思います。少なくとも複数のArudino nanoパチをお持ちの場合は、1つをピンソケット仕様にしておくと実験の時にムダにブレッドボードを使わなくていいので、お手軽です。というよりも300円のnanoパチに150円のミニブレッドボードを専有されるのはもったいない、という貧乏心なのですが。



で、テスト。手っ取り早く、「arduino stts751」でぐぐったら、コードが出てきたのでさっくり動かします。動きました。

このコードには問題がありました。修正版を後日公開します。とりあえず風呂温度センサーについては修正版を公開しました。

今回これを引っ張りだしたのは、「風呂の水温計測」(ESP-WROOM-02で温度データ収集)に使うためです。以前、ESP-WROOM-02とアナログセンサーで作ったのですが、デジタルセンサーの方が校正などの手間が省けて便利なので。

追記:組み込みました。
100円温度センサー+ESP-WROOM-02でWiFi風呂水温計

追記:ライブラリ書きました。
https://github.com/TareObjects/STTS751

追記:とんでもなくダメなバグをfixしました
グラフがところどころおかしな動きを見せるので、センサーからデータを取り出すところに問題があるのかと大騒ぎしたのですが、浮動小数を文字列に変換する関数に致命的な間違いがありました。余りにもダメなバグなので、晒しておきます。

void ftoa(float f, char *buf) {    // wrong ftoa code
  float a = int(f);
  float b = int((f - a) * 100.0000);
  sprintf(buf, "%d.%d", (int)a, (int)b);
}

以上。codeで首を吊るべきレベルだ…。さすがに自分で書いたものだとは思いたくないけど、そうだとしても気づかない時点で同罪だ…。

なお、浮動小数から文字列への変換にはdtostrfが使いやすいです。dtostrf(浮動小数,整数部最小桁数,小数部桁数,char*)で使えます。整数部最小桁数よりも小さい場合はスペースが入ります。

2016年5月27日金曜日

Arduino空気質センサー+OLED



3年ぐらい前に作ったArduinoニオイセンサーの記事が未だにアクセスが多い。ありがたいことです。

でも、あっちの記事で使っているTGS2450は、いろいろタイミング制御やら電圧制限やらが厳しくて、気楽に使えません。

ので、先日ESP-WROOM-02でも使った空気質センサーを使って、作りなおしてみました。

なお、上の写真でグラフが急上昇しているのは、地味なので消臭スプレーを噴射してみたところです。人間の感じるいい匂いと空気質が必ずしも一致しない、という図です。でも、私が「ハー」ってやると確実に上昇します。ちなみに冬の早朝、部屋の空気を入れ替えた状態が一番低い値を示していました。

■使用部品■

Arduino nano(他のArduinoや互換機でも問題ないはず), 空気質センサー, OLED 0.96インチです。なお、安いところで買うと詳しい説明書いてないのですが、ピンの配列や対応する電源電圧などが異なる場合がありますので、十分ご注意ください。

なお、配線のためにミニブレッドボードとメス-オスのジャンプワイヤを使いました。

■配線■

Arduino nano/unoAirQuality Sensor0.96インチ OLED
A0AO(Analog out)
5VVCC
GNDGNDGND
A4SDA
A5SCK(SCL)
3v3VDD


■プログラム■

ESP-WROOM-02の記事では別のライブラリを使っていますが、ここではAdafruitさんのライブラリを使ってみました。大きなフォントが今ひとつなんですが、グラフィックスの命令が豊富なのでこのあとグラフ化も簡単でした。

コードのほとんどはOLEDへの表示です。

AirQualityセンサーからの値はアナログ値なのでanalogReadで読みます。読んだ値は64桁のバッファに格納して、これを用いてグラフを描画しています。

ソフト屋としては、「単純バッファで毎回シフトw」「グラフの描画で座標を二重に計算ww」など、ちょっと恥ずかしいのですが、わかりやすさを優先しました(真顔

あと、ドットを描画する命令がわからなかったので、drawLineで同じ座標を指定してます。ドキュメント読めば書いてあると思うんだけどw


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に感謝申し上げます。ありがとうございました。