2015年9月4日金曜日

mongoDB/mongoose

自宅のNATの内側から、さくらVPSのnode.js上のサーバーまでsecure websocket serverが開通したので気温や湿度、コマンドのやりとりや各種センサーの情報を記録するデータベースを設定していきます。
MEANスタックというのが流行りのようなので、mongoDBを使ってみることにしました。
node.js上のアクセスはmongooseを使用しています。
素人が書くよりも色々ネット上に書いてくれている情報があるのでインストール方法とかは省略します。
mongooseはSchemaを設定してアクセスするようなので、最初にどういうデータで格納していくかを考えていきます。
まず、定期的に測定する気温や湿度などのセンサー情報と何かスイッチ等をon/offした時などのタイミングで上がってくるイベントの最新情報のみを記録するためのStatusSchemaを考えます。これはLogとは別に最新データを素早くアクセスするために記録します。
情報としては接続先のclientID、センサー名称、センサーの値、更新時のTimeStampです。

var StatusSchema = new mongoose.Schema({
  client: {type:String, required: true},
  sensor: {type:String, required: true},
  value: {type:String, required: true},
  update: {type:Date, default:Date.now}
});
var Status = db.model('status', StatusSchema);

次にデバイスの最新情報を取得して保持しておくためのDeviceInfoSchemaです。
記録する情報は接続先のclientID、デバイス名称、デバイスタイプ、ZigBeeアドレス下位32bit、デバイスの機能情報、バージョン、電源電圧、デバイス状態、更新時のTimeStampです。
var DeviceInfoSchema = new mongoose.Schema({
  client: {type:String, required: true},
  device: {type:String, required: true},
  type: {type:String, required: true},
  addrL: {type:String, required: true},
  func: {type:String, required: true},
  version: {type:String, required: true},
  voltage: {type:String, required: true},
  state: {type:String, required: true},
  update: {type:Date, default:Date.now}
});
var DeviceInfo = db.model('deviceInfo', DeviceInfoSchema);

次は全ての変化の記録を記録していくLogSchemaです。
ここには接続先のclientID、情報のタイプ、データベースを検索する時に情報粒度を落とすためにつける分解能フラグ、更新時のTimeStamp、データ本体です。
データ本体はコマンド、レスポンス、ステータスなどのメッセージobjectです。
var LogSchema = new mongoose.Schema({
  client: {type:String, required: true},
  type: {type:String, required: true},
  fine: {type:Boolean, required: false},
  timeStamp: {type:Date, default:Date.now},
  data: mongoose.Schema.Types.Mixed
});
var Log = db.model('log', LogSchema);

最後にclientごとのUIを定義するためのClientUISchemaです。
これは制御する機器のコマンドとUIの表記を記述したテーブルを記録しています。
var ClientUiSchema = new mongoose.Schema({
  client: {type:String, required: true},
  clientUi: mongoose.Schema.Types.Mixed
});
var ClientUi = db.model('client_ui', ClientUiSchema);

長くなってきたのでUIのテーブルについては次回にします。

2015年8月28日金曜日

node.jsとwebsocket

node.js自体のinstall方法は色々な方が書かれているのでここでは飛ばします。
今回はさくらVPS上でubuntu14.04LTSでサーバーを運用しています。

javascript初心者なので何かとつまらないところで躓いてますが、なんとか通信が動くようになりました。

最初にhttpsで接続し、upgradeでwebsocketに切り替える動作になるので、サーバー認証、クライアント認証はhttps接続時に行います。
最初に躓いたのは、自己認証局の証明書(いわゆるオレオレ証明書です)でMacのSafari(8.0.8)からwebsocketに接続しようとすると接続がハネられてしまうことに気が付かなかったため数日間悩みました。Chromeで接続するとちゃんと接続できたので、Safariの仕様のようです。wiresharkでみてみるとサーバー側からはリクエストが出ていますがSafariからクライアント証明書を送っていないようです。
最終的にはSafariではなくRaspberryPi上の自作プログラムから接続するので、このまま進めます。

