About this

このサイトの目的

  • 長年開発し続けているIOTハウスのハードやソフトについて
  • 今まで経験してきたコンピュータや周辺機器、ネットワーク、IT昔話
  • 親が子供を褒め育てる環境へのヒントになればと思って
    • 子供が実験や遊び学んだ物が実用化->親が喜ぶ->親が子供を褒める->子供が褒めてもらう為に更に学び工夫する->親が子供を褒める->子供が育つ->社会が育つ

著者

  • kujiranodanna:くじらのだんな、昔からコンピュータで外部機器を制御したいと思っている人
  • 大昔1970年代コンピュータ周辺機器やネットワーク機器メンテナンス、ネットワークエンジニア、IT専門学校非常勤講師、大学非常勤講師(情報基礎)、近年はビル管理、現在は隠居生活
  • Raspberry Piや古いPCとLinuxを使いIOTハウスの開発と実践をしている人

実践IOTハウスとは

  • 家電の自動化、防犯、防災、音声応答、監視制御システムです
  • IOTハウスのIOTは(Input Output Things)入力と出力で何か出来ればIOTと思っています、Internet無くてもイベントや定時処理が出来ます
  • shell script、C、javascriptで構築され全てブラウザで操作出来ます
    • 出先から部屋の温度を確認してクーラー運転する
    • 夕方外が暗くなると玄関や部屋の明かりを点ける
    • 明け方に外の湿度を元に家庭菜園の水やりをする
    • 防犯センサーがはたらくと動画をメールする
    • 決まった時間に音楽を鳴らす
    • 火災感知器が発報するとメールと電話(ワンギリ)で知らせる
    • 外気湿度を元に床下換気扇を間欠運転させる
    • 古いノートPCをIOTハウスで復活させる
  • Homebridge Alexaを追加導入、Alexaアプリで家電を音声操作
  • 机の奥へ仕舞い込んだRaspberry Piでホームエレクトロニクス&ホームセキュリティを実現しよう

https://iot-house.jpn.org
実践IOTハウス

IOT-House_docker

IOT-House_dockerとは

  • IOT-House_old_pcのDocker版です。
  • IOT-House_dockerにはUbuntu 18.04 ,Ubuntu 20.04のバージョンを用意してます。
  • 実行するにはdockerのprivilegeモードでGPIOのCP2112(Silicon Laboratories社 Single-Chip HID USB to SMBus Master Bridg) Sunhayato MM-CP2122Aを動作させます。
    I2Cバスへは環境ガスセンサーBME680を接続します。
  • 実行条件
    Docker engineにはLinuxが必要、ここではUbuntu20.04デスクトップで確認しています。
    デバイスドライバーが無いWindowsとMACはCP2112の操作が出来ません。
    WindowsとMACはインターフェースをnoneとしてリモートraspberry piのIPアドレスを設定GPIOの操作します。
  • 準備
    イメージのpull
    1
    docker pull kujiranodanna/iot-house_docker:ubuntu18.04-latest
    又は
    1
    docker pull kujiranodanna/iot-house_docker:ubuntu22.04-latest
  • 実行
    1
    docker run -itd --privileged --name iot-house_docker -p 8022:22 -p 80:80 -p 443:443 kujiranodanna/iot-house_docker:ubuntuxx.xx-latest
    • もしTWE-Lite-DIPをUSBへ用意出来るなら
      1
      docker run -itd --privileged --name iot-house_docker --device=/dev/ttyUSB0:/dev/ttyUSBTWE-Lite -p 8022:22 -p 80:80 -p 443:443 kujiranodanna/iot-house_docker:ubuntuxx.xx-latest
  • 確認
    1
    2
    3
    # docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    08bf7215bed2 a54286a23d97 "/etc/rc.local_docker" 17 hours ago Up 18 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:8022->22/tcp, :::8022->22/tcp iot-house_docker
    1
    2
    3
    http://localhost
    User:remote
    Password:hand
    iot-house_docker
  • 停止
    1
    docker stop `docker ps -ql`
  • 再開
    1
    docker start `docker ps -ql`
  • コンテナ削除
    1
    docker rm `docker ps -ql`

  • ホスト側へHomebridgeHomebridge-Alexaを導入iot-house_homebridge 防犯センサーとAlexa、IOT-Houseデモ動画・・・みんなのサマーセミナー2022の8月6日土曜日1限目4階2G教室「メイドカデン!?でええやん!」授業の再現
    授業のスライド

