投稿

2018の投稿を表示しています

第39回「IoT GW ラズパイによる」

イメージ
IoTゲートウェイは各社の専用機もありますが、とりあえず実証実験したい時にはハードルが高いのでそんな時はRaspberry Piをお薦めします。 電源が来ていればいいですが、屋外だったり屋根裏だったりに置きたいのに電気工事士に頼むまでもないような場合は、PoE(Power over Ethernet)をお薦めします。 アーミンオンラインショップでも扱っています。

第38回「サーモパイル  原理と応用」

イメージ

第37回「測距 サンプルを動かしてみた」

イメージ

第36回「測距 測距センサーの原理と応用」

イメージ

第35回「PoE GWの電源について」

イメージ

第34回「BLE サーバとクライアント」

イメージ

第33回「トイレIoT導入のメリット」

イメージ
※トイレ向けIoTの導入サービスページはこちら

第32回「BLE 通信のトポロジー」

イメージ

第31回「BLE Bluetooth Low Energy」

イメージ

第30回「Node-REDのススメ」

イメージ

第29回「トイレIoT 人感センサーの併用」

イメージ
前回のトイレ個室の扉が②のタイプ(人が居る居ないに関わらず閉まっている)の場合、人の在室検知にドアセンサーが使えないので、人感センサーを併用することをお薦めしています。 次のトイレIoTの話題はこちら ※トイレ向けIoTの導入サービスページはこちら

第28回「トイレIoT ドアセンサーの応用」

イメージ
トイレの個室の扉には、①人が居ないと開いているタイプ、②人が居ても居なくても閉じているタイプ、がある。 上記①のタイプの扉の場合、マグネットが近いか遠いかを検知するドアセンサーを使えば、ドアが閉まっているとき人が中に居ることがわかるので、ドアセンサーを在室検知に使えることになる。 ※トイレ向けIoTの導入サービスページはこちら

第27回「「電源」の話が続きます」

イメージ
無線センサーノードの消費電力を下げるには ①無線発信頻度を下げる ②スリープ時の消費電力を下げる(特にセンサー類) が有効 次の電源の話題はこちら

第26回「「電源」の話の続き」

イメージ
仕事量の国際単位はジュール(Joule)だが普通は仕事率(W)と時間の積で表す。 例えば家庭や事務所の使用電力量はkWh(kilo watt hour)で表す。 電池はVが一定の仮定のもとでmAh(mili ampere hour)で表す。 コイン電池のCR2032を1年間一定電流放電し続けるとすれば220mAh/8760h=25uA以下でないといけない。 EnOceanのSTM431J/STM429Jに使われているソーラーセルの性能は3V 4.5uAなので更に条件が厳しい。

第25回「メインはPythonに決めた」

イメージ
当社の開発方針を決めたのでその話です。

第24回「EnOcean over MQTT」

イメージ
EnOceanのロッカースイッチ、ドアセンサーをUSB400Jで受けてMQTT brokerに送り、同じMacでMQTT brokerから受け取って表示させています。

第23回「プロトタイピングの実際 MQTT SubscriberにNode-REDを使う」

イメージ
当社はセンサーの提供業者ですが、テスト、販促のためにも、クラウド、サービス側をある程度知っておく必要があり、実用化はさておいてプロトタイピングでMQTT Subscriberを作る場合は比較的容易な言語、Node-REDが最適である、という話です。

第22回「IoT実用化の壁 電源」

イメージ
複数のセンサーとゲートウェイ、という構成の場合、前者は電池かエナジーハーベスト、後者はAC電源、が一般的です。 個人住宅だと10年程度はメンテナンスしたくないですが、商業施設、事業所なら年1回設備の棚卸をするはずなのでついでにメンテナンスするのはそれほど無理でもないだろうというような話です。 次の電源の話題はこちら

第21回「I2CからMQTTまで」

イメージ
今回は、I2C I/Fを持つRTCを、MbedでUSBのテキストストリームに変換後、Mac/Pythonで外部MQTTサービスに繋いで見ます。

第20回「外部MQTT Brokerにアクセス」

イメージ
IoTゲートウェイから外部MQTTに接続する前段階として、MacからPythonを使って外部MQTTサービスに接続して見たところをお見せしています。

第19回「I2C制御(4) ターミナルからアクセスできた」

イメージ
実際にPCのターミナルからI2Cを制御しているところをお見せしています。

第18回「I2C制御(3) text stream化」

イメージ
なぜUSBポートにI2Cプロトコルを載せた方がいいのか、について説明しています。 ・ハードウェア依存を避ける(機種が変わると使えなくなる、ということを避けたい) ・過度な隠蔽を避ける(I2Cセンサーはデータシート上で使い方をタイミングチャートで説明しているが、過度な抽象化をしていると対応が分からなくなるため)

第17回「I2C制御(2) I2C over USB」

イメージ
I2Cをメインボードのソフトウェアで制御したい場合、I2CプロトコルをUSBインタフェースに載せる案を解説しています。USBポートから制御できると、Windows/Mac/Raspberry Piで同じように扱えるからです。

第16回「I2C制御(1) プロトコル」

イメージ
I2Cインタフェースの詳細について説明しました。

第15回「I2CからMQTT」

イメージ
前回説明したように、IoTシステムを組む場合の仕事は大きく2つに分かれる。 1つは、I2C etc.からゲートウェイを介してMQTTまで。 もう1つは、MQTTを受け取るクラウド、そして端末まで。 前者を組むには、言語として"C"と"Python3"くらいが扱えれば、センサー素子をMQTTプロトコルに載せるところまでできると思います。

第14回「通信プロトコル(3) MQTT」

イメージ
MQTT Publisher, Broker, Subscriberの関係について。 IoTシステムはMQTTプロトコルを使うことを前提にすると仕事は2つに分かれる。 1つはセンサー情報をPublishするまで。 そしてもう一つはBrokerとSubsciber側。 前者が当社のようなセンサー装置の提供側、後者が各クラウドベンダー側、ということになる。

第13回「通信プロトコル(2) TCP/IP」

イメージ
TCP/IPプロトコル階層 アプリケーション層:HTTP, SMTP, FTP, MQTT etc. トランスポート層:TCP, UDP インターネット層:IP ネットワークインタフェース層:Ethernet, 公衆網, LPWA

第12回「通信プロトコルOSI参照モデル」

イメージ
OSI参照モデル アプリケーション層:メール、web、等々。 プレゼンテーション層:情報の形式、フォーマット セッション層:通信の開始から終わりまでの流れ、手順 トランスポート層:信頼性を上げる層 ネットワーク層:論理アドレスを指定して装置を超えて通信できるようにする データリンク層:ここから上が論理層。8bit, parity, stop, bard rate等々。 物理層:コネクタ、電気仕様等。

第11回「IoTでできること」

イメージ
IoTシステムの出口 ・通知する:メール、LINE、Twitter… ・(蓄積後)表示する:Web画面、専用アプリ、サイネージ ・アクションを起こす:照明、アナウンス、モータ?

第10回「プログラミング言語について」

イメージ
1970-1980年代 アセンブラ、FORTRAN, COBOL, BASIC, C, Pascal, LISP, Algol, Ada 2018.11現在の人気Top10 Java, C, C++, Python, Visual Basic.NET, C#, PHP, JavaScript, SQL, アセンブリ 今後30-40年、今一回書いたコードが生き残ることはないだろう、ということを前提に、今使いやすいものを使っていればいいと思われる。 とは言っても、私からの提案としては、組込系のC/C++、WebアプリのJavaScript、glue言語としてPython/Node-REDあたりを使いこなせれば、IoT業界で当面幅の広い仕事がこなせるものと思われる。

第9回「コントローラボードを使いこなす(2)」

イメージ
一個のセンサーから直接インターネットに出ていく構成は、検出する情報一個のイベントが非常に重大でそういう構成をとってもペイする、採算が合うような用途で使われます。 一方、複数の多くのセンサーを一個のゲートウェイでまとめてインターネットに出ていく構成は、センサーから上がってくる小さな情報を長期間、もしくは大量にまとめることで情報の重要度が上がるような応用に使われます。

第8回「コントローラボードを使いこなす(1)」

イメージ
Arduinoについて説明をします。 Arduinoを拡張するには以下の方法があります。 ①センサー素子などをブレッドボードに載せてジャンパワイヤーでつなぐ ②Groveコネクタが出ているセンサー等はそのコネクタがついているArduino互換機を使う ③シールド基板を使う(センサーもインターネット接続もあり)

第7回「コントローラボードのいろいろ」の要約

イメージ
従来ソフトウェアツールは高額で購入する必要があったが昨今無償なのが一般的になってきた。それらボードで代表的なのが以下の3種類。 Arduino Mbed 以上がシングルタスクでリアルタイム性に優れアナログ値も入力できる。 Raspberry Pi…Linux OSが走る。

第6回「長距離無線について」

イメージ
有線:光ケーブル。新規は少ない 無線:公衆網…3G, 4G(LTE)    新通信業者…Sig-fox, LoRaWAN    自前のアンテナ…同上

第5回「近距離無線のいろいろ」の要約

