楠川技研

楠川の技術研究

土偶どっち(ステッピングモーターをNode-REDで動かそう)

ビジュアルプログラミングIoTLT vol6で「土偶どっち」を発表してきました。

ビジュアルプログラミングはNode-RED以外使ったことがなかったんだけど、色々なビジュアルプログラミングの使い方などが見れて興味深かった。

 

 

Node-REDソース

[{"id":"35dd822b.d4c34e","type":"tab","label":"土偶どっち","disabled":false,"info":""},{"id":"557614e9.2da12c","type":"exec","z":"35dd822b.d4c34e","command":"python /home/pi/Desktop/stepMotorSample2.py","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":450,"y":640,"wires":[["61010ffe.33d3d"],,]},{"id":"e9bf5f12.4033c","type":"switch","z":"35dd822b.d4c34e","name":"晴れか曇りは1、それ以外は2へ","property":"payload.id","propertyType":"msg","rules":[{"t":"gte","v":"800","vt":"num"},{"t":"lt","v":"800","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":370,"y":460,"wires":[["7e5e343c.fdea0c"],["6e5fd1e4.9dca9"]]},{"id":"dc26563.091f1a8","type":"inject","z":"35dd822b.d4c34e","name":"3時間ごとに実行","props":[{"p":"payload.id","v":"100","vt":"num"}],"repeat":"10800","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":150,"y":280,"wires":"3431651b.418f0a"},{"id":"82679ecc.b3456","type":"change","z":"35dd822b.d4c34e","name":"現在位置保存","rules":[{"t":"set","p":"genzai_ichi","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":640,"wires":[]},{"id":"e207bedb.61fd4","type":"change","z":"35dd822b.d4c34e","name":"python用引数生成","rules":[{"t":"set","p":"payload","pt":"msg","to":"JIKU IDOU","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"JIKU","fromt":"str","to":"jiku","tot":"flow"},{"t":"change","p":"payload","pt":"msg","from":"IDOU","fromt":"str","to":"idou","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":460,"wires":[["557614e9.2da12c"]]},{"id":"7e5e343c.fdea0c","type":"function","z":"35dd822b.d4c34e","name":"1. 位置:0 までの移動量計算","func":"idou = 0 - flow.get(\"genzai_ichi\");\nflow.set(\"idou\",idou);\nmsg.payload = idou;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":440,"wires":[["e207bedb.61fd4"]]},{"id":"6e5fd1e4.9dca9","type":"function","z":"35dd822b.d4c34e","name":"2. 位置:12800 までの移動量計算","func":"idou = 12800 - flow.get(\"genzai_ichi\");\nflow.set(\"idou\",idou);\nmsg.payload = idou;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":670,"y":480,"wires":[["e207bedb.61fd4"]]},{"id":"4059629.04f239c","type":"change","z":"35dd822b.d4c34e","name":"選択モーター","rules":[{"t":"set","p":"jiku","pt":"flow","to":"0","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":300,"y":160,"wires":[]},{"id":"12f196f2.44d689","type":"inject","z":"35dd822b.d4c34e","name":"初期化","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":110,"y":80,"wires":"abfa4f7a.708f6","4059629.04f239c","4ca5f233.debeac"},{"id":"abfa4f7a.708f6","type":"change","z":"35dd822b.d4c34e","name":"移動量","rules":[{"t":"set","p":"idou","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":120,"wires":[]},{"id":"61010ffe.33d3d","type":"function","z":"35dd822b.d4c34e","name":"現在位置確認","func":"msg.payload = Number(msg.payload) + flow.get(\"genzai_ichi\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":760,"y":640,"wires":[["82679ecc.b3456"]]},{"id":"4ca5f233.debeac","type":"change","z":"35dd822b.d4c34e","name":"現在位置","rules":[{"t":"set","p":"genzai_ichi","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":80,"wires":[]},{"id":"3431651b.418f0a","type":"openweathermap","z":"35dd822b.d4c34e","name":"福岡天気は?","wtype":"current","lon":"","lat":"","city":"Fukuoka","country":"Japan","language":"ja","x":380,"y":280,"wires":"e9bf5f12.4033c"},{"id":"b7e3d0c7.20176","type":"comment","z":"35dd822b.d4c34e","name":"OpenWeatherMap API使用 (node-red-node-openweathermap)","info":"","x":680,"y":260,"wires":},{"id":"737ef72d.d1b998","type":"comment","z":"35dd822b.d4c34e","name":"モーター動作フロー","info":"","x":110,"y":240,"wires":},{"id":"30471443.42d75c","type":"comment","z":"35dd822b.d4c34e","name":"初期化フロー","info":"","x":90,"y":40,"wires":},{"id":"85f084ad.569638","type":"comment","z":"35dd822b.d4c34e","name":"flow.genzai_ichi セット","info":"","x":500,"y":80,"wires":},{"id":"ce9becce.b38bb","type":"comment","z":"35dd822b.d4c34e","name":"flow.idou セット","info":"","x":480,"y":120,"wires":},{"id":"9ef94495.583118","type":"comment","z":"35dd822b.d4c34e","name":"flow.jiku セット","info":"","x":480,"y":160,"wires":},{"id":"b5be87fb.632e48","type":"comment","z":"35dd822b.d4c34e","name":"flow.idou セット","info":"","x":640,"y":400,"wires":},{"id":"7893fe48.2f97c","type":"comment","z":"35dd822b.d4c34e","name":"flow.genzai_ichi 使用","info":"","x":650,"y":360,"wires":},{"id":"27a93e4e.2daf22","type":"comment","z":"35dd822b.d4c34e","name":"flow.idou 使用","info":"","x":930,"y":420,"wires":},{"id":"50cc1fb4.837eb","type":"comment","z":"35dd822b.d4c34e","name":"flow.jiku 使用","info":"","x":930,"y":380,"wires":},{"id":"1749d6c4.806ab9","type":"comment","z":"35dd822b.d4c34e","name":"flow.genzai_ichi 使用","info":"","x":770,"y":600,"wires":},{"id":"bf0f55eb.30fdd8","type":"comment","z":"35dd822b.d4c34e","name":"flow.genzai_ichi セット","info":"","x":980,"y":600,"wires":},{"id":"de712fa1.98495","type":"inject","z":"35dd822b.d4c34e","name":"即実行","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":320,"wires":"3431651b.418f0a"},{"id":"bd1a204b.edef4","type":"inject","z":"35dd822b.d4c34e","name":"晴れ","props":[{"p":"payload.id","v":"800","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":400,"wires":"e9bf5f12.4033c"},{"id":"744aa74a.75a5c8","type":"inject","z":"35dd822b.d4c34e","name":"雨","props":[{"p":"payload.id","v":"200","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":440,"wires":"e9bf5f12.4033c"}]

 

Pythonソース

 

# -*- coding: utf-8 -*-

import time

import sys

import MD6470 as MD

 

def stopStat(timeOut):

    sTime = time.time()

    while True:

        try:

            statMD = (MD.getStatus(0)) #1軸のみに変更

            if not(statMD & 0x0060):        # if both motor STOP, exit

                sStat = True

                break

            elif time.time() - sTime > timeOut:

                sStat = False

                break

        except KeyboardInterrupt:

            sStat = False

            break

    return sStat

 

def main():

    MD.open()        # ドライバー設定

    MD.resetDevice(2)    # 初期化

    time.sleep(0.1)

    MD.setKval(2, 0x60, 0xB4, 0xB4, 0xB4)    # トルクコントロールパラメーター設定

    MD.setMoveVal(2, 0x1A, 0x1A, 0x14, 0x00, 0x027)    #モーションパラメータ設定

 

    MD.goToAbsPos(int(sys.argv[1]), int(sys.argv[2])) #動作モータと移動量を指定

#    MD.goToAbsPos(0, 12800)

    if stopStat(5.0):

    time.sleep(0.1)

 

#    print (MD.readAbsPos(0))# , end="")

#    sys.stdout.write (MD.readAbsPos(0))

    sys.stdout.write ("%s" % MD.readAbsPos(0)) #現在位置の読み出し

 

    MD.close()    # ドライバーの設定解除

    

if __name__ == '__main__':

    main()