入出力イベント設定

  1. DIO Control-1
  • 入力端子がHighからLow、またはLowからHighに変化した時に開始する動作を設定します。
  • 開始する操作を設定する2つのタブがあります。
  • 最初のタブで、操作を開始、カウンターをリセット、およびログを表示するように設定できます。
  • 送信先Addressにlinenotifyを設定するとLINEにメッセージや写真を送ることが出来ます。
    • linenotifyを使用するには事前にhttps://notify-bot.line.me/my/でline notifyアクセストークンを発行
      /etc/rc.pepo/linenotifyに設定しておく必要があります
DIO_Control-1 2. DIO Control-2 DIO_Control-2

gmail設定

  • メール設定(gmailを使う場合)
    • gmailでコマンド・レスポンスする為の設定です
    • 2022.5.30以降パスワードはGoogleの2段階認証の有効化とアプリパスワードを取得してgmailのプレーンパスワードの代わりに設定します。
    • Gmailを介して遠隔地でIOT-Houseのコマンドと応答を操作できます。
    • コマンドで出力端子のHigh/Low、レスポンスで入力端子のHigh/Low状態、温度、湿度、気圧、大気質の値、グラフ、写真、ビデオなど操作
    • 新規メールをEmail check interval時間毎チェックしSubject(keyword)に合致したキーワード内容を実行してレスポンスを返します
gmail_settings
  1. Email settingsタブ
  • Gmailを介して遠隔地でIOT-Houseのコマンドと応答を操作できます。
  • コマンドで出力端子のHigh/Low、レスポンスで入力端子のHigh/Low状態、温度、湿度、気圧、大気質の値、グラフ、写真、ビデオなど操作gmail_command

Mail コマンド
To: dokokanodareXX@gmail.com
Subject: iot009
Body: none
Mail Response
From:root <dokokanodareXX@gmail.com>Date: Tuesday, September 22, 2020 10:53 10:53To:dokokanodareXX@gmail.comSubject:iot009 IOT-House report
Body: 以下
==input list==
1:火事です=high
2:扇風機スイッチ=low
3:Input3=high
4:出力4と接続=high
5:Input5=none
6:Input6=none
7:Input7=none
8:Input8=none
9:防犯センサー=high
10:Input10=high
11:Input11=high
13:屋外照度=high
14:Input14=none
15:Input
15=none
16:Input16=none
17:CPU温度=high
18:部屋の温度=low
19:部屋の湿度=low
0:外気温度=high
21:外気湿度=low
22:気圧=high
23:ガス=high
24:空気=low
==output list==
1:換気扇=high
2:電気=low
3:Outnput3=low
4:入力4と接続=high
5:Outnput5=none
6:Outnput6=none
7:Outnput7=none
8:Outnput8=none
9:ななちゃん天井電灯
10:冷房
1:エアコン
12:暖房
13:天井電気
14:サーキュFAN
15:散水ポンプ=low
16:Outnput
16=none
17:玄関電灯=low
==Other Command==
21:CPU Temperature
22:GPIO Temperature&Humidity
23:No1 Camera Movie
24:No1 Camera Picture
25:No2 Camera Movie
26:No2 Camera Picture
27:No3 Camera Movie
28:No3 Camera Picture
29:Module Camera Movie
30:Module Camera Picture
31:Twlite Temperature&Humidity
32:CPU Temperature&Graph
33:GPIO Temperature&Graph
34:GPIO Humidity&Graph
35:Twlite Temperature&Graph
36:Twlite Humidity&Graph
37:GPIO Pressure&Graph
38:GPIO Gas&Graph
39:GPIO IAQ&Graph
40:GPIO Last Hour CSV Data

温度グラフを要求
To: dokokanodareXX@gmail.com
Subject: iot009 33
Body: none
Mail Response
From:root <dokokanodareXX@gmail.com>Date: Tuesday, September 22, 2020 12:53 10:53To:dokokanodareXX@gmail.comSubject:iot009 IOT-House report
Body : GPIO Temperature Graph Report
shot_gpio_temp_grap

config_M2M