イメージ
近距離無線のメリット ・設置が容易で電線が剥き出しにならないので見栄えが良い デメリット ・期待したほど飛ばない、不安定 周波数が高いと情報を多く送れる反面、直進性が高くなる 2.4GHz帯:Wi-Fi(5GHz帯へ), BLE  920MHz帯:Z-Wave, EnOcean, Wi-SUN等

第4回「センサーからインターネット」の要約

イメージ
センサーからインターネットに出るまでのインタフェースの整理 ①センサー素子と制御回路間 アナログからディジタルへ I2C, SPI, UART, etc. ②制御回路とゲートウェイ間 有線LAN 無線:Wi-Fi, BLE, Zigbee, Z-Wave, EnOcean ③ゲートウェイとインターネット間 公衆網:光ケーブル、3G, 4G, LTE LPWA:Sigfox, LoRaWAN

第3回「センサーの用途と分類」の要約

イメージ
(1) センサーが内蔵されている機器 スマホ ・マイク、カメラ、タッチパネル、指紋センサー ・温湿度、気圧、照度、ジャイロ、加速度の各センサー その他多くのセンサーを内蔵している機器類 空調機器 調理機器 自動車 (2) センサーを使う目的、用途 観測対象の物理量をセンサーで電気信号に変える。得られた電気信号(場合によっては複数)を加工して(人がこれから何をしようとしているか等の)複雑・高度な情報を得る。 (3) センサーで得られる情報の分類 視覚:可視光、赤外線、紫外線。これをまとめた画像 聴覚:音声、振動 触覚:速度、加速度、質量 味覚:液体成分、流量 嗅覚:気体成分 (4) センサーを使えるようにするための機器構成 インタフェース①:センサー素子と制御回路(これらをまとめてセンサー機器) インタフェース②:制御回路とゲートウェイ

第2回「情報通信の進化の歴史」の要約

イメージ
1.送れる情報量が拡大した 2.家庭から個人へ、固定からモバイルへ、の動きがあった 3.蓄積伝送ができるようになった 4.情報通信網に人以外のモノが参加するようになった

「IoT実用化講座」主に応用を話題にしている回

28 トイレIoT ドアセンサーの応用 29 トイレIoT 人感センサーの併用 33 トイレIoT導入のメリット

「IoT実用化講座」主にハードウェアを話題にしている回

7 コントローラボードのいろいろ Arduino, Mbed, Raspberry Pi 8 コントローラボードを使いこなす(1) 9 コントローラボードを使いこなす(2) 39 IoT GW ラズパイによる

「IoT実用化講座」の中で無線を話題にしている回

5 近距離無線のいろいろ Z-Wave, EnOcean, Wi-SUN, etc. 6 長距離無線について 3G, 4G(LTE), Sig-fox, LoRaWAN 24 EnOcean over MQTT 31 BLE Bluetooth Low Energy 32 BLE 通信のトポロジー 34 BLE サーバとクライアント

YouTubeチャンネル「IoT実用化講座」をまとめます

YouTubeチャンネル「IoT実用化講座」の動画が増えてきてジャンルがあちこち飛んでいるのでここらで整理しておこうと思います。今回は順番に並べました。 (タイトルはサムネイルによる) 2018.12.28現在 IoT実用化講座1 IoT実用化講座 開講 2 情報通信の進化の歴史 (以下、繁雑になるので数字だけにします) 3 センサーの用途と分類 4 センサーからインターネット 5 近距離無線のいろいろ Z-Wave, EnOcean, Wi-SUN, etc. 6 長距離無線について 3G, 4G(LTE), Sig-fox, LoRaWAN 7 コントローラボードのいろいろ Arduino, Mbed, Raspberry Pi 8 コントローラボードを使いこなす(1) 9 コントローラボードを使いこなす(2) 10 プログラミング言語について 11 IoTでできること 12 通信プロトコルOSI参照モデル 13 通信プロトコル(2) TCP/IP 14 通信プロトコル(3) MQTT 15 I2CからMQTT 16 I2C制御(1) プロトコル 17 I2C制御(2) I2C over USB 18 I2C制御(3) text stream化 19 I2C制御(4) ターミナルからアクセスできた 20 外部MQTT Brokerにアクセス 21 I2CからMQTTまで 22 IoT実用化の壁 電源 23 プロトタイピングの実際 MQTT SubscriberにNode-REDを使う 24 EnOcean over MQTT 25 メインはPythonに決めた 26 「電源」の話の続き 27 「電源」の話が続きます 28 トイレIoT ドアセンサーの応用 29 トイレIoT 人感センサーの併用 30 Node-REDのススメ 31 BLE Bluetooth Low Energy 32 BLE 通信のトポロジー 33 トイレIoT導入のメリット 34 BLE サーバとクライアント 35 PoE GWの電源について 36 測距 測距センサーの原理と応用 37 測距 サンプルを動かしてみた 38 サーモパイル  原理と応用 39 IoT GW ラズパイによる

IoT gatewayをどう構築するか

イメージ
IoT gatewayをどう構築するかについてYouTubeにアップしました。

Raspberry Pi起動時にNode-REDを自動で開始する

以下、 Running on Raspberry Pi という記事によります。 === Pi起動時にNode-REDを自動で開始するには次のコマンドを使用できます。 sudo systemctl enable nodered.service

RN4871-I/RM130を入手しました

イメージ
早速火を入れました。 リセット後$$$を叩くとCMD>になるのでVを入れるとバージョンが出ます。 無事revision1.30であることが確認できました。

MacにMQTT Broker/Publisher/Subscriberをインストールする

mosquittoコマンドのインストール・使い方 すごくいい記事なんですが、最後の最後、画竜点睛を欠くので訂正しておきます。 mosquitto_sub -t "topic/path" mosquitto_pub -t "topic/test" -m "Hello2" --> /testではなくて/pathにします。 ここまで

pythonからOpenCV経由でキャプチャしてみる

pythonからOpenCV経由でキャプチャしてみる リンク先の下の方です。 $ sudo apt-get install python-opencv $ python Python 2.7.9 (default, Sep 17 2016, 20:26:04) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import cv2 >>> c = cv2.VideoCapture(0) >>> r, img = c.read() >>> cv2.imwrite('capture.jpg', img) True >>> 出てきたcapture.jpgを確認してみてください。

ラズパイにUSBカメラをつなぐ

guvcviewと言うソフトを使ってみました。 $ sudo apt-get install guvcview でインストール $ guvcview & で起動すると画面が現れます。次にどう使うべきかを考えます。

ラズパイをリモート制御する

ディスプレイやキーボード・マウスを外してラズパイを実運用し始めると、いざ設定を変更しようとした時またそれらをつなぐわけには行かなくなってきます。そこでリモート制御したくなるわけで、やり方を備忘録として残しておきます。 Raspberry PiをWindowsPCから操作する方法 【CUI・GUI】 CUIの場合、"ssh pi@192.168.X.XXX"等でリモート接続します。 GUIでMac側は"Microsoft Remote Desktop"と言うソフトを使いました。 現在のバージョンはVersion 10.2.4 (1434) 詳しくは以下を参照 Raspbian リモートデスクトップで外部から接続(mac)

PoEのススメ

本家のサイトでPoEのススメ を書いてみました。 PoE対応のゲートウェイでトイレIoTを実証実験してみませんか。 IoTトイレPoCキット2++(ドア開閉センサー(電池バックアップ有の2個)とPoE版ゲートウェイのセット)※PoC=Proof of Concept(概念実証、実証実験) ==== Raspberry Pi 3 model B+専用のPoE HAT単体でも発売開始しました。 Raspberry Pi PoE HAT - オフィシャルボード for Pi 3B+

サーモパイル センサーを動かしてみました

詳しくは IoT実用化講座 をご覧ください。

測距センサーを動かしてみた

YouTubeのチャンネル をご覧ください。

距離センサー(測距センサー)について

YouTubeのIoT実用化講座36 の内容を要約しました。 距離を測る意味 ①実際にセンサーと対象の距離を知る:例として河川の増水を知る ②人が居る居ない、人が近づいた遠ざかった、物が動いた等を知る 測距の原理 ①超音波やレーザの反射してくる時間から換算する ②三角測量による(赤外線LEDとPSDセンサーの組み合わせ) センサーを選択するには ①対象物の性質(固体か液体か等)や表面の状態(反射するか否か) ②反射を阻害する外乱のあるなし(自然光が入り込む、他の音波等) を事前に調査しておく必要がある。センサー自体はそれほど高価なものでもないので一通り実証実験してみることをお勧めしたい。

EnOceanのトイレセンサーをLINE Botで確認する

アイエンターという会社の方の記事です。 「EnOceanのトイレセンサーをLINE Botで確認する」

「IoTの台風の目!?EnOceanについて本気出して語ってみた」

NTTコミュニケーションズの方の記事です。 IoTの台風の目!?EnOceanについて本気出して語ってみた

ラズパイでBLEを使えるようにする

raspberry piのbluetoothを使えるようにする

ラズパイのNode-REDをupdateする

ラズパイに最初からインストールされているNode-REDでは「パレットの管理」と言うメニューが出てこないのでNode-REDをアップデートしました。 ここを参照 リブートしたら「パレットの管理」が出てきました。 ここまで