最初に必要なモジュールを読み込みます。
var WebSocketServer = require('ws').Server;
var https = require('https');
var fs = require('fs');

後で変更しそうな設定値を記述したconfigファイルを用意して読み込みます。
var config = require('./config');

httpsのセキュリティ条件をoptsで設定します。
  var opts = {
    key: fs.readFileSync(config.keyFile),
    cert: fs.readFileSync(config.certFile),
    ca: fs.readFileSync(config.caFile),
    ciphers: "ALL:!EXP:!ADH:!LOW:!SSLv2:!SSLv3:!DES:!3DES:!RC4",
    honorCipherOrder: true,
    secureProtocol: "TLSv1_2_method",
    requestCert: true,
    rejectUnauthorized: true
  };

クライアント認証をするには最後のrejectUnauthorized:trueが必要です。
これがないとやりとりはするけど認証されてない相手でも通信を許してしまいます。
あとdebug時にwiresharkで暗号通信の中身を確認したい場合はciphers:の先頭のALL:をkRSA:にする必要があります。これをしないと暗号が解けないので中身が見えません。

  // connect from house controller
  var houseControllerServer = https.createServer(opts);
  var wss = new WebSocketServer({server:houseControllerServer});
  var houseControllerConnections = [];

  houseControllerServer.listen(config.houseControllerPort, function() {
    console.log("house controller listing on port %d", config.houseControllerPort);
  });
指定されたportでアクセスが来るのを待ちます。

  wss.on('connection', function (ws) {
    // connectionイベントの処理
    console.log('connect from house controller');
    houseControllerConnections.push(ws); // 接続先を記録しておきます。
  // ここにwebsocket接続時の処理を追加します。

    ws.on('close', function () {
      // closeイベントの処理
      console.log('disconnect from hosue controller');
      // closeする接続先を記録から除いています。
      houseControllerConnections = houseControllerConnections.filter(function (conn, i) {
        return (conn === ws) ? false : true;
      });
     // ここにdisconnect時の処理を追加します。
    });

    ws.on('message', function (message) {
      // mesageイベントの受信処理
      var OU = ws._socket.getPeerCertificate().subject.OU;
      var msg = JSON.parse(message);
      // ここに通信相手からのメッセージの処理を追加します。
      console.log(msg);
    });
  });

  //送信はイベント処理ではないのでfunctionです。
  function sendWebsocket(message) {
    houseControllerConnections.forEach(function (con, i) {
      // 登録されている通信相手にメッセージを送信します。
      con.send(JSON.stringify(message));
    });
  }

以上で接続、終了、受信、送信の処理となります。


2015年8月21日金曜日

websocket

これまでは自宅のNAT内のRaspberryPiのホームコントロールシステムを外からアクセス出来るようにするためにNAT内から外のサーバーに対してTLSでsocketを1本通しておいて、外部サーバーの443portにアクセスしてきたものをclient認証をした後にTLSを逆流させてRaspberryPiのapache2に繋ぐという仕組みを作って運用していました。
これはこれで簡単でいいのですが、apache2をRaspberryPiで運用していたのでどうしても重たくなっていました。
少し世間一般的な解決方法を取り入れようと考えて、色々と最近の流行を調べたりしているのですが、webの世界はフレームワークの標準とかの変化が激しすぎてなかなかついていけません。とりあえず始めないと始まらないので、まずは手始めにサーバーサイドをnode.jsにしてRaspberryPi上のホームコントロールサーバーにwebsocketのプロトコルを話せるような機能を追加してみました。
websocketはwikipediaの説明を読めば大体理解できたので対向のwebsocketサーバーにnode.jsのサンプルプログラムを利用してそのままTLS化して繋いで動作確認をしていきます。
まだ他の部分が安定して動作してないので安定してきたら公開しようかと思います。
最終的にはセンサー、HAコントロール、etcの機能をESP8266を使ったWiFiモジュールで実現し、RaspberryPi2上のホームコントロールサーバーで情報集約してsecure websocketでNAT越しにさくらVPSで借りているサーバー上のnode.jsに接続、そこからiPhone上のWebAppに繋ぐということを実現しようかと考えています。
まだjavascriptを勉強し始めたところなので道のりが長そうですが........