実践IOTハウスのM2Mシナリオ

  • 家中に散らばるRaspberry Pi zero WHで分散処理

  • 個々に搭載しているデバイスや機能を外部から利用可能にする

  • 単一で完結処理出来ない機能やスペック的に厳しい物は他へ依頼する

  • ローカルネットワークに無い機能はGmailで外の世界へ依頼する

    • Gmailにより世界に繋がるM2Mの実践IOTハウス
  • 設定
    Dio ControlタブでAction:high→low or low→highでSend_mesageを選択、Addressへローカルアドレス、Messageボックスへキーワードやメッセージを設定します

    ①入力イベント:防犯センサー high→low、iot00f.localホストへMessageボックス:「dio0low」送出、iot00fが入力ポート0番イベントhigh→lowを実行

    ②Messageボックス:「あかりをつけて」送出、iot00f.localを監視しているブラウザが処理して「あかり」を設定している出力ポートをhighへ

    ③Messageボックス:「@あかりをつけて」送出、iot00f.localを監視しているブラウザが処理して「あかりをつけて」を発話・・・発話出来るブラウザが監視している場合

    Alexaで返事出来ない事をブラウザから応答できるスクリプトpepoalexahelp

    ④ AddressがGmailアドレスの場合Mail Settingsタブで設定したキーワード監視中のIOT-Houseがマッチ出力番号をHigh又はオンする、又は監視しているブラウザが処理・・・Gmailなので世界中に繋がる事が出来る、なのでM2Mで世界に繋がる実践IOTハウスです


  • 実際のIOTハウスでは

    • 人感センサーが接続されている機器からモジュールカメラが搭載している機器へ動画メールか写真メールを時間帯を切り替え依頼
    • 開発当初からGmail経由で外の世界から家の家電を操作していたがhomebridge alexaでより快適に操作・・・夏場、外出中alexaアプリでペット・ルームの温度を確認、エアコン冷房を運転
    • 寝室の温度を測定している機器から温度により換気扇が接続している機器へ運転、停止を依頼・・・熱帯夜でも無い限り27度で運転、停止すれば快適
      Auto Prosessタブで部屋温度でリモコン high・low
      出力4(リモコン)と入力4(リモコン入力)が接続を接続している為、リモコン入力のhigh,lowイベントが発生
    • 温度上昇→iot02fホストへ出力4high依頼→換気扇が運転
    • 温度下降→iot02fホストへ出力4low依頼→換気扇が停止
    • iot02fは時間帯と入力条件により換気扇を運転、停止・・・実際は省エネとハンチング防止の為、間欠運転をしている
  • more information and source
    https://github.com/kujiranodanna/IOT-House/blob/master/raspberrypi/usr/local/bin/pepoalexado
    https://github.com/kujiranodanna/IOT-House/blob/master/raspberrypi/usr/local/bin/pepomsgsend