オリジナル(自分専用)のUUIDを得る

BLEでオリジナルのサービスやキャラクたりスティックを追加したい場合、UUIDが必要になります。こう言う場合、あれこれ悩むより ここで生成する と良いです。 以上

I2C対応のRN4020資料まとめ

RN4020 Data sheet(I2Cのピンが書かれている。ただしSDAとSCLが実際には逆らしいので要注意) Firmware 1.20 Release note(I2Cコマンドが書かれている) RN4020でI2Cを制御をした人のブログはこちら 最新のYouTubeチャンネルはこちら

BLE(RN4020)をMacで受信する

BLEの評価に着手しています。 >IoT実用化講座 手元にRN4020があったのでこれをアドバタイズさせてMacのアプリLightBlueで受信してみます。 LightBlueが立ち上がった状態でRN4020をアドバタイズさせてもconnectできず、RN4020をコマンド"A"でアドバタイズさせてからLightBlueを立ち上げるとPeripheralsに名前が出てきました。 これをクリックするとServices, Characteristics, Detailsが表示され、connectできました。Subcribe/Unsubscribe/Readも動いているようです。 以上、備忘録でした。

Pythonで行きます

YouTubeの方でアナウンスしましたが、 当社のメイン言語はPython で行きます。 最後まで悩んだのがJavaScriptを主力にしなくていいか、という点です。「主力」とは、習熟するために時間を割く、ソフトを書き溜める=資産を築くことになる、と言う意味です。 最後に出した結論の根拠は ・IoTシステムには今後、機械学習への対応が必要だと想像されるが、Pythonの方に分がありそうだ ・見栄えをリッチにするにはJavaScriptの方が良さそうだが、これは当社が追求すべきジャンルではなさそうだ。必要な時にやれば良いこと。今はセンサーと密なアルゴリズム開発に徹すべきと判断した と言う理由によります。 ここまで

EnOcean over MQTTの裏側

イメージ
シリアルノードの設定 MQTT publisherノードの設定(サーバ、ポートとトピックを入力する) 上記サーバ名を入力した右端の鉛筆ボタンを押して出てくるウィンドウの「接続」タブにサーバとポートを入力する 同じく「セキュリティ」タブにユーザ名とパスワードを入力する 更新ボタンを押し、デプロイボタンを押してノード下に「接続済」が表示されればOK

EnOcean over MQTT

イメージ
以下の構成で動作を確認しました。 EnOceanロッカースイッチ、ドアセンサー -> USB400J -> Mac/Node-RED(screen shotのUSB400Jで始まりMQTT nodeで終わる部分。表示はtopic=enoceanとなっている) -> CloudMQTT -> Mac/Node-RED(screen shotのMQTT node(表示はtopic=enocean)で始まりdebug node(表示はmsg.payloadになっている)で終わる部分。screen shotの右のpaneにmqttで受信した結果が表示されている)

MQTTは秩序破壊のきっかけになる

今まで技術に特化した記事を書いてきましたが、今回はビジネスについて少しだけ話をしておきます。 今やHTTP(S)の全盛の時代と言っていいと思います。HTTP(S)の覇者は、GAFA+Mだと思いますが、MQTTが急激にシェアを伸ばしてきており、GAFA+Mと言えども安閑とはしていられないと思います。 https://japan.zdnet.com/article/35124196/ 大胆に言えば、 「HTTP(S)は人対人の通信で利用してきたプロトコル」 なのに対して 「MQTTはIoTが利用するプロトコル」 だからです。 「MQTTを制する者がIoT時代を制する」 と言っても過言では無いのでは無いでしょうか。 というわけで当社はMQTTに全力を注ぐことを宣言します。 今回は以上です。

I2CからMQTTまで

イメージ
今まで紆余曲折ありましたが、ようやくI2CからMQTTまでのパスが通りました。 RTCから「秒」を1秒毎に読んでMQTT brokerに送る動きをYouTubeに紹介しています。

動作確認(2'')

イメージ
同じく書き込み動作も再確認しました。

動作確認(1'')

イメージ
I2C-COMのrevisionを3->3.1にした(戻り値を全て2桁の16進数にした)ので再度動作を確認しました。

I2C-COM Ver3.1

binary1バイトを16進で表現する際に、00~FFとASCIIコードで2文字要することを明記した。

有線による通信距離(メモ)

USB (1) 規格上の上限は5m (2) USB延長ケーブルが市販されている  これを使えば20m I2C (1) I2Cは元来基板上でいくつものデバイスを芋づる式にぶら下げて使うもので、長さに特に規定があるわけではない(数m延ばせる可能性はあるがirregularな使い方) (2) 1対1でいいなら延長ケーブルが市販されている  これを使うと数十mいけるらしい Ethernet 規格がたくさんあるのでこちらを参照。 100m程度から数10km程度まで幅があり長距離には向いているが、tranceiverやケーブルの価格を考えると多くのセンサーをこれで1対1で繋いでいくのは現実的ではない。 ※センサーを部屋のあちこちに複数個置くようなケースだと有線はあまり現実的とは思えない。2個以上使うのが見えているなら無線化を指向するべきだろう。

Macから外部サーバのMQTTブローカに接続する(2)

イメージ
前回はNode-REDを使ってCloudMQTTに繋ぎました。 今回はPython3を使って繋いでみました。 オリジナルはここです 。 #                   Nov/27/2018 # # ------------------------------------------------------------------ import  sys from time import sleep import paho.mqtt.client as mqtt # ------------------------------------------------------------------ sys.stderr.write("*** 開始 ***\n") host = 'Server name' port = xxxxx topic = 'topic_1' client = mqtt.Client(protocol=mqtt.MQTTv311) client.username_pw_set('User', 'Password') client.connect(host, port=port, keepalive=60) client.publish(topic, 'Good Afternoon!!') sleep(0.5) client.publish(topic, 'こんにちは') client.disconnect() sys.stderr.write("*** 終了 ***\n") # ------------------------------------------------------------------ ※ host = 'Server name' port = xxxxx client.username_pw_set('User', 'Password') は適宜変更を要します。 以上を実行させると こんな感じに出力されます。 以上

Gravityシリーズ

DFRobot社のGravityシリーズ というのがあるようです。センサー素子が載る子基板のコネクタはPH2.0-4pのようです。 Gravity 4Pin IIC/I2C/UART Sensor Cable (10pcs)の仕様は、 "One side is PH2.0-4p connector and the other side is XH2.54 DuPont port. " だそうで、PH2.0-4pは2.0mm pitch、XH2.54は2.54mm pitchです。 PH2.0-4pはGroveとピン配列も違いますね。 各社統一の気配は全く感じられません。

IoT実用化講座更新しました

イメージ
IoT実用化講座10はこちら

Node-REDでセンサーデータを可視化する

非常によく書かれている記事があるのでここを参考にします。 Node-REDにダッシュボードを追加してセンサーデータを可視化する ここまで

Macから外部サーバのMQTTブローカに接続する

イメージ
MQTT brokerを立てるより外部サービスを使うのが圧倒的に簡単です。ここではCloudMQTTを使いました。 Node-REDをMac上で動かしてMQTT publisherとし、CloudMQTTをbrokerにして、CloudMQTT上でmessageが届くことを確認します。 今日はここまで

今考えていること・・・

前回まででI2Cセンサー出力がUSBポートを経由してPC/Mac/RasPiへ、と言う経路は確立できました。では次はどうするか。 「PC/Mac/RasPiから外部サイトのサービスにどう接続すべきか」だと思います。 ここの間のプロトコルはHTTP(S)かMQTTの二者択一でしょう。更に言うならIoTのジャンルではMQTT一択だと思います。 MQTTに載せるデータ・フォーマットまで標準化したいところですが、話が大きすぎて独りよがりは通用しませんので、当面は「MQTTプロトコルをどう実装するか、テストするか」と言う話に絞りたいと思っています。 ここまで