2015年8月14日金曜日

OS-XでESP8266開発環境その2

前回作ったSDKの環境でbuildしていきます。
# cd ~/ESP8266/esp_iot_sdk_v1.2.0
# cp -r examples/at/ .
# cd at
scriptの属性を実行可能に修正
# chmod +x gen_misc.sh
# ./gen_misc.sh
gen_misc.sh version 20150511

Please follow below steps(1-5) to generate specific bin(s):
STEP 1: choose boot version(0=boot_v1.1, 1=boot_v1.2+, 2=none)
enter(0/1/2, default 2):
1 <---最初にfirmware updateで使用したイメージと同じものを選択
boot mode: new

STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)
enter (0/1/2, default 0):
1 <---ここも最初にfirmware updateで使用したイメージと同じものを選択
generate bin: user1.bin

STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)
enter (0/1/2/3, default 2):
2 <---defaultを選択
spi speed: 40 MHz

STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
enter (0/1/2/3, default 0):
0 <---defaultを選択
spi mode: QIO

STEP 5: choose spi size and map
    0= 512KB( 256KB+ 256KB)
    2=1024KB( 512KB+ 512KB)
    3=2048KB( 512KB+ 512KB)
    4=4096KB( 512KB+ 512KB)
    5=2048KB(1024KB+1024KB)
    6=4096KB(1024KB+1024KB)
enter (0/2/3/4/5/6, default 0):
2 <---ここも最初にfirmware updateで使用したイメージと同じものを選択
spi size: 1024KB
spi ota map:  512KB + 512KB


start...

DEPEND: xtensa-lx106-elf-gcc -M -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -DICACHE_FLASH -DAT_UPGRADE_SUPPORT -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle user_main.c
xtensa-lx106-elf-gcc -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections  -DICACHE_FLASH -DAT_UPGRADE_SUPPORT   -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle  -o .output/eagle/debug/obj/user_main.o -c user_main.c
xtensa-lx106-elf-ar ru .output/eagle/debug/lib/libuser.a .output/eagle/debug/obj/user_main.o 
xtensa-lx106-elf-gcc  -L../lib -nostdlib -T../ld/eagle.app.v6.new.1024.app1.ld -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain -ljson -lupgrade -lsmartconfig user/.output/eagle/debug/lib/libuser.a -lat -Wl,--end-group -o .output/eagle/debug/image/eagle.app.v6.out 

!!!
Support boot_v1.2 and +
Generate user1.1024.new.2.bin successully in folder bin/upgrade.
boot.bin------------>0x00000
user1.1024.new.2.bin--->0x01000
!!!

これで../bin/upgradeに
user1.4096.new.4.S 逆アセンブルコード
user1.4096.new.4.bin 書き込みイメージ
user1.4096.new.4.dump シンボル情報
が出来上がります。

# cd ../bin

基板のIO0のスイッチをUART書き込み側に倒してリセットします。

# esptool.py -p /dev/cu.usbserial-A101JG84 write_flash -fs 32m 0x00000 boot_v1.4\(b1\).bin 0x1000 upgrade/user1.1024.new.2.bin                                   
Connecting...
Erasing flash...
Writing at 0x00000800... (100 %)
Erasing flash...
Writing at 0x00040800... (100 %)

Leaving...

基板のIO0のスイッチを通常モードに戻してリセットします。
# jerm -b 115200 -r rntn /dev/cu.usbserial-A101JG84
を起動してATコマンドでバージョンを確認
AT+GMR
AT version:0.30.0.0(Jul  3 2015 19:35:49)
SDK version:1.2.0
compile time:Jul 25 2015 10:44:06
OK
ちゃんと更新されて動いているようです。

2015年8月7日金曜日

OS-XでESP8266開発環境その1

ともの技術メモさんを参考にArduinoIDE ESP8266の環境をinstallします。
linux版ですが非常にわかりやすく書いてくれています。
OS-Xでもほぼ同じ手順で行けます。