timelapse設定

  • timelapseシナリオ

    • raspberry piにはモジュールカメラでtimelapse機能が標準搭載されているが

    • 低スペックかつ多重処理のIOT-House_zero_w単体でtimelapseを完結するには厳しい

    • なので2台のraspberry pi zeroでサーバーとクライアント分散処理をします

    • サーバー側(https://github.com/kujiranodanna/IOT-House/blob/master/raspberrypi/usr/local/bin/pepotimelapse)

      • raspistillコマンドのawbとannotationオプションをつけ60秒ごとにimage000.jpg,image001.jpg … image059.jpgファイル作成(スペック制限で画像サイズは640x480)
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        while true;do
        NOWSEC=`date +"%S:"`
        NOWMIN=`date +"%M:"`
        if [ $NOWSEC = "00:" ];then
        k=`printf "image%03d.jpg" $j`
        raspistill -awb flash -a 1036 -ae +25+25 -w 640 -h 480 -o $IMAGE_DIR/$k
        j=$(($j + 1))
        if [ $j -gt 59 -o $NOWMIN = "59:" ];then
        .
        fi
        done
      • 1時間ごとにこれをtimelapse.tar.gzで固め繰り返す
        1
        2
        3
        4
        mkdir $IMAGE_DIR_TMP
        mv $IMAGE_DIR/* $IMAGE_DIR_TMP/
        (cd $WORKDIR;tar cfz ${IMAGE_TIMELAPSE}.tar.gz $IMAGE_TIMELAPSE)

    • クライアント側(https://github.com/kujiranodanna/IOT-House/blob/master/raspberrypi/usr/local/bin/pepoffmpegtimelapse)

      • 1時間毎にtimelapse.tar.gzをサーバー側からゲット解凍後、日付時間毎の2021-08-17_00.mp4 … 2021-08-17_59.mp4の動画ファイル作成、htmlで閲覧できるようにしておく
      • 1時間毎のtimelapse(セキュリティ上大部分をトリミングしてます)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      while true;do
      NOWMIN=`date +"%M:"`
      if [ $NOWMIN = "05:" ];then
      NOWHOUR=`date +"%H:"`
      NOWDATE=`date +"%Y-%m-%d_%H"`
      HOURAGO=`date -d "1 hour ago" +"%Y-%m-%d_%H"`
      DAYAGO=`date -d "1 day ago" +"%Y-%m-%d"`
      WEEKAGO=`date -d "1 week ago" +"%Y-%m-%d"`
      msleep 60000
      else
      msleep 10000
      continue
      fi
      .
      curl -s --connect-timeout $RETRYTIME --retry $RETRY --user-agent ${USERAGENT} --tlsv1 -k -u ${USER}:${PASSWORD} https://$RMHOST:$PORT/$REMOTEFILE >$LOCALFILE
      .
      ffmpeg -f image2 -i $IMAGE_DIR_TMP/image%03d.jpg -vcodec libx264 -y $IMAGE_DIR/${HOURAGO}.mp4 >/dev/null 2>&1
      • 00時に時間毎ファイルから1日分2021-08-17.mp4の動画ファイル作成、外部SDカードに移動htmlで閲覧できるようにリンクしておく
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        if [ $NOWHOUR = "00:" ];then
        ls -l $IMAGE_DIR/*| grep $DAYAGO| awk '{printf("file %s\n",$9)}' >$FFMPEGINPUT
        .
        ffmpeg -safe 0 -f concat -i $FFMPEGINPUT -c copy -y $IMAGE_DIR/${DAYAGO}.mp4
        .
        mv $IMAGE_DIR/${DAYAGO}.mp4 $MP_DIR/
        ln -s $MP_DIR/${DAYAGO}.mp4 $IMAGE_DIR/${DAYAGO}.mp4
        .
        WEEKAGO_IMAGE=`ls -l $IMAGE_DIR/*| grep $WEEKAGO| awk '{printf("%s ",$9)}'`
        MP_WEEKAGO_IMAGE=`ls -l $MP_DIR/*| grep $WEEKAGO| awk '{printf("%s",$9)}'`
        if [ `echo $WEEKAGO_IMAGE| wc -w` -eq 0 ];then
        continue
        else
        rm $WEEKAGO_IMAGE
        .
        fi
      • 外部SDカードに溜まった1週間前の動画ファイルを消去
  • timelapse設定

    • サーバー側起動(/service/にサーバー・スクリプトへリンクを張りdaemotoolsで起動する)
      1
      2
      3
      4
      5
      6
      7
      8
      9
        ssh pi@iotXXX
      .
      $ sudo su
      # cd /service/
      # mkdir timelapse
      # cd timelapse
      # ln -s /usr/local/bin/pepotimelapse run
      # svstat /www/pepolinux/timelapse/
      /www/pepolinux/timelapse/: up (pid XX) X seconds
    • クライアント側(USBへ動画保存用SDカードセット後クライアント・スクリプトを起動)
      1
      2
      3
      4
      5
      6
      7
      8
      ssh pi@iotXXX
      .
      $ sudo su
      # cd /service/
      # mkdir ffmpegtimelapse
      # /usr/local/bin/pepoffmpegtimelapse run
      # svstat /www/pepolinux/ffmpegtimelapse/
      /www/pepolinux/ffmpegtimelapse/: up (pid XX) X seconds
      • 1日分のtimelapse(セキュリティ上大部分をトリミングしてます)

WindowsとMACでIOT

WindowsとMACでIOTをする

  • WindowsかMACでIoT(Internet of Things)は数多あるけど、IOT(Input Output Things)はGPIO搭載されてないので温度測定や外部端子の入出力が直接出来ません
  • ここではIOTをVirtualBox仮想化でGPIOを接続、WindowsとMACでIOTハウスを実験します
  • WindowsとMACはVirtualBoxのインストールは既に終わっていると仮定して
    • Windowsは便宜上MACからのRemote VNCでの画面キャプチャした物
  1. URLよりイメージをダウンロードしますIOT-House_old_pc_xx.7z
  2. ダウンロードしたファイル、IOT-House_old_pc_xx.7z を解凍、IOT-House_old_pc_xx.imgをVirtualBoxのDISKイメージへ変換します
    1
    2
    3
    VBoxManage convertfromraw --format VDI IOT-House_old_pc_0.01.img IOT-House_old_pc_0.01.vdi
    Converting from raw image file="IOT-House_old_pc_0.01.img" to file="IOT-House_old_pc_0.01.vdi"...
    Creating dynamic image with size 8068792320 bytes (7695MB)..
  3. 以下VirtualBoxでIOT-House_old_pc_0.XX.vdiをストレージへ設定、起動しますVirtualbox_setting
  4. USBへMONOSTICK、TWELITE、MM-CP2112Aに環境ガスセンサーBME680や温湿度センサーAM2320接続、VirtualBoxのUSBタブで接続設定をしますVirtualbox_usb_MAC
  5. MACのVirtualBoxでIOT-House_old_pcへログインVirtualbox_iot-house_MAC
  6. VirtualBox内localhostへ接続IOT-House_old_pcのControl PanelVirtualbox_iot-house_Windows
    Virtualbox_iot-house_control1_Windows
  7. VM(VirtualBox IOT-House_old_pc)経由ではあるがWindows直接続USB<->GPIO変換MM-CP2112A<->I2C接続<->環境ガスセンサーBME680の温度、湿度、気圧、IAQなど取得表示されている事がわかると思う
    Virtualbox_iot-house_control2_Windows

IOT-House_old_pc

IOT-House_old_pcとは

  • 古くなってWindowsでは使えなくなったノートPCをiot-houseで復活させる物です。
  • IOT-House_old_pcはUbuntu 18.04 LTSにraspberry piのIOT-Houseを移植したものです。
  • SunhayatoのMM-CP2112AをGPIOに使い環境ガスセンサーBME680や温度湿度センサーAM2320で使います。
  • IOT-House_old_pcはサーバーで使用するのでそれ程、高い性能は必要有りません。
  • 動作環境はCPUが1GHzメモリが約1GB程度の古いノートパソコンを想定しています。
  • raspberry pi zero Wに比べて古いノートパソコン消費電力(25W程度)は多いですが、標準でUPS搭載 (バッテリー)、速度、安定性に優れています。iot-house_old_pc_img
    Left debug MAC, Right old PC,MM-CP2112A+Self-made board,I2C sensor BME680,AM2320

ハードウエア

  • 下記容量のフッラッシュメモリを用意して下さい
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    fdisk /dev/sdb

    Welcome to fdisk (util-linux 2.29.2).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.

    Command (m for help): p
    Disk /dev/mmcblk0: 7.3 GiB, 7820279808 bytes, 15273984 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x15ae16d5

インストール

  • URLよりイメージをダウンロードしますIOT-House_old_pc_xx.7z
  • ダウンロードしたファイル、IOT-House_old_pc_xx.7z を解凍、IOT-House_old_pc_xx.imgをフッラッシュメモリへ書き込みます、例えばddコマンド
    1
    dd if=IOT-House_old_pc_xx.img of=/dev/sdb bs=100M
    ノートパソコンのUSBへフッラッシュメモリとMM-CP2112Aを装着後電源を投入します、5分ぐらい立ち上げに掛かるかもしれません。

設定

  • ログイン画面が出たら user: remote, password: hand でログイン

  • ネットワークの設定を各環境に合わせ設定します、初期設定では優先LAN、ホスト名 iot000

  • 別PCからは http://iot000.local でuser:remote, password: hand でログイン

  • Control panel が表示されたら設定をします

  • ネットワークの設定が終了したら、以下コマンドGUI無しで立ち上げ時間の短縮出来ると思います。

    1
    sudo systemctl set-default multi-user.target
    iot-house_old_pc_control_panel-1
    iot-house_old_pc_control_panel-2
  • 設定方法はraspberry piのIOT-Houseを同じです

cp2112_BME680

CP2112とは

  • 開発するためのパッケージをlibhidapiインストール

    1
    2
    # apt install libhidapi-dev
    libhidapi-dev libhidapi-hidraw0 libhidapi-libusb0
  • 以下ファイルをゲット・コンパイルBoschSensortec/BME680_driverからFork

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    bme680.c  bme680.h  bme680_defs.h  pepocp2112ctl.c
    # gcc -Wall -o pepocp2112ctl pepocp2112ctl.c bme680.c -lhidapi-hidraw
    # ll
    合計 144
    drwxr-xr-x 2 root root 140 4月 6 17:39 ./
    drwxr-xr-x 3 www-data www-data 840 4月 6 17:39 ../
    -rwxr-xr-x 1 root root 44364 4月 13 2019 bme680.c*
    -rwxr-xr-x 1 root root 8353 4月 13 2019 bme680.h*
    -rwxr-xr-x 1 root root 17134 4月 13 2019 bme680_defs.h*
    -rwxr-xr-x 1 root root 34644 4月 6 17:39 pepocp2112ctl*
    -rw-r--r-- 1 root root 30626 3月 28 16:26 pepocp2112ctl.c
  • プログラミング例、SMBus Devices操作のみソースから抜き出し重要な箇所だけ説明します、他はソースを確認して下さい。(経験上GPIOはマルチプロセスで動作させる必要があると思いセマフォ (semaphore)を使用し結構な量が有ります。)

    • CP2112のI2C接続デバイスBME680はバッファーにI2Cアドレス、必要なコマンド、データ、バイト・カウンタを設定、hid_send_feature_reportで送信し必要に応じてコマンドに対するレスポンスを待ち処理をします。
    • BME680ライトはコマンド(CP2112_DATA_WRITE)、レジスター・アドレス、データ、バイト数を設定しデバイスに書き込みます。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
      {
      .
      reg[0] = CP2112_DATA_WRITE;
      reg[1] = BME680_I2C_ADDR_PRIMARY<<1;
      reg[2] = len+1;
      reg[3] = reg_addr;
      for (int8_t i=4; i<len+4; i++)
      reg[i] = reg_data[i-4];
      rslt = hid_send_feature_report(hd, reg, len+4);
      • デバック中のバッファ等ダンプ
        1
        2
        3
        4
        5
        user_i2c_write() dev_id: ec reg_addr: e0 len: 1
        user_i2c_write()1 rslt: 5 len: 1
        reg dump start
        0:14 1:ec 2:02 3:e0 4:b6
        reg dump end
    • BME680リードは最初にライトコマンドでレジスターアドレスを送信します。
      • 次にI2Cアドレスリード・リクエスト・コマンド(CP2112_DATA_READ_REQ)送信、
        データが整う迄(CP2112_DATA_READ_FORCE_SEND)でPolling、ステータス確認、(CP2112_DATA_READ_RESPONS)を待ち、デバイスからデータを読み出します。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len)
        {
        .
        reg[0] = CP2112_DATA_WRITE;
        reg[1] = BME680_I2C_ADDR_PRIMARY<<1;
        reg[2] = 1;
        reg[3] = reg_addr;
        rslt = hid_send_feature_report(hd, reg, 4);
        .
        user_delay_ms(HID_WAIT);
        reg[0] = CP2112_DATA_READ_REQ;
        reg[1] = BME680_I2C_ADDR_PRIMARY<<1;
        reg[2] = 0x00; // reads length_high
        reg[3] = len; // reads length_low
        rslt = hid_send_feature_report(hd, reg, 4);
        .
        user_delay_ms(HID_WAIT);
        while (retry_cnt < 3)
        {
        /* SMBus Polling */
        reg[0] = CP2112_DATA_READ_FORCE_SEND;
        reg[1] = 0x00; // reads length_high
        reg[2] = len; // reads length_low
        rslt = hid_send_feature_report(hd, reg, 3);
        .
        user_delay_ms(HID_WAIT);
        rslt = hid_read_timeout(hd, buf_in, len+3, timeout);
        .
        /*
        buf_in[0]:hid_report ID->0x13:CP2112_DATA_READ_RESPONS
        buf_in[1]:hid_status 0x00->Idle ,x01->Busy ,x02->Complete
        ,buf_in[2]:hid_read_length
        buf_in[3]-:Following_BME680_Read_Data
        */
        if (buf_in[0] == CP2112_DATA_READ_RESPONS)
        {
        if (buf_in[1] == 0x00 || buf_in[1] == 0x02 || buf_in[1] == 0x03)
        .
        break;
        retry_cnt++; // Busy or Idle or Other
        user_delay_ms(HID_WAIT);
        continue;
        }
        if (buf_in[0] == CP2112_TRANSFER_STATUS_RESP)
        {
        .
        user_delay_ms(HID_WAIT);
        retry_cnt++;
        continue;
        }
        }
        .
        if(buf_in[2] > 0 && rslt > 3 && buf_in[2] < rslt)
        {
        int8_t j = buf_in[2];
        for (int8_t i=0; i < j; i++)
        {
        reg_data[i] = buf_in[i+3];
        }
        return 0;
        }
      • デバック中のバッファ等ダンプ
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        user_i2c_read dev_id: ec reg_addr: d0 reg_data: 04 len: 1
        user_i2c_read()hid_read_timeout rslt:4 retry_cnt:0
        buf_in dump start
        0:13 1:02 2:01 3:61
        buf_in dump end

        user_i2c_read dev_id: ec reg_addr: 89 reg_data: 04 len: 25
        user_i2c_read()hid_read_timeout rslt:28 retry_cnt:0
        buf_in dump start
        0:13 1:02 2:19 3:40 4:a3 5:66 6:03 7:2f 8:80 9:8e 10:c9 11:d6 12:58 13:ff 14:de 15:19 16:cf 17:ff 18:2f 19:1e 20:00 21:00 22:1a 23:f3 24:e7 25:f6 26:1e 27:02
        buf_in dump end
  • 最後に
    ここまで苦労して分かってみれば、案外hidapiからCP2112でI2C素子扱いもMM-CP2112A売り文句マイコンのプログラミング不要でI2C接続のセンサーやGPIO(8ピン)をPCアプリケーションから直接制御できます。を納得出来ない事はないかも、如何でしょう

  • Please check the source code below
    https://github.com/kujiranodanna/BME680_driver