動作確認(2')見直しました(古くなりましたが記録として残します)

イメージ

動作確認(1') 見直しました(古くなりましたが記録として残します)

イメージ
「動作確認(1)」からの変更です。Wコマンドの返り値を表示するようにしました。これでWコマンドによるエラーが検出できるようになります。

YouTubeチャンネル開設しました

イメージ
チャンネルはこちらです。

PythonからmacのUSBポート入出力

イメージ
PythonからMbed経由でI2Cセンサーにアクセスするための事前準備です。 macにUSB接続した外部ボード(ここではArduino互換機)に、Pythonから入力した文字をそのままecho backさせました。まずはArduinoのスケッチ。 === void setup() {   Serial.begin( 9600 ); } void loop() {   if( Serial.available() ){     char c = Serial.read();     Serial.print( c );   } } === 次にmacで動かすPython === import serial ser = serial.Serial('/dev/tty.usbserial***',9600,timeout=None) while True:     ch1 = input()     ser.write(bytes(ch1, 'UTF-8'))     ch2 = ser.read()     print(ch2) === 結果はこんな感じです。 0を入力したらb'0'が出力され、1を入力したらb'1'が、、、の連続です。 ※ボードを変えると"tty.usbserial***"の部分が変わるので注意が必要です。('18.11.19記す) === ここまで

pySerialのインストール

イメージ
Pythonからシリアルポートアクセスするためには、 pySerialというパッケージをインストール します。 $pip3 install pyserial Successfully installed pyserial-3.4 (バージョンは'18/11/12当時) が出ればOKです。 いきなりI2C-COMの基板を繋ぐ前に、PythonからUSBポートに入出力できるか、確認します。 まずUSBポートから"Hello"を連続入力してPythonの画面に出るか? macのUSBポートにテキストを連続に流し込むArduinoのスケッチ(Mbedにまだ慣れてない) === char ch1 = 0; void setup() { Serial.begin(9600); } void loop() {     Serial.println("Hello");     delay(1000); } === mac側で受けるPythonは === import serial ser = serial.Serial('/dev/tty.usbserial-***',9600,timeout=None) while True:     ch1 = ser.read()     print(ch1) === 結果は となりました。時間になったのでPython -> USBは明日にします。 ここまで

macにPython3をインストールする

I2Cを手入力と目視で制御できるようになったので、次はいよいよプログラムからI2Cを制御できるようにします。まずプログラミング言語を決めないといけないのですが、ここではPythonを選びました。なぜPythonなのか? これから多種多様なI2Cセンサーの動作を記述してどんどん資産が増えていきますから、今後廃れそうな言語は避けたいところです。これから末長く生き延びるだろうことを現時点で予測するのはどんな技術でも難しいことですが、①書店で書籍を多く見かける、②ざっと見たところ言語仕様が初心者でも取っつき易そう(新しく覚えることが比較的少なそうだしデバッグも容易に思えた)、③RasPiのPiはPythonのPiらしい(RasPiを立ち上げた人が意識していたことは間違いない)、等々の理由により選びました。因みにNode-REDにもwebにも使えるJavaScriptが次点でした。 さて、macOSには最初からPython2がインストールされているのですが、ここではPython3を新たにインストールします。これから新しくプログラムを書こうという人が進歩が止まった言語に執着する理由はありませんから。 Pythonのインストーラーはここ にあります。2018.11.12現在macOS用のverionは3.7.1でした。インストールが終わったらターミナルから$python3 -Vでバージョンをチェックします。 次に 使いやすいMicrosoftのテキストエディタをインストール します。Visual Studio Codeの中でPython用のプラグインもインストールしておきます。 ここまで

動作確認(2)(古くなりましたが記録として残します)

イメージ
内容を更新しました。 最新はこちら。 === 動作確認(1)で確認したのはレジスタリード動作なので、ライト動作も確認しておきます。 (レジスタリード動作の中でもデバイスにはレジスタアドレスを書き込んでいますがdata sheetに記載のあるプロトコルを確認する意味があります) レジスタ03hはRAM_byteで、汎用に読み書きできるようなので、ここに適当なパターン、ここでは5ahとa5hを書いて読み出してみます。 今回は1行1行説明しませんが、"5a"を書いた後、"5a"が読めて、"a5"を書いた後は"a5"が読めていることが確認できました。 ここまで

動作確認(1)(古くなりましたが記録として残します)

イメージ
内容を更新しました。 最新はこちら 。 === 最初の動作確認として、RTCからreadしました。 レジスタ00h~0Ahまで11バイトを連続で読み出しています。 最初なので1行毎に説明をしますと s <-- start wa2 <-- write a2h(7bitアドレス51hを左1bitシフトしたもの) w00 <-- write 00h(レジスタアドレス0h) p <-- stop(このデバイスはrepeated startではなく一旦stopを出す必要がある) s <-- start wa3 <-- write a3h(7bitアドレス51hを左1bitシフトして右端に1bit=read指定) rk <-- read ack(レジスタアドレス0hを読む) 0 <-- レジスタアドレス0hの返り値が0h rk <-- read ack(レジスタアドレスがauto incrementされているので1hを読む) 0 <-- 同じく1hの返り値が0h rk 0 <-- 2h rk 34 <-- 3h rk 9 <-- 4h(これは「秒」を表す) rk 50 <-- 5h(「分」) rk 19 <-- 6h(「時」) rk 28 <-- 7h(「日」) rk 5 <-- 8h(「曜日」) rk 1 <-- 9h(「月」) rn <-- 最後なのでread nack 0 <-- Ah(「年」) p <-- stop ここまで

I2C-COM仕様 第3.1版 (保存版)

コントローラにMbedを使うことにした結果、I2C-COMを===以下に示すように簡素化することにしました。今一度、I2C-COMの意義をここで再確認しておくと 「I2Cプロトコルをtext streamにする」 です。 === I2C-COM仕様 第3.1版 updated 2018.11.30 数値を16進で表現する際、1バイト当たり2文字要することを明記した。 S: start(); P: stop(); Wxx: xx=00~FFで書き込むバイトを表す。返り値はACK=01 or NACK=00 <-- updated Ry: y=K or Nで、K=ACK, N=NACKを表す。返り値は読んだバイトで00~FF ※Wでslave addressを送る際、7bit addressを1bit左シフトして、write mode=0, read mode=1を加える必要があります。 ※いずれも大文字小文字とも有効。 ※S,P,W,R,K,N,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F以外は区切り記号。区切り記号のとき実行する。いずれ連続リード・ライトを追加する可能性がある。 ※1バイトのbinaryをreadableにするためには00~FFの2文字を使う。text stream上では2文字、つまり2バイトに倍増すると言うことである。<-- updated === ここまで

Mbedで使う関数(保存版)

I2C name(sda, scl);//初期化 name.frequency(hz); name.start(); name.stop(); int=name.read(bool);//int:受信バイト、bool:false=nack, true=ack(正しいことを実機で確認した) bool=name.write(int);//bool:false=nack, true=ack、int:送信バイト(実機で確認したところ、ack=true=1であった) === 以上だけを使う予定です。後日、スピードが問題になったら連続read/writeを使う可能性はあります。

RTCチップのPCF85063TPにハマる(備忘録)

ここではI2Cファームウェア開発のreferenceとして RTC を使っているのですが、中のPCF85063TPにちょっとクセがあってハマったので備忘録として残しておきます。 === ReferenceとしているI2Cマスターのライブラリは ここ です。ここでのI2C-COMの開発では、ここに記述のあるstart, stop, read, write、の基本関数だけで記述したいわけですが、 PCF85063TP data sheet のP.26によると、register address setのトランザクションと、後に続くreadトランザクションの間はstopを要します。通常はrepeated startでいいはずなのですが、なぜかstop -> start、になっていました。 これに気づくまで小一時間無駄にしてしまいました。 === ここまで

I2CをUSBに変換する意義

ここでは、I2CセンサーをUSBポートからアクセスできるようにするべく開発を進めているわけですが、開発に手こずっているうちに目指している方向を見失うことがないように、この開発の意義をここに書き留めておきます。 === 1. 目的とする開発成果物のイメージ I2C I/Fのセンサーを、USB経由で可制御・可観測にする(制御可能でかつ情報を受け取れる) 2. 開発の狙い、目的 ・各種センサーのI/FをWindows PC/Mac/マイコンボード(ex. Raspberry Pi)で共通にすることによって、開発成果物(具体的には制御・可視化用のソフト)を相互に移植しやすくする。例えばMacで開発したものをRaspberry Piに持って行くなどが簡単にできるようにする。 ・例えばRaspberry Pi基板にはGPIO等が使える拡張コネクタがあるが使えるケースが限定されている(ケースに穴が開いておらず、また拡張用基板の固定にも困る)。片やUSBポートはどんなケースでも使えるようになっており、センサーを取り付けるにはUSBポートの方がスマートと言える。 ※ここでI2Cの重要な特徴を挙げておきたい。それは転送周波数をゼロつまりプロトコルの途中どこでも止めることができる、いつまでも待たせておくことができる、ことである。この性質により、I2Cを使ったセンサーを遠隔から手入力で操作し表示するのにタイムアウトを気にする必要がない。手入力でデバッグすることができるということでもある。 === ここまで

I2Cが開通した

イメージ
前回まででMbed --> Macが開通したので、次の課題はI2C --> Mbedを開通させることです。 === ゴール:I2CデバイスをアクセスしてMacに表示させる 機材: リアルタイムクロック(RTC) ツール:前回と同じ(Mbed Compiler、CoolTermMac) ソースは以下 === #include "mbed.h" #include "USBSerial.h" USBSerial   usb(0x1f00, 0x2012, 0x0001, false); I2C i2c(p26, p25);        // sda, scl const int addr8bit = 0x51 << 1; // 8bit I2C address int main(void) {     char regaddr[1];     char readdata[11]; // room for length and 7 databytes     while(1) {         regaddr[0] = 0x00;         i2c.write(addr8bit, regaddr, 1, true);  // select the register, no I2C Stop         i2c.read(addr8bit, readdata, 11);        // read 11 bytes // print the data to the screen         usb.printf("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n",             regaddr[0] , readdata[1], readdata[2], readdata[3],             readdata[4], readdata[5], readdata[6], readdata[7],             readdata[8], readdata[9], readdata[10] );         wait(

Mbedで最初に試すべきこと(備忘録)

イメージ
今調べたら4年以上前にmbed(当時は全部小文字)で製品開発していたことがあったのですが、開発環境(自分もWinからMacにしてた)も石(半導体チップのこと)もだいぶ様変わりしていたので戸惑いました。私を含めて新しいハードを使い始めるときは立ち上げの初っ端でつまづく人が多いと思うので、ここに備忘録として残しておきます。 === 最初のゴールは「Macの画面に、Mbed基板のシリアル出力を出すこと」 ・使った機材: LPC11U35マイコンボード 、micro-USBケーブル、Mac ・使ったツール: Mbed Compiler 、 CoolTermMac 手順の要点、つまづいた点など (1) LPC11U35マイコンボードの初期テストをする。SW1とSW2を同時に押しながらUSBケーブルを接続し、SW2から手を離すと"CRP DISABLD"という名前のディスクがデスクトップに現れる。これを開くと中に"firmware.bin"というファイルがあるので削除する(上書きはできない)。説明書にあるテストプログラム"firmware.bin"をダウンロードしてきて書き込む際、ドラグ&ドロップでは上手くいかず、 $ cp firmware.bin /Volumes/CRP\ DISABLD で書き込む。その後SW2を押すと基板にリセットがかかってLEDが点滅すれば正常に動いている。 (2) Mbedコンパイラに登録する(自分は4年以上前に登録が済んでいた)。 (3) テストしたソースは ここにあるものを使った #include "mbed.h" #include "USBSerial.h" Serial      uart(P0_19, P0_18); USBSerial   usb(0x1f00, 0x2012, 0x0001, false); int main(void) {     while(1) {         uart.printf("I am a UART serial port\r\n");         usb.printf("I am a USB se

Mbedの学習を再開した

最近、mbed --> Mbedに変わったそうです。 それはさておき、昨日からMbedの学習を再開しました。まず手始めに LPC11U35 QuickStart Board互換ボード の動作テストをしました。 すぐ動くだろうと思っていたのに説明書通りLEDが点滅しない。ネットでいろいろ調べた挙げ句、Macでfirmware.binを書き込む際にはドラッグ&ドロップではだめで、 $ cp firmware.bin /Volumes/CRP\ DISABLD などとしなければ行けないようです。上記でようやくLEDが点滅し始めました。 ("\"はoption+"¥"で入力する) ここまで

先人がいました

世間には同じようなことを考える人はいらっしゃるようで、先行されている方のサイトにリンクを張っておきます。コマンド体系を見ていただければ分かる通り、当社は真似してませんので念のため。 「LPC810を使ったUART-I2Cブリッジの改良版が出来ました」 ※「リンク張りは禁止」とあったのでリンクを削除しました。ググって見てください。 当社のI2C-COMは、手入力することも可能ですが、最終的にはUnixのスクリプトやプログラム言語から掃き出したコードをinterpretするような使い方を視野に入れています。可読性は落ちますがI2Cプロトコルを理解している人には1対1に対応していて分かりやすいことが第一の目的、と言うところが違いでしょうか。 早く実装して動くところをお見せしないといけないと思っています。

Arduinoからmbedに方針変更!!

昨日秋葉原をぶらついていて、次のような連想が働きました。 === (1) 8pin のARM系CPU、LPC810の書籍が目に止まる。今LPC810って手に入るんだろうか?今後I2Cセンサーと一緒に組み込むことを想定すると、I2Cが使える小さくて安いマイコンが気になっていたから。 〜昼を食べながらネット検索 (2) LPC810は見当たらないがLPC812というのはある。これはどうやって開発するんだろうか?mbedで開発できるのか?mbedでI2Cはどうコーディングするんだろうか? 〜更にネット検索 (3) mbedだとI2C周りの記述はスッキリしそうだ。そう言えばLPCはNXPが開発しているがI2Cは旧フィリップス現NXPが管理してるんだった! 〜更に更にネット検索 (4) mbedの開発ボードが¥1000以下で売られていることを発見。ショップに行って即購入。 === と言うわけで、I2C周りの開発はmbedでトライしてみることにしました。さすがmbedはNXPが推進しているだけのことはあって、I2Cの記述方法に目が行き届いています。Arduinoの言語仕様は回路に思い入れが少ない人が設計した気がして仕方がない。(I2Cの動きを過度に隠蔽していてI2Cの動きを見えなくしてしまっている) ここまで

I2C slave simulatorを作る(3)〜便利な関数を定義する(内容が古くなりましたが記録として残します)

「I2C slave simulatorを作る(2)〜メインloopを作る」のtransaction記述の中で使う順番に、あると便利な関数を列挙しておきます。 === (1) startを待つとき使うもの byte read_scl(); void wait_sda_fall(); (2) byte readするとき使うもの byte read_sda();//SCL=riseを待ってSDAを取り込む。返り値は1bit void wait_scl_rise();//read_sdaの中で使う (3) ACKを返すとき使うもの void write_sda(byte);//read_scl()でSCL=highのときSDAにデータを載せる (4) 8bit read/writeのとき使うもの(2)(3)で既出 (5) 次のサイクルを判定するとき使うもの(既出) === 以上をまとめると === void wait_scl_rise(); void wait_sda_fall(); byte read_scl(); byte read_sda(); void write_sda(byte); === ここまで

I2C slave simulatorを作る(2)〜メインloopを作る(内容が古くなりましたが記録として残します)

メインloopではtransactionの流れを記述します。ここでtransactionとは、start条件>slave addressとR/W bit送出>バイト転送>・・・>stopまたはrepeated start条件、のことを指します。 === (1) startを待つ(SCL=1のとき、SDA=fallになるのを待つ) (2) 7bit slave addressと、1bitのR/~Wを受信する。具体的にはSCL=riseでSDAを取り込む。次のバイト転送の向きを決めるためR/~W bitの状態を覚えておく。 (3) ACKを返す。具体的にはSCL=highのときSDA=0とする。 (4) Wサイクルだったら8bit受信してACKを返す。Rサイクルだったら8bit送信してACK/NACKを待つ。 (5) 次のサイクルが何かを判定する。具体的には、SCL=riseを待つ>SCL=highの間中SDAが変化しなければ1bit転送が成功したということ。次の7bitの転送は(4)に戻って続ける、SCL=highの間にSDA=riseになったらstop条件なので(1)に戻る、同じくSDA=fallになったらrepeated start条件であり(2)に戻る。 === 以降、必要な関数をいくつか定義していきます。 ここまで

I2C slave simulatorを作る(1)(内容が古くなりましたが記録として残します)

slave simulatorを作る前に、I2Cプロトコルをもう一度おさらいします。 (1) SCL=highのとき、SDA=fallを検出すると"START condition"と認識する。 (2) SCL=highのとき、SDA=riseを検出すると"STOP condition"と認識する。 (3) SCL=riseのとき、receiver側がSDAの状態を読み取る。 (4) SCL=fallのとき、transmitter側がSDAの次の状態を出し始める。 slaveがreceiverまたはtransmitterのときの動作で書き直すと receiverのとき (3') SCL=riseのとき、SDAの状態を読み取る。 (4') SCL=fallのときは何もしない。 transmitterのとき (3'') SCL=riseのときは何もしない。 (4'') SCL=fallのとき、SDAにデータを載せ始める。 ではreceiver/transmitterはいつ切り替わるのか? === ここでは説明の都合で「8bitデータをtransmitterからreceiverに送り、transmitterがACKかNACKを返すまで」を「バイト転送」と定義しておきます。 仕様では「全てのtransactionはSTARTで始まりSTOPで終わる」とありますが、transactionの中身を分解すると 「START、slave address7bit+R/W1bitのバイト転送(1)、バイト転送(2)(の連続)、STOP」 となります。バイト転送(2)の向き、つまりslaveがreceiverなのかtransmitterなのかはその前のR/W bitで決まります。 日本語で説明するとややこしいので後日ソースコードで公開することにします。 ここまで

現状の開発環境(内容が古くなりましたが記録として残します)

現状の機器構成は以下のようになっています。 Mac#1 -> Arduino+自作I2C Shield for master -> 自作I2C Shield for slave -> Mac#2 ここでは贅沢にMacを2台使いましたが、PC/MacでUSBポートが2つ使えればそれで構いません。ハードの初期テストは以下のようにやりました。 slave側のスケッチはシリアルプロッタでSCL, SDAを観測しているだけです。 const byte SCL_I = 13;//ピンの定義。SCLは入力固定。 const byte SDA_I = 12;//ピンの定義。 Arduinoの外部ShieldにMOS FETを使った回路を載せて双方向を実現している。スケッチでは入力・出力を分けて記述する。こちらは入力。 const byte SDA_O = 11;// こちらは出力。'0'だとhi-z、'1'だとlowになる。このスケッチでSDAは出力しないので'0'でhi-z、つまりSDAのレベルはmasterに依存する。 byte SCL_V = 0; byte SDA_V = 0; void setup() {   Serial.begin(9600);   pinMode(SCL_I, INPUT);   pinMode(SDA_I, INPUT);   pinMode(SDA_O, OUTPUT);   digitalWrite(SDA_O, 0);// ここではSDAをhi-zにしておく。SDA_Iのレベルはmaster側の出力に依存する。  } void loop() {   SCL_V = digitalRead(SCL_I);   SDA_V = digitalRead(SDA_I);      Serial.print(SCL_V+2);// SDAを0 or 1, SCLを2 or 3の位置に表示するため2を加えている   Serial.print(",");   Serial.print(SDA_V);   Serial.println(""); } ここまで

ArduinoでI2C信号をモニタする

イメージ
SCL, SDAをモニタするのに、専用の機材(ロジックアナライザ等)を使う、LEDを光らせる、等がありますが、ここではせっかくI2C slaveをArduinoで作っているのでArduinoの機能を使います。 従来はシリアルモニタでキャラクタコードを出力していたのですが、最近シリアルプロッタと言う便利な機能が追加されたのでこれを使いましょう。以下がサンプルコードです。 byte scl = 0; byte sda = 0; byte b = 0; void setup() {   Serial.begin(9600); } void loop() {   Serial.print(scl+2);//SCLが下なのが一般的のようなので気になる人は変えて下さい   Serial.print(",");   Serial.print(sda);   Serial.println("");      if (b == 00) { scl=0;sda=0;}   else if (b == 64){ scl=1;sda=0;}   else if (b == 128){ scl=0;sda=1;}   else if (b == 192){ scl=1;sda=1;}   b++;      } Arduino IDEのメニューのツール>シリアルプロッタを選択すると以下のような画面が現れます。 ここまで

ネットワークセンサー?

ネットワークカメラ(IPカメラとも言う)I/Fの標準規格にONVIF(Open Network Video Interface Forum)と言うのがあるようです。ネットワークカメラとその受像機、レコーダの間の規格です。 これに対して、ネットワーク対応のセンサーの標準規格を策定する団体が見当たりません。まだメーカ各社がそれぞれ独自にやっている感じです。 また、画素数が少ないなど、カメラの規格では重いと思われるセンサー類のインターフェースはどうしたらいいのか? (MQTTと言うプロトコルの存在は知っていますが、これに載るセンシング情報がどこまで標準化されているのか?当社としてはまだよく把握していない) ここら辺りに当社の存在価値、存在意義を見つけることができます。

SCCBとは 備忘録

SCCB (Serial Camera Control Bus)という、OmniVision社が作ったI2Cのサブセットのカメラ用のインターフェースがあるようです。 製品自体が少ないようで、スピードの問題もあると思うので実際使うかどうかわかりませんが、備忘録として残しておきます。

I2Cシミュレータのハードウェア構成について(内容が古くなりましたが記録として残します)

今回はI2Cシミュレータのハードウェアの話です。 Windows/Mac/RasPiからアクセスするのに便利なUSBインターフェイス経由でI2Cセンサーを操作しようとしているわけですが、RasPiに組み込みたい場合、USBインターフェースは冗長ですね。 そこで、I2CシミュレータはUSB-シリアル変換部と、I2C I/Fを持つメインマイコン部に分離できるようにしておきます。開発時にはUSB-シリアル変換を使うが、RasPiに組み込む時はこれを外してシリアルインターフェース同士で直結するようにする。 以前はI2Cインターフェースで直結しようとしていましたから、コマンド解釈のためのマイコンが途中に挟まることになります。開発効率や発展性を考えるとこれくらいは許してもらいたいものです。

ブレッドボードで試す回路は最小限に

腕に覚えのある人はすぐ自分で色々やりたがりますが(私もそうです)、仕事を先に進めるためには、自分で手を加えるところは最小限度にすべきです。今回は自作の回路とプログラム、しかもmasterとslaveの二組あるので1本の信号の動きを確認するだけでも大変でした。特にブレッドボードは曲者です。ジャンパ線は多くても数本程度にすべきでしょう。最後は信号ピンの定義が間違っていたことと電圧降下で動かないことがわかるまで時間がかかってしまいました。今回は予想外に大規模になったのが失敗の元でした。 明日は予定があってこの仕事はできませんので、明後日、確認の取れた部分は半田付け回路に固定してトラブルを抑えようと考えています。 今日はここまで。

センサーの物理I/Fの標準化について

いわゆるメーカーズを標榜する各社が、センサーの物理I/Fの標準規格を提案しています。代表的なものに SparkfunのQwiic SeeedのGrove DigilentのPmod MikroElektronikaのmikrobus DFRobotのGravity <-- '18.11.26追記 スイッチサイエンスのConta 等があり、考え方がそれぞれ違います。当社の考えは (1) 通信の規格はI2Cに限定する 当社のやりたいことはI2Cで実現できるからです。他の規格、例えばSPIなどが必要になった時に考えます。必要のないときに余計な規格を決める必要はないでしょう。 (2) メイン基板を固定してセンサーを各種取り替えながら開発する可能性を考えると、基板同士を繋ぐ規格は欲しいが、センサーには設置条件とか取り付け方法があるのでセンサー基板をメイン基板に直に固定する構造を取れるかどうかを予め決められない。例えばイメージセンサーはケースに固定したいし、温度センサーはケーブルで引き出したい、等が考えられる。と言うわけで、メイン基板に載せるコネクタ(メス)だけ決めることにする。そのコネクタ以降センサーまで、電線が繋がればどんな規格でもいいことになります。 (3) コネクタを決める際に考慮すべきなのは、(a)信号の種類(数)、(b)寸法・形状、であるが、今までの経験から次のようにする。 ・I2Cのみの対応で大抵のことは実現できる。従って信号はVDD, GND, SCL, SDAの4本にする。 ・VDDの電圧は決めない。5V対応のコネクタには5V対応のセンサーを刺せば良いだけだからだ。ここではコネクタ内のピン位置だけ決める。対応する電圧はコネクタ毎、基板にシルクで明示が必要だろう。 ・試作では未だ主流の2.54mmピッチに合わせる。 ※ DFRobot社のGravity 4pin cableは2.0mmピッチのコネクタと2.54mmピッチのコネクタを両端に持っているようです <-- '18.11.26追記 ・実用化を視野に入れると、脱落しないようロック機構は欲しい。 ※コネクタを各種見てきましたが、XHシリーズが一番当社の目的に適っていると思います。 これだけ決めておけばメイン基板の設計ができます。

I2Cシミュレータを作る

初版のコードは書き上げました。これからデバッグしたいのですがデバッグのために既製のI2Cセンサーを使うのは操作性が悪く(ロジアナやオシロを使うことになる)、またカバー率も良くない(既製品が全てのプロトコルを実現しているわけではない)ので、今後繋ぐ可能性のあるI2Cセンサーのシミュレータを作ってみようと思います。ただし、ここでもこれを作るのが本業・本筋ではないので、完璧を目指すようなことはしません。というわけで開発方針は 1.スタートスモールで始める。今回の目的からスレーブモードのみとする。1byte read/write等の簡単なプロトコルで動かし始め、必要になったら複雑なプロトコルを追加できるようにする。ホストCPUのターミナルやプログラムから動かすのが目的なので、必要以上に完璧を目指すことはしない。 2.タイミング規定については専用の計測器を頼ることにする。 となります。次はこのシミュレータの仕様を考えます。

I2C-COM仕様 第2版(内容が古くなりましたが記録として残します)

2018.11現在、第3版になっています。 こちらからどうぞ。 === 第1版から変更した箇所は 下線で示す 。 === 1.名称: I2C-COM 2.文字: 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|S|P|R|W|T|K|N| a|b|c|d|e|f|s|p|r|w|t|k|n の36文字。その他は全て区切り記号として 使われる。 3.数値文字: 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F| a|b|c|d|e|f の22文字。 4.バイト: 数値文字2桁で表す。範囲は0x00~0xFFである。 5.スレーブアドレス: 7bitを数値文字2桁で表す。範囲は0x00~0x7Fである。 6.制御文字: S|P|R|W|T|K|N| s|p|r|w|t|k|n の14文字。以下にそれぞれの機能を説明する。 前提として、1つのトランザクション(ひとまとまりの流れ)はS |s で始まりP |p で終わる。その途中に再度S |s があってもよい。 S |s ・I2C信号線上にSTART条件を出す。リプライはない。エラーもない。 P |p ・I2C信号線上にSTOP条件を出す。リプライはない。エラーもない。 K |k ・I2C信号線上でslaveから8bit受信した後ACK条件を出す。8bit受信できなかったらタイムアウトエラーになる。(タイムアウトになる条件は後日) N |k ・I2C信号線上でslaveから8bit受信した後NACK条件を出す。8bit受信できなかったらタイムアウトエラーになる。(タイムアウトになる条件は後日) R |r ・スレーブアドレスが後に続く。Pを出すまでデータの向きはslave -> masterである。slaveからACKが返らないとタイムアウトエラーになる。(タイムアウトになる条件は後日) 例)R29 W |w ・スレーブアドレスが後に続く。Pを出すまでデータの向きはmaster -> slaveである。slaveからACKが返らないとタイムアウトエラーになる。(タイムアウトになる条件は後日) 例)W29 T |t ・バイトが後に続く。Pを出すまでデータの向きはmaster -&g

I2C-COM仕様を見直します

I2C-COM(コマンド言語の名称)のパーサを実際ターミナルから動かしながらデバッグしていて、使用感が悪いことに気づいたので仕様を見直そうと思います。 (1) 大文字が入力しづらい capital lockすればいいのですが、そう言う習慣がなく、いちいち切り替えるのが面倒なので大文字でも小文字でもいいことにしようと思います。 (2) キー入力直後に動作することに違和感がある 現状の仕様では、例えば"S"と入力したら入力した直後に動作し、"W01"と入力する場合は最後の"1"を入力すると同時に動作するわけですね。ターミナルから使うことを考慮すると、入力した1文字毎にエコーバックして、"W01"の次にEnterを押した後に実行するのがいいと思います。将来的には間違いがあったら直せるのがベターだと思いますが実装に時間がかかりそうなので後回しにします。 (3) (2)に関連しますが、将来的にはプログラムから直接駆動もしたいので、ターミナルから使う場合はターミナルモードに入ってから使うようにしようと思います。ターミナルモードに入らない場合はバイナリモードになるかもしれません。実装は後日になります。

Arduino用16進キャラクタから数値へ変換プログラム(内容が古くなりましたが記録として残します)

オリジナルは こちら char convertCharToHex(char ch) {   char returnType;   switch(ch)   {     case '0':     returnType = 0;     break;     case  '1' :     returnType = 1;     break;     case  '2':     returnType = 2;     break;     case  '3':     returnType = 3;     break;     case  '4' :     returnType = 4;     break;     case  '5':     returnType = 5;     break;     case  '6':     returnType = 6;     break;     case  '7':     returnType = 7;     break;     case  '8':     returnType = 8;     break;     case  '9':     returnType = 9;     break;     case  'A':     returnType = 10;     break;     case  'B':     returnType = 11;     break;     case  'C':     returnType = 12;     break;     case  'D':     returnType = 13;     break;     case  'E':     returnType = 14;     break;     case  'F' :     returnType = 15;     b

Arduino用 loop backテスト(内容が古くなりましたが記録として残します)

ArduinoをMacにUSBポートで繋いで、ターミナルから操作できることを確認します。 === オリジナルスケッチは こちら です。 void setup() { Serial.begin(9600); } void loop() {   if(Serial.available() > 0){     char ch = Serial.read();       Serial.write(ch);   } } === Arduinoに上記スケッチを書いたら、Mac/Linuxのターミナルから cd /dev でシリアルポートを探し、 screen /dev/*** 等で、叩いたキーがそのまま表示されるか確認します。終了はctrl+a, ctrl+k, yです。 ここまで

I2C-COMの実装〜コマンドパーサ(内容が古くなりましたが記録として残します)

コマンドパーサとは、コマンドを解釈するルーチンのことですが、Arduinoのスケッチではloop内に実装します。以下、概略を示します。 === シリアル受信した1文字が 'S'ならstart()を出しておしまい。 'P'ならstop()を出しておしまい。 'W'なら後に続く2文字(hexa)を受信して左に1bitシフトして、write(bit)を8回実行し、read()でACK/NACKを返す。 'R'なら後に続く2文字(hexa)を受信して左に1bitシフトして1bを加え、read()を8回実行し、9回目のread()でACK/NACKを読んで返す。 'T'なら後に続く2文字(hexa)を受信してMSBからwrite(bit)を8回実行し、read()でACK/NACKを返す。 'K'ならwrite(0)を出しておしまい。0=ACKを意味する。 'N'ならwrite(1)を出しておしまい。1=NACKを意味する。 === ここまで

I2C-COMの実装〜start/stop/read/writeの各関数(内容が古くなりましたが記録として残します)

start/stop/read/writeの各関数を書いていきます。"tSU_STA"等は規定時間以上待つことを意味します。 void start(void) {sda(1); scl(1); tSU_STA; sda(0); tHD_STA; scl(0); tLOW;} void stop(void) {sda(0); scl(0); tLOW; scl(1); tSU_STO; sda(1); tBUF;} データ転送関数は、関数に入ってくる時の状態がバラバラなので、次の規則を設けて時間を保証することにする。考え方は、 ・関数に入って出るまでにSCLがlow->high->lowの1サイクル動く。この時間をtLOW1, tHIGH1, tLOW2で表す。tLOW1>tSU_DAT, tHIGH1>=tHIGH, tLOW2>tVD_DAT、とする。 ・writeは関数に入った直後、readは関数に入ってくるとき、SDAは確定していることを前提とする。そのため、関数から抜けるときに次の転送サイクルのSDAが確定しているようにする。 void write(byte data) {sda(data); scl(0); tLOW1; scl(1); tHIGH1; scl(0); tLOW2;} byte read(void) {scl(0); tLOW1; scl(1); temp=SDA; tHIGH; scl(0); tLOW2; return temp;} ここまで

I2C-COMの実装〜SCL, SDAを操作する関数を設計する(2)(内容が古くなりましたが記録として残します)

start/stop/read/writeの各関数を書き下す前に、SCL, SDAの各信号を操作する関数を作ります。 === void scl(byte) ※引数の形式はbyteであるが、0x00の時はSCL=low、それ以外の時high-impedanceにします。SCL信号はpull upされているのでhighになります(slaveはhigh-impedanceであることが前提)。 byte sda(byte) ※引数の形式はbyteであるが、0x00の時はSCL=low、それ以外の時high-impedanceにします。SDA信号はpull upされているのでslave出力がlowならlow、highもしくはhigh-impedanceならhighになります。 ※返り値の形式はbyteであるが、0x00かそれ以外で判断すること。 ここまで

I2C-COMの実装〜SCL, SDAを操作する関数を設計する(1)(内容が古くなりましたが記録として残します)

関数のイメージを作るためにI2Cバスプロトコルを最小単位に分解してみます。 1. START: SCL=high, SDA=fall 2. STOP: SCL=high, SDA=rise 3. write_low: SDA=low, SCL=low>high>low。ACKをmasterから出すときもこれ。 4. write_high: SDA=high, SCL=low>high>low。NACKをmasterから出すときもこれ。 5. read: SCL=low>high>lowの時SDAを読む。slaveから出るACK/NACKもこれ。 できるだけ関数は減らすことを考えます。引数を持つようにすれば関数の数は減りますが、引数に固定値を入れるくらいなら関数を分けるのと同じなので、引数に変数を使うメリットがあるかどうかで考えます。 ・1と2は引数を使って一緒にすると分かりにくく間違いが起きそうなので一緒にはしない。 ・3と4は変数引数を使えると便利なので一緒にする。 よって関数は次の4つを作ることにします。 1. void start(void) 2. void stop(void) 3. void write(byte) ※引数の形式はbyteであるが、0x00の時は0b(ACK)、それ以外の時は1b(NACK)を書く。 4. byte read(void) ※返り値の形式はbyteであるが、実際には1bitであり、0x00(ACK)か否か(NACK)で判断すること。 ここまで

I2C-COMの実装(1)〜タイミング規定を見ておく(内容が古くなりましたが記録として残します)

ここからいよいよI2C-COMを実装して行きます。 当面Arduinoのスケッチを書くことになるのですが、その準備作業としてSCL、SDAを操作する関数を作ることにします。ここで考慮したいのが、関数にどこまで機能を持たせるかです。高機能で書きやすいのと低機能で細かく制御できるのとのバランスをどこに置くかと言ういつもの問題です。底辺の最初の設計を間違うと後々まで響くので慎重に検討します。 === まず、後で困らないようにSCL, SDAのタイミング規定を確認しておきます。Standard-mode CLK=max.100kHzを前提とします。 ここではSCLはmasterからだけ出力し、SDAもmasterから出力するときの規定だけ気にすれば良いので(slaveが規定を逸脱したらどこかでエラーになることを期待する)、守らねばならない規定は次のようになります。 (1) SCL自身の規定 0<fCLK<100kHz, tLOW>4.7us, tHIGH>4.0us (2) SCLとSDAの関係に関する規定 小解説: set up timeとは、信号Aのある時点に対して信号Bが前もって確定しておかねばならない時間 hold timeとは、信号Aのある時点以降も信号Bが確定しておかねばならない時間 === プログラムで意識しやすいように、タイミング規定を(1) SDA -> SCL、(2) SCL -> SDA、に分類します。 (1) SDA -> SCL tHD.STA>4.0us:START condition時、SDA=fallからSCL=fallまで tSU.DAT>250ns:データ転送時、SDAが確定してからSCL=riseまで (2) SCL -> SDA tSU.STA>4.7us:REPEATED START condition時、SCL=riseからSDA=fallまで tHD.DAT>0:データ転送時、SCL=fallからSDAが次に変化するまで tSU.STO>4.0us:STOP condition時、SCL=riseからSDA=riseまで === 長くなるのでここまで

I2C制御コマンドの書式( 初版。第2版が出ましたが、記録として残しておきます)

I2C制御コマンドを実装する下準備として、I2C制御コマンドの書式を正確に定義しておきます。 === 1.仮称: I2C-COM 2.文字: 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|S|P|R|W|T|K|N の23文字。その他は全て区切り記号として読み飛ばされる。 3.数値文字: 0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F の16文字。 4.バイト: 数値文字2桁で表す。範囲は0x00~0xFFである。 5.スレーブアドレス: 7bitを数値文字2桁で表す。範囲は0x00~0x7Fである。 6.制御文字: S|P|R|W|T|K|N の7文字であり、以下にそれぞれ説明する。 前提として、1つのトランザクション(ひとまとまりの流れ)はSで始まりPで終わる。その途中に再度Sがあってもよい。 S ・I2C信号線上にSTART条件を出す。リプライはない。エラーもない。 P ・I2C信号線上にSTOP条件を出す。リプライはない。エラーもない。 K ・I2C信号線上でslaveから8bit受信した後ACK条件を出す。8bit受信できなかったらタイムアウトエラーになる。(タイムアウトになる条件は後日) N ・I2C信号線上でslaveから8bit受信した後NACK条件を出す。8bit受信できなかったらタイムアウトエラーになる。(タイムアウトになる条件は後日) R ・スレーブアドレスが後に続く。Pを出すまでデータの向きはslave -> masterである。slaveからACKが返らないとタイムアウトエラーになる。(タイムアウトになる条件は後日) 例)R29 W ・スレーブアドレスが後に続く。Pを出すまでデータの向きはmaster -> slaveである。slaveからACKが返らないとタイムアウトエラーになる。(タイムアウトになる条件は後日) 例)W29 T ・バイトが後に続く。Pを出すまでデータの向きはmaster -> slaveである。slaveからACKが返らないとタイムアウトエラーになる。(タイムアウトになる条件は後日) 例)W8A 以上

I2C制御コマンドの検討(3)(内容が古くなりましたが記録として残します)

今日は休日ですが、早く方向性を出したかったのでSoftI2CMasterを使って見ました。 結論から申しますと、SoftI2CMasterは使わず、SCL, SDA信号を直接制御することにしました。一から作るのは大変なことは百も承知ですが、土台がしっかりしていないといくらその上層部が綺麗にお化粧されていたところで動きがよくわからず、問題があった時デバッグも修正も拡張もできないことがわかったからです(こんなこと書くのこれで何度目だ)。 いきなりアセンブラやCで書き始めるのは無理があるので、当面はArduinoのdigitalWrite/digitalReadでどこまで対応できるかやってみることにします。 === 最初に気づくのは、SCL, SDAを制御するには双方向なことです。ArduinoのピンはpinModeでinputかoutputのどちらかしか定義できませんからArduinoの外部に3-stateバッファを外付けすることを考えないと行けません。 もう一つ気になるのは、Arduinoのスケッチで書いてI2Cのスピードが出なかったときどうするかです。I2C制御をするだけのためにArduinoを高いCPUに置き換えることは考えにくいのですが、メインCPU(RasPiを想定している)にI2C信号を直結すればスピードの問題は解消するかも知れません。その際に一度書いたプログラムがそれほど大きく書き換えなくていいことが望ましいのは言うまでもありません。 I2C+uC->USB->メインCPU、の流れにしておけば、メインCPUはMac/Windows/Raspi等々何でも使えるので、I2Cセンサーをちょっと使ってみる、ソフトの初期開発をする、等の際には便利でいいと思っていました。もし仮に、実用化の際にuC->USBの部分を端折って、I2CをメインCPUに直結せねばならない時が来ても、I2Cプロトコルを一旦コマンドにしておく、と言う流れは変えなくて良いので、今後無駄にはならないのではないかと思います。

I2C制御コマンドの検討(2)(内容が古くなりましたが記録として残します)

次にどう実装するかを考えます。当然今までの検討は実装することをイメージして進めているわけですが、最終段階で、できると思ってたことができなかったりすると後戻りが大きいので、一つのレイヤーの実装イメージができたら実際に動作を確認してから次のレイヤーの構想・開発に進めることが大事です。 前回までで、以下に示す7種の動作をI2Cで実現する(1)のと、これらを使って言語で使い勝手の良い関数を作る(2)ことを進めれば良いことがわかります。本稿では(1)を進めます。 S:START P:STOP R:7bitのslave addressにRと識別する1bitをつけて1byte writeしてACKを待つ W:7bitのslave addressにWと識別する1bitをつけて1byte writeしてACKを待つ T:8bitのregister address/dataを1byte writeしてACKを待つ K:slaveから8bit送ってきたらACKを返す N:slaveから8bit送ってきたらNACKを返す 上記のS, P,,,Nの動作をI2Cに落とし込むのに、ここではArduinoをベースに考えます。「一気通貫に動くところまで進めてから後のことを考える。一個一個を完璧にするようなことはしない」と言う方針に則り、手元にあってIDEに習熟して動作が簡単に確認できる物を使います。もちろんどんなCPU、言語、を使っても構いませんし、やってくれる人がいると嬉しいのですが。 ArduinoでI2Cを動作させるのに、 Wireライブラリ があることがわかります。ところがこのライブラリの関数には以下のようなものがあるのですが、いたって使い勝手が悪いのです。ここまで読み進めていただいた方にはお分かりでしょうからクドクド申しません。 === begin() requestFrom() beginTransmission() endTransmission() write() available() read() SetClock() onReceive() onRequest() === せっかくI2Cプロトコルを一番primitiveなところまで分解したのにまた高級言語の壁に突き当たってしまいました。

I2C制御コマンドの検討(1)(内容が古くなりましたが記録として残します)

本稿からいよいよコマンドからI2Cの制御ができるようにしていきます。 ここで考慮したいのが使い勝手と処理スピードのバランスです。例えばPythonから直接SCL, SDAが見えて制御できれば何でもできるわけですが、あまりにも非効率なのは議論を待たないでしょう。しかし今あるライブラリの関数だとデバッグ性も拡張性も低い。ではどこら辺りが落としどころなのか? ここでもう一度、I2Cプロトコルのおさらいをしますと、 === (1) データ転送は、SCL=highの時SDAを安定させ、SCL=lowの時SDAを変化させて行うのが基本。 (2) SCL=highの時SDAをhigh->lowとしたらSTART、SCL=highの時SDAをlow->highとしたらSTOP。全てのトランザクションはSTARTで始まりSTOPで終わる。START->STOPの間にSTARTが再びあっても良い。START/STOPはマスター側からしか起こさない。 (3) 送信側が8bitデータを転送した直後、受信側がACK or NACKを返す。マスターが送信側の時はスレーブが受信側だがその逆もある。ACK (NACK)とは、SCL=highの時SDA=low(high)で示す。 === 以上を踏まえてプロトコルを次のように分類します。 === (1) マスターから一方通行でリプライのないアクション。 (2) マスターからアクションを起こしてリプライを待つ。 (3) マスターが予期しないときスレーブからの割り込み動作は考慮しない。 === (1)には、START, STOPが入ります。 (2)を更に整理すると (2-1)マスターから1byteデータを送ってスレーブからのACKを待つ。1byteデータには、7bitのslave address+R/W識別bit、8bitデータ、のバリエーションがある。1つのコマンドでは使いにくいので3つに分ける。シェルからコマンド打つとき、頭の中でアドレスを1bitシフトしてR/Wの1bitをつけて、は面倒だと思った。 (2-2)「マスターから何らかのアクション」を起こされてスレーブからデータを送るシーケンスが始まる。データ受信後マスターがACKを返せば継続、NACKを返せばそこで終了。「マスターから何らかの

I2Cプロトコルをどう見せるか

前稿でI2Cプロトコルをおさらいしました。今回はこれをソフトにどう見せたら使い勝手が良いのか考えてみることにします。 今まで見てきたI2C制御のライブラリは、コマンド・関数の実装の中でI2Cを参照・制御している部分がブラックボックスになっており、信号の動きが想像しづらくてデバッグ性が低く、拡張性もない、のが気に入らないのです。 そこで、I2C制御に出来るだけ1対1に対応するコマンドを設定して、シェルから直接コマンドを叩くもよし、このコマンドを使ってもっと高度で複雑な関数を作るもよし、にしようと考えました。 と言うわけで、まずは前稿のI2Cプロトコルをどんなコマンドにしたら良いかを検討することにします。

I2Cプロトコルのおさらい(保存版)

本稿が参照しているのは 「I2Cバス仕様およびユーザーマニュアルRev.5.0J-2012年10月9日」 の日本語翻訳11月2日 ですが、I2Cバスの全仕様を実装するのが目的ではないので、以下を前提とします。 (1) マスターは1個で固定。スレーブは複数あって良い。マルチマスターは考慮しない。 (2) SCLはマスターが駆動する。SCLをスレーブが駆動する処理は考慮しない。 と言う前提でI2Cプロトコルを要約すると (1) データ転送は、SCL=highの時SDAを安定させ、SCL=lowの時SDAを変化させて行うのが基本。 (2) SCL=highの時SDAをhigh->lowとしたらSTART、SCL=highの時SDAをlow->highとしたらSTOP。全てのトランザクションはSTARTで始まりSTOPで終わる。START->STOPの間にSTARTが再びあっても良い。START/STOPはマスター側からしか起こさない。 (3) 送信側が8bitデータを転送した直後、受信側がACK or NACKを返す。マスターが送信側の時はスレーブが受信側だがその逆もある。ACK (NACK)とは、SCL=highの時SDA=low(high)で示す。 これらを前提に、コマンドとか関数にはどう見えるのが使い勝手がいいのか考えることにします。