以下はOS-X yosemiteでの環境構築です。

Arduino IDE for ESP8266
のInstalling with Boards Managerに書かれているとおりの手順です。

Aruduino website
からARDUINO 1.6.5のMac OS X 10.7 Lion or newerをdownloadします。
ダウンロードしたzipファイルをダブルクリックして開くとArudiono.appが展開されます。
Arudiono.appをApplicationフォルダにコピーし、ファイルを右クリックで開きます。
メニューバーのArudino->Preferences...を開きます。
Additional Boards Manager URLs:に
    http://arduino.esp8266.com/package_esp8266com_index.json
を設定しOKボタンを押してPreferences...を閉じます。
メニューバーのツール->ボード->Board Manager..を開きます。
一番下にesp8266 by ESP8266 Communiyというものがあるので選択し、Installボタンを押します。
ダウンロードが完了したら閉じて、Aruduinoを終了します。

~/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9/
にxtensa-lx106のツール一式が出来上がっています。
このままでもいいのですが、diretoryが深すぎて使いにくいので
# cp -pr ~/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9 /usr/local/ESP8266
とします。(このへんは好みの問題です)
shellのPATH設定に/usr/local/ESP8266/binを追加します。

次にBRILLIANTSERVICE TECHNICAL BLOGさんを参考にESP8266のSDKとツール等を展開するためのdirectoryを掘ります。
まずは最新firmwareをbuild出来る環境を作って確認していきます。

# mkdir ~/ESP8266
# cd ~/ESP8266
# curl -o esp_iot_sdk_v1.2.0_15_07_03.zip https://raw.githubusercontent.com/esp8266/esp8266-wiki/master/sdk/esp_iot_sdk_v1.2.0_15_07_03.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11.7M  100 11.7M    0     0  2088k      0  0:00:05  0:00:05 --:--:-- 2992k
# unzip esp_iot_sdk_v1.2.0_15_07_03.zip
Archive:  esp_iot_sdk_v1.2.0_15_07_03.zip
..............
  inflating: release_note.txt  

buildに必要なincludeファイルを入れます。
# curl -o includes.tgz https://raw.githubusercontent.com/esp8266/esp8266-wiki/master/include.tgz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  956k  100  956k    0     0   316k      0  0:00:03  0:00:03 --:--:--  316k
# cd esp_iot_sdk_v1.2.0
# tar zxvf ../includes.tgz
x include/
..........
x include/wctype.h

libc.a,libhal.aを入れます。
# curl -o lib/libc.a https://raw.githubusercontent.com/esp8266/esp8266-wiki/master/libs/libc.a
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 2689k  100 2689k    0     0   854k      0  0:00:03  0:00:03 --:--:--  854k
# curl -o lib/libhal.a https://raw.githubusercontent.com/esp8266/esp8266-wiki/master/libs/libhal.a
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  339k  100  339k    0     0   593k      0 --:--:-- --:--:-- --:--:--  594k

書き込みのためのツールを入れます。
# cd ..
#  git clone https://github.com/themadinventor/esptool esptool-py 
Cloning into 'esptool-py'...
remote: Counting objects: 192, done.
remote: Total 192 (delta 0), reused 0 (delta 0), pack-reused 192
Receiving objects: 100% (192/192), 66.80 KiB | 0 bytes/s, done.
Resolving deltas: 100% (93/93), done.
Checking connectivity... done.
# cd esptool-py 
# python setup.py install
running install
.......
Installing esptool.py script to /usr/local/bin
......
Finished processing dependencies for esptool==0.1.0
# cd ..

ここまででbuild出来る環境が出来上がりました。
次回は実際にbuildして書き込んで確認します。

2015年7月31日金曜日

ESP-WROOM-02 WiFiモジュール firmware update

OS-X環境でESP-WROOM-02のfirmware version upをしようとしてちょっとハマったのでメモ。

最初に基板の改造です。
UART書き込み出来るようにIO0に切り替えスイッチを追加(pull-upしてあるのでGNDとショートするスイッチを追加)


上に出ているコネクタはUARTの通信を横から監視するためのdebug用コネクタです。

まず、書き込みツールのinstall
# git clone https://github.com/themadinventor/esptool.git
# cd esptool
# python setup.py install

次にfirmwareのイメージの準備
ESPRESSOのDownload BSSのTOPICSの中から最新のESP8266 SDKを選択
今回はESP8266 SDK (esp_iot_sdk_v1.2.0_mesh_v0.0.6_15_07_03)にAttachされている
esp_iot_sdk_v1.2.0_mesh_v0.0.6_15_07_03.zip
をダウンロードして解凍し、firmwareのイメージがあるdirectoryに移動
# cd esp_iot_sdk_v1/esp_iot_sdk_v1.2.0/bin

モジュールのIO0をLowに落としてリセットしUART書き込みモードに切り替えます。

最初に間違えて消してしまった時のためにMACアドレスを確認しておきます。
# esptool.py -p /dev/cu.usbserial-A101JG84 read_mac
Connecting...
MAC: xx:xx:xx:xx:xx:xx

次にイメージを書き込みます。
最初のときは
# esptool.py -p /dev/cu.usbserial-A101JG84 write_flash 0xfe000 blank.bin 0x00000 boot_v1.4\(b1\).bin 0x1000 at/user1.1024.new.2.bin 0xfc000 esp_init_data_default.bin
とやったら書き込みは完了したのですが、通常モードにして起動してuart terminalからアクセスするとゴミを大量に吐きまくってる状態になってしまいました。

これの解析のためにdebug用のコネクタを追加してUARTの通信をのぞいて色々調べてみると送信しているheaderの中のflash_size指定のbitが4Mbitになっているのがうまく書き込めていない原因のようです。これの解析に4〜5時間かかってしまいました。

esptoolのhelpをみるとwrite_flash用のoptionがあるようで
# esptool.py write_flash --help
で-ff -fm -fsのオプションをみつけて指定したところうまくいきました。

# esptool.py -p /dev/cu.usbserial-A101JG84 write_flash -ff 40m -fm qio -fs 32m 0xfe000 blank.bin 0x00000 boot_v1.4\(b1\).bin 0x1000 at/user1.1024.new.2.bin 0xfc000 esp_init_data_default.bin

Connecting...
Erasing flash...
Writing at 0x000fec00... (100 %)
Erasing flash...
Writing at 0x00000800... (100 %)
Erasing flash...
Writing at 0x00040c00... (100 %)
Erasing flash...
Writing at 0x000fc000... (100 %)

Leaving...

モジュールのIO0をHighに戻してリセットし通常モードにします。
terminalを接続しVersionを確認すると
AT+GMR
AT version:0.30.0.0(Jul  3 2015 19:35:49)
SDK version:1.2.0
compile time:Jul  3 2015 20:52:32
OK

無事Version upされてます。

2015年7月24日金曜日

ESP-WROOM-02 WiFiモジュール

Cerevoから発売された技適対応のWiFiモジュールが安いので買おうと思っていたら、あっという間に売り切れてしまいました。
暫く入荷待ちするつもりでいたら数日後にスイッチサイエンスからも予約販売されたのですかさず注文してみました。モジュール単体でも普通にハンダ付け出来そうですが、一応変換基板付きも一緒に購入しました。

IEEE802.11b/g/n対応で技適対応で710円+消費税は格安です。XBeeよりも千円くらい安くてWiFi接続できるのは魅力的ですね。WPA2対応のようですし、家電制御に使うにはこんなものかと思います。


入荷予定日に発送しましたとの通知が来て翌日届いたので、秋月のUSB-UARTモジュールと接続しました。


今週は組み立てただけで、ちょっと忙しくてまだ火入れできていません。
動かしたらどんな感じかレポートします。

2015年7月17日金曜日

DAIKINエアコンのコントロール

自宅ではないのですが、ダイキンのエアコンにHA2moduleを接続しました。機種はS22STES-Wです。
HA端子対応と聞いていたので簡単につながるかと思いましたが、色々と大変でした。
現地でカバーを開けて基板を確認してみましたが、どこにもHA端子らしいものが見当たりません。




