■配線状況
↓前回記事の際の配線状況
↓今回の配線状況
↑配線がつなぎだらけ。
・PICO2台。上の1台がリニアスライド駆動用、
下の1台が動作検出&mqttへのPUB用。
それぞれ独立して動作します。
・太い銀色のケーブルは5VUSB電源。
・USB-Cメス端子で受け、PICO−WのVSYSに供給。
・同時にフォトインタラプタの発光側にも5Vから1kΩを介して供給。
・フォトインタラプタのドレインをPICOのGPIOに接続。
・PICO2台の信号系統は分離しています。
フォトインタラプタ周りはとくにごちゃごちゃしてしまいました。
↓リニアスライド
↑可動体にアルミ板のドグを設置
↑ドグが溝に適切に入るようにアルミ板を曲げて調整
アルミ板厚0.3mm、AMAZONで手配。
はさみで切り出しができました。
スライド可動体とフォトインタラプタの溝との寸法関係から、
簡単な展開図を先に描いておいて、はさみで切り出し、
ドグになるように曲げ、インタラプタの溝を適切に通過できるように
曲げ角度を調整しました。
一番手前のインタラプタは動作端検出用。
これが遮光されたらスライド動作を停止、反転動作させます。
その向こうのインタラプタは動作状態検出用。
これが遮光されたら動作状態をmqttにて発信します。
↓mqttをpubするPICO-W
↑フォトインタラプタ2個からの信号をGPIO18 と19に接続。
赤い4Pディップスイッチはデバイス識別用ですが、今回未使用です。
↓リニアスライド制御用PICO-Wの配線状況
ロック付きプッシュボタン2個、左がena、右がdir。
これらは前回記事の接続のままで利用。
両端検知用のフォトインタラプタからの信号線をブレッドボード上で
わたり配線しています。
■動作状況
2台のPICO-Wで信号系統がごちゃまぜにすると、
正しく動作しませんでしたので、分離すると良好に動作しました。
1台ずつ動作が良好であることをThonny上で確認したうえで、
USB-CからVSYS電源へつなぎました。
配線が交錯、ブレッドボードへの差し込みが甘く、
配線にふれると無用なオンオフが多発します。
今回はとりあえずの動作確認と割り切っています。
↓mqttのsub(pubされた情報の受信)
mqttのpub/subの動作は十分に速く、IoT用途なら十分に適用できます。
↓動作中のモータドライバ電源出力状況
9.2W程度、モータ表面は概ね室温レベルのままです。
241224補記
・電圧を上下してみました。
24V:動作音が明らかに小さくなりました。電力は12Wまで上がり、
モータがほんのりと暖かくなります。
12V:音は18V時と変わりませんが、電力が4Wまで下がりました。
8.7V:これが電圧下限。動作音も若干低下しました。
電力1.9W、24V時の1/6。負荷が小さいのでこれでも動作します。
241224補記以上
↓無負荷時
■リニアスライド制御コード
# test_linear_slide.py
#制御プログラム(リニアスライドユニット用)
# Linear Sliding length 100mm
# Stepping moter : 2pahse-bipoler NEMA17
# Stepping moter driver : TB6600
# CPU : RaspberryPi PICO-W
# Edit by kabayon date:20241220
# Coding : utf-8
# ライブラリ:micropythonの標準ライブラリのみ
from time import sleep
import time
from machine import Pin , PWM
# set standerd value of signal
signal_high = 1
signal_low = 0
# set GPIO Pin-number
GP00 = 0
GP01 = 1
GP02 = 2
GP03 = 3
GP04 = 4
GP05 = 5
GP18 = 18
GP19 = 19
GP20 = 20
GP21 = 21
# 動作端検出用フォトインタラプタのオブジェクト設定
sw_ena = Pin(GP18, Pin.IN, Pin.PULL_UP)
sw_direction = Pin(GP19, Pin.IN, Pin.PULL_UP)
ls01 = machine.Pin(GP20, Pin.IN, Pin.PULL_UP)
ls02 = machine.Pin(GP21, Pin.IN, Pin.PULL_UP)
# Stepping motor driverへ信号出力するピンのオブジェクト設定
pin_pulse = Pin(GP02, Pin.OUT)
pin_direction = Pin(GP03, Pin.OUT)
pin_ena = Pin(GP04, Pin.OUT)
# ■TB6600ドライバ信号初期値
# DIR = HIGHで正転、DIR = LOWで逆転。
# status_direction = signal_high
# ENA = HIGHでトルク発生、ENA = LOWでトルクフリー
# status_ena = signal_high
# ■基本動作パラメータ設定
# ボールねじピッチ長さ(mm単位)
length_lead = 4
# 減速比を設定。モータ単体ならば1
ratio_gear = 1
# 1mm移動時のモータ主軸の総回転数設定
length_drive_1mm = 1
num_rotate_1mm = ratio_gear * length_drive_1mm / length_lead
# 1mm移動時のパルス数
num_pulse_1rotation = 1600
num_pulse_1mm = int( num_rotate_1mm * num_pulse_1rotation )
# パルス幅を秒単位で指定。値を小さくする程高速で回転する。
width_pulse = 0.0005
# ■動作繰り返し
time_stop_ls01=2
time_stop_ls02=2
dir_up=1
dir_down=0
status_dir = dir_up
while True:
status_sw_ena = sw_ena.value()
#time.sleep(0.5)
# 移動長さ
length_drive = 95
# 移動パルス数
count_pulse = length_drive * num_pulse_1mm
print("num_pulse_1mm ",num_pulse_1mm,"count pulse ",count_pulse)
#time.sleep(1)
print("start driving")
status_ls01 = ls01.value()
status_ls02 = ls02.value()
print("ls01:",status_ls01,"ls02:",status_ls02)
if status_ls01==1:
status_dir = dir_up
elif status_ls02==1:
status_dir = dir_down
pin_direction.value(status_dir)
for j in range( 0 , count_pulse ):
pin_ena.value( sw_ena.value() )
status_ls01 = ls01.value()
status_ls02 = ls02.value()
if status_ls01==1 and status_dir==dir_down:
pin_ena.value(0)
j=count_pulse
time.sleep( time_stop_ls01 )
status_dir = dir_up
pin_direction.value(status_dir)
if status_ls02==1 and status_dir==dir_up:
pin_ena.value(0)
j=count_pulse
time.sleep( time_stop_ls02 )
status_dir = dir_down
pin_direction.value(status_dir)
else:
pin_pulse.value( signal_low )
time.sleep( width_pulse )
pin_pulse.value( signal_high )
time.sleep( width_pulse )
■mqtt制御プログラム(機械動作IoT用)
# test_mqttwithPI.py
#制御プログラム(機械動作IoT用)
# photo intrupter
# CPU : RaspberryPi PICO-W
# Edit by kabayon date:20241221
# Coding : utf-8
# ライブラリ:標準ライブラリ
import time
from machine import Pin
import machine
import sys
# ライブラリ:networkライブラリ
import network
from umqtt.simple import MQTTClient
# set GPIO Pin-number
GP18 = 18
GP19 = 19
# Wi-Fi接続function
def connect():
# 自分の固定IPアドレス設定
IPaddress_mine = '192.168.10.81'
# Wifi起動
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Wifi接続
wlan.connect(ssid, password)
while wlan.isconnected() == False:
print('Waiting for connection...')
time.sleep(1)
wlan_status = wlan.ifconfig()
wlan.ifconfig((IPaddress_mine, wlan_status[1], wlan_status[2], wlan_status[3]))
ip = wlan.ifconfig()[0]
print(f'Connected on {ip}')
return ip
# Subメッセージ表示function
def printMessage(topic, message):
# 受信データをytes型からUTF-8文字列へ変換、標準出力表示
print("topic:" + topic.decode("utf-8") )
print("message:" + message.decode("utf-8") )
# メインルーチンーーーーーーーーーーーーーーーーーーーーーー
# LED制御値設定
on_led = 1
off_led = 0
time_on_led = 0.5
# Wi-Fi接続SSID、パスワード設定
ssid = 'kabanet24'
password = 'kabanet24'
# MQTTブローカーサーバーIP設定
address_kaban5105 = '192.168.10.32'
mqttBroker = address_kaban5105
# ConnectID(ユニーク)設定
myId = 'rpp01'
# トピック(構造化)設定
topic= b"test_mqtt/rpp01"
# メッセージヘッダー設定
msg_header = "rpp01 send "
# 接続維持時間設定
time_keepalive_MQTTClient = 3600
# LEDオブジェクト定義
led_rpp = machine.Pin("LED",machine.Pin.OUT)
# 初動LED点滅&オフ
led_rpp.value(on_led)
time.sleep(time_on_led)
led_rpp.value(off_led)
# 初期設定
# MQTTオブジェクト定義
client = MQTTClient(myId, mqttBroker, keepalive=time_keepalive_MQTTClient)
# 受信(Subscribe)時に呼ぶ関数の設定
client.set_callback(printMessage)
# Wi-Fi接続
connect()
# ブローカーに接続
try:
# ブローカー接続処理
client.connect()
# Subトピック登録
client.subscribe(topic)
except:
# ブローカー接続失敗時、プログラム終了
print("Could not connect to mqtt server.")
sys.exit()
print("mqqtt connect done ")
# 動作検出用フォトインタラプタのオブジェクト設定
sw_head = Pin(GP18, Pin.IN, Pin.PULL_UP)
sw_bottom = Pin(GP19, Pin.IN, Pin.PULL_UP)
# get intial status of sw
status_old_sw_head = sw_head.value()
status_old_sw_bottom = sw_bottom.value()
# ■動作繰り返し
while True:
flag_head = 0
flag_bottom = 0
status_sw_head = sw_head.value()
status_sw_bottom = sw_bottom.value()
if status_sw_head !=status_old_sw_head:
flag_head = 1
if status_sw_bottom !=status_old_sw_bottom:
flag_bottom = 1
if flag_head==1 or flag_bottom==1:
# LED on
led_rpp.value(on_led)
#print(status_sw_head,status_sw_bottom)
msg_status = "H"+str(status_sw_head)+"/B"+str(status_sw_bottom)
#print(msg_status)
# Pubメッセージ生成
msg = msg_header+msg_status
# Pub実行
client.publish(topic, msg)
# LED点滅
led_rpp.value(on_led)
time.sleep(time_on_led)
led_rpp.value(off_led)
# ブローカーPubメッセージ確認チェック
client.check_msg()
# LED off
led_rpp.value(off_led)
status_old_sw_head = status_sw_head
status_old_sw_bottom = status_sw_bottom
以上