シリアル通信ソフト

シリアル通信ソフトepiconとは

  • epiconはLinuxのシリアル通信ソフトです。

  • 実践IOTハウスでは、Raspberry PiのUSB接続ToCoStick(トコスティック)からシリアル通信でTOCOS TWE-Liteで温湿度計AM2321センサーやAI・DIOを制御に使っています。

  • SwitchやRouterなどシリアルポートでとコンソールPCでConfig設定するネットワーク機器はメーカーや機種を問わず使えると思います。

  • Cisco製SwitchやRouterは設定を自動化する際、事前に作成したテキストデーターをコピー&ペーストして、コンフィグの流し込みを行います。
    この時文字と改行の送出ディレィを行いコンフィグデーターの取りこぼしを防ぐことが重要です。

  • このシリアルコンソールとして重要な文字と改行の送出ディレイをepiconはサポート、コンフィグを安心してコピー&ペーストが出来ます。

  • この他、簡易telnet、zmodemなどのファイル転送ソフト、shell、マクロ、外部ソフトの起動などCUIだが多機能でコンパクトな作りとなっています。

  • インストール
    Download
    https://osdn.net/projects/pepolinux/releases/p3211

    1
    2
    3
    4
    5
    6
    7
    # tar xvfz epicon-XX.XX.tar.gz
    # cd epicon
    # ./configure
    # make
    # make install
    uninstall
    # make uninstall
  • 使い方

    • 起動、オプションなし(com1:/dev/ttys0ポート、9600bps、8bitノンパリティ)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      # epicon

      ** Welcome to epicon Version-5.2 Copyright Isamu Yamauchi compiled:Feb 24 2021 **
      exec shell ~!
      send binary files ~f
      send break ~b
      call rz,sz,sx,rx ~rz,~sz,~sx,~rx
      call kermit ~sk,~rk
      external command ~C
      change speed ~c
      exit ~.
      Connected /dev/ttyS0
    • 終了方法
      Enter~.
    • 通信状態->shellへ->コマンド入力->exitで元の通信状態に戻る
      Enter~!
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
        epicon wait
      # ls
      AUTHORS README configure.ac install-sh
      COPYING aclocal.m4 depcomp missing
      ChangeLog autom4te.cache epicon.c patch-gkermit1.0+counter-CentOS4.2
      INSTALL config.h epicon.h patch-gkermit1.0+counter1.2.1
      Makefile.am config.h.in epicon.nr sample.scr
      Makefile.in config.status epicon_main.c stamp-h1
      NEWS configure epicon_uty.c
      # exit
      epicon run
    • Switchの設定、オプションあり(/dev/ttyUSB0,19200bps,キャラクタディレイ:30ms,CRディレイ:50ms)大昔の経験で、これ位のディレイを設定するとコンフィグの取りこぼしが起こらない。
      1
      # epicon -d 30 -D 50 -s 19200 -l /dev/ttyUSB0
    • Switchの設定、オプションあり(telnet,キャラクタディレイ:20ms,CRデレイ:50ms)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      # epicon -d 20 -D 50 -n 192.168.0.1:23

      ** Welcome to epicon Version-5.2 Copyright Isamu Yamauchi compiled:Feb 24 2021 **
      exec shell ~!
      send binary files ~f
      send break ~b
      call rz,sz,sx,rx ~rz,~sz,~sx,~rx
      call kermit ~sk,~rk
      external command ~C
      change speed ~c
      exit ~.

      Telnet Server 1.10 All rights reserved.


      login :
    • “-c”オプション:外部スクリプトの指定
      • mono-wireless無線モジュールTWELITEとMONOSTICKで温湿度計AM2321センサー、アナログ入力、デジタル入出力信号を離れた場所から遠隔監視・制御がするプログラム pepotocsctlで使用しています。twelite_dip_monostick
      • 以下は、AM2321センサーから温湿度を読み取るスクリプトを作成してepiconを起動します。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        # /usr/local/bin/epicon -s 115200 -ql /dev/ttyUSBTWE-Lite -c $CMD
        # cat $CMD
        #!/bin/bash
        RETRY=5
        I2CRD="-1"
        while [ ${RETRY} -ne 0 ];do
        retry_time=`echo -en $RANDOM |cut -c 1-2`
        echo -en ":7888AA015C0000X\r\n"
        msleep 50
        read -s -t 1 I2CRD || I2CRD="-1"
        echo -en ":7888AA015C03020004X\r\n"
        msleep 50
        read -s -t 1 I2CRD || I2CRD="-1"
        msleep
        echo -en ":7888AA025C0006X\r\n"
        msleep 50
        read -s -n 28 -t 1 I2CRD || I2CRD="-1"
        TMP=`echo -en ${I2CRD} | wc -c`
        [ ${TMP} -eq 28 ] && break
        RETRY=$((${RETRY} - 1))
        [ ${RETRY} -eq 0 ] && break
        RETRY=$((${RETRY} - 1))
        msleep $retry_time
        I2CRD="-1"
        done
        echo -en ${I2CRD} >/dev/stderr
  • マニュアル抜粋

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    # man epicon

    epicon(1) epicon Manuals

    NAME
    epicon is Easy Personal Interface Console terminal software. First I
    am sorry. Because my English linguistic power is very shabby, this sen‐
    tence is being translated by the machine. Because of that, read it in
    the interpretation which it is tolerant of though it thinks that it is
    a little funny translation.

    SYNOPSIS
    usage:
    epicon [-options [argument] [-options [argument]]
    [-b ] <--escape cannot be used
    [-c external_command]
    [-d send_charcacter_delay(ms)]
    [-D send_CR_delay(ms)]
    [-e escape_char]
    [-f send_file]
    [-F send_file_effective_delay]
    [-m ] <--input echo mode
    [-M ] <--line mode
    [-l com_port]
    [-L output_log_file]
    [-n ip_address[:port]]
    [-p [server_port]]
    [-q ] <--quiet mode
    [-s speed]
    [-v ] <--show version
    [-x bit_length (5|6|7) parity(o|e|n) stop_bit (1|2)]
    [-z ] <--auto rz prohibition

    defaults:
    speed: 9600b/s (Higest of 460800)
  • Please check the source code below
    https://github.com/kujiranodanna/IOT-House/tree/master/raspberrypi/usr/src/epicon