ネットでカタログとか色々調べてみると、どうも別売りの基板が必要でそれなりの値段です。
エアコンの電源の状態を取るためにはHA端子が必要なのですがそのために基板を購入するのは勿体無いので、statusを取れそうなところを探してみました。
メイン基板上のコネクタなどをテスターであたりながら電源をon/offして変化するかを確認していきますが適当な信号が見当たりません。今回は自分のものではないので基板にハンダ付けとかで線を引き出すわけには行きません。
混み合っているところなので線を引き出すのが大変そうなのですが、結局on/offの表示LEDとSWや赤外線リモコンの受光部の載っている基板から取ることにしました。




基板のパターンを追いながら回路図(下の回路の黒線部分)にしていきます。
動作中の電圧をみながら動作を想定して、HA2moduleのHA端子のフォトカプラに繋ぐ回路を追加。
LED基板側の10pinコネクタを外してコネクタの種類を確認します。
形状からJSTのPHコネクタのようですので、オス・メスのコネクタを用意して中継する途中から信号を横取りすればいけそうです。(下の回路の赤線部分)



運転LEDは13.7Vの電源からLEDをとおして1.8kΩの抵抗の先で多分Trでon/offされるようです。
このLEDと並列にフォトカプラのLEDに2Kの抵抗を介して接続します。
HA2moduleのHA端子の制御側もフォトカプラのTrなのでon/off出来るSWのところに噛ませます。
これで通常のHA制御と同様の機能が実現できます。
ちょっと判りにくいですが、元々のPHコネクタの先に延長ハーネスを追加して途中から信号を取り出しています。
 




これに温度センサーと赤外線発光部をつけてエアコンの内部に収めて出来上がりです。
かなりごちゃごちゃしてますが、なんとか収まりました。


ちゃんとリモコン信号でも制御できて、HA端子側からon/off制御、動作ステータスがとれていることを確認して完成です。


2015年7月10日金曜日

バーチカルブラインドの電動化 その5

仮組みした所はロフトからアクセスが簡単な、目的とは別のブラインドの手動の紐が出ている側ですが、実際に取り付けたい所は簡単にアクセス出来ない吹き抜けの上のブラインドで、手動の紐と両立したいので手動の紐の出ていない側になります。梯子をかけて頑張って取り付けました。




紐の無い側の構造は非常に簡単で、2本の軸をスペーサーと止め輪(丸くて内側に歯がついていて軸に咬むようになっているリング)で止まっているだけなので止め輪を2つ外すことで簡単に取り外せます。写真はカバーと止め輪とスペーサーを外した状態です。

ここにモーター部を取り付けます。上から見るとこんな感じです。



ちょっとごちゃごちゃしていますが吹き抜けのところなので下から4.5mほどあり、それほど気になりません。




実際の動作はこんな感じです。




実験していた側のブラインドが24枚スラットだったのですが、最終的に取り付けた側のブラインドが30枚スラットと増えているのと僅かですが手動用の紐の負荷もあるのでちょっと重そうです。

本当はもう少し強力なモーターの方が良さそうですが、モーターの軸間が20mmなので直径20mm以下のモーターで手頃なものとなるとなかなか選択肢が無いのとGear比をこれ以上高くすると今度は手動で回せなくなりそうなので暫くこれで運用してみようかと思います。





2015年7月3日金曜日

バーチカルブラインドの電動化 その4





モーター電源を9V化しました。
基板も作り替えて3端子レギュレータをmurataのDC-DCコンバータに置き換えました。
これまではモーターを外形を軽く保持する形で構成していたのですが、回転で押されて位置が変動するのでちゃんと固定する形にしました。それに合わせてアクリル板も再設計して基板もカバーする形にしました。


カバー部分を曲げてこうなります。


モーター部分の固定


組み上げたところ


仮組みで取り付けてみたところ


制御ソフトも組んだので、スラットを半分回して全開まで送ってみました。


ちゃんと最後まで動いています。