昨今スーパーなどのお店の店頭によく置いてあるアルコール自動噴出器(以下オートディスペンサーとします。)を自作してみました! 下記が実際に製作したオートディスペンサーの写真になります。
100均(DAISO)で購入したものを駆使して製作致しました。現在はこれを家の玄関前において動かしております。本記事ではこの製作に関して説明していきます。
目的
昨今のコロナの影響で我が家でも手の消毒の意識が高まり、その時たまたまみていたyoutubeの動画で、オートディスペンサーの製作の動画を見かけました。
趣味で電子工作を行っている事もあり、前々から気になっていたラズベリーパイピコを使って工作がしてみたくなったこともあり、その動画を参考に製作を行いました。
本記事では製作方法に関しての情報を記載したいと思います。
オートディスペンサーの仕様
今回製作したオートディスペンサーの外観図を考えてみると下記の通りになります。
動作としては、下記に示すように超音波センサーの前に手を置いて、距離の閾値を超えたらサーボモータが駆動して、針金を経由してスプレーを駆動させ、それによりストローからアルコールが出る仕組みになっております。
ストローを利用した理由としては、スプレーがそのまま出ると手に位置に当たらない為であり、ストローがある事によって超音波センサーの前にアルコールが落ちるようになっております。
電源に関してはダイソーの10000mAhのバッテリー(1000円)を使用しました。ラズベリーパイピコのmicro usb端子に直接接続して電源を供給致します。
全体回路ブロック図
全体回路ブロック図を描くと下記の通りになります。
回路概要としては、上記の通りで構成されております。
スプレー駆動の為のサーボモータと距離測定用の超音波測定センサーで構成されており、動作させる為のバッテリーとそのバッテリーの最低電流を決めるLEDと抵抗を使っております。
ダイソーのモバイルバッテリーなのですが、出力電流が小さすぎると、勝手にOFFになる仕様になっており、10000mAhタイプだと動かし続けるのに50~60mA程度の電流を流し続ける必要があります。(USB電流チェッカーを使って実測を行いました。)
その為、抵抗を組み合わせて調整出来るようにしました。また、電力は一般的な1/4Wタイプ(0.25W)のもので問題ない組み合わせにしました。
材料
この工作で使う材料を下記に記載致します。
- 駆動用サーボモータ(SG90) x 1
- 距離測定用距離センサー(HC-SR04) x 1
- ラズベリーパイ ピコ x 1
- 携帯用バッテリー(10000mAh) x 1
- ユニバーサル基盤 x 1
- 抵抗類(可変抵抗も含む)
- LED x 1
- 100均スプレーボトル x 1
- 細い針金 1m程度 x 1
- ストロー x 1
- スペーサー x 4
製作に使用する主な道具は
- はんだごて x 1
- はんだ x 1
- グルーガン x 1
- ラジオペンチ x 1
- ニッパー x 1
になります。下記にメインで使用する材料に関しての詳細を記載します。
超音波距離センサー
超音波距離センサーの回路の部分に関して中身を確認します。赤線部分を抜き出すと下記のようになります。
ここで使用する超音波センサーはKeyestudioの超音波距離センサーHC-SR04を使用しました。データシートは下記の通りになります。
超音波距離センサーは下記の通りの外観になります。(ぼけててすみません。)
ピン配置は下記の通りになっております。
- Vcc 電源供給ライン
- Trig 超音波発生のトリガー(タイミング信号)
- Echo 超音波の受信部
- GND GNDピン
データシートを見る限り、40kHzの超音波発生させます。超音波センサーの動作は下記の通りになります。データシートの内容を元に書きました。
中身を確認してみると、Trigger信号を入れた際にBurst信号(40kHz x 8)の超音波を発生させ、それの跳ね返りのReflected信号が帰ってくるまでの時間の情報をECHO端子から出力する仕組みだそうです。そこで距離の計算にはECHO端子のパルス幅を読み取りその値を元に、下記の通りに計算して導出致しました。(参考)
(Echoのパルス幅 x 0.0343) / 2 (cm)
サーボモータ
サーボモータに関して記載致します。今回使用したサーボーモータはSG90になります。
サーボモータとは、一般的なモータが動力源として連続回転運動を伝えるものになっているのに対して一定の角度に回転して、その位置に止まる事が出来る制御をするモータになります。
生産工場でよく使用されるロボットアーム等によく利用されており、位置制御をしたい場合に重宝致します。今回使用するSG90といったサーボモータですが、仕様としては下記の通りになります。
- 重さ : 9g
- 大きさ : 22.2mm x 11.8 mm x 31 mm
- 停動トルク :1.8kgf・cm
- 動作スピード :0.12s / 60度
- 動作電圧 : 3.3V~6.0V
- デットバンド幅 : 1us (信号が入ってから動き出すまでの時間)
- 動作温度 :0℃-55℃
サーボモータはPWM出力で動作しており、PWM信号のDuty幅で制定される角度が決まります。
PWM(Pulse Width Modulation)
サーボモータで使用するPWM出力に関して考えてみます。PWM(Pulse Width Moodulation)出力とは、パルス幅変調出力の事を指します。イメージとしては下記の通りになります。
パルスの周期に対してDutyといったものが決まっており、割ったものをDuty比と呼んでおります。
このようにPWM出力とはパルスの幅を変調する出力の事を指し、この方法はエネルギー変換技術としてh他スイッチング電源や、インバータ技術等によく用いられております。
今回使用するサーボモータはDuty比の割合で定まる角度が決まります。
仕様を確認すると、1周期20ms(50Hz)で、Dutyが0.5ms(-90度)、.1.45ms(0度)、2.4ms(90度)になっており、グラフにすると下記の通りになりそうです。
※このmsという単位は、1000分の1秒(ミリ)の事を指します。
計算すると、角度は大体下記の式で求められます。
角度 = 94.74度/ms × Duty時間(ms) -137.37
上記の式から、Duty時間を求めれば、このサーボモータの制御角度が得られます。(エクセル等で計算してみて下さい)
プログラム
プログラムの仕様は
- モジュールの読み込み
- PINの設定
- サーボモータ関連の設定
- 距離測定関数
- サーボモータ駆動関数
- メインループ
の通りになります。プログラムを下記に記載致します。
from machine import PWM, Pin
import time
import utime
#pinの設定
trigger = Pin(14, Pin.OUT)
echo = Pin(16, Pin.IN)
#サーボモータ出力設定
servo1 = PWM(Pin(0))
#PWMの周波数
servo1.freq(50)
#Dutyによるサーボモータ角度の定義
max_duty = 65025
dig_0 = 0.025 #0°
dig_90 = 0.10 #90°
#距離確認関数
def read_dist():
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep(0.00001)
trigger.low()
while echo.value() == 0:
sigoff = utime.ticks_us()
while echo.value() == 1:
sigon = utime.ticks_us()
tpass = sigon - sigoff
dist = (tpass * 0.0343) / 2
return dist
#サーボモータ駆動関数
def move_servo():
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.5)
servo1.duty_u16(int(max_duty*dig_90))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_90))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.5)
#メインループ
while True:
dis = read_dist()
#5cm以内に手が入ったら駆動する。
if dis<5 :
move_servo()
utime.sleep(0.1)
continue
utime.sleep(0.5)
各々のプログラムの説明を次に示します。
モジュールの読み込み
こちらはプログラムを動かすためにモジュールの読込を行っております。読み込むモジュールは
- PWM : PWM出力用モジュール PWM出力をするのに使用
- Pin : 出力Pin設定用モジュール PINの入出力を設定するのに使用
- time : 時間モジュール サーボモータの待ち時間を指定するのに使用
- utime : 時間モジュール 距離測定の待ち時間を指定するのに使用
となっております。
from machine import PWM, Pin
import time
import utime
PINの設定
本プログラムでは、超音波距離センサーのTrigger端子をGPIO14pin、Echo入力端子をGPIO16pinに設定して動作させた。
GPIO16に関しては3.3Vでしか動作出来ないため、Echo端子を分圧(5Vしか出力しない為)して3.3Vへの変換を行った。
#pinの設定
trigger = Pin(14, Pin.OUT)
echo = Pin(16, Pin.IN)
サーボモータ関連の設定
サーボモータ用のPWM出力はGPIO0で設定し、動作周波数は50Hzで定義した。(SG90が読み取れる周波数で定義)
またDutyの最大値を65025とおいて、0度の時を0.025、90度の時を0.10と定義した。
#サーボモータ出力設定
servo1 = PWM(Pin(0))
#PWMの周波数
servo1.freq(50)
#Dutyによるサーボモータ角度の定義
max_duty = 65025
dig_0 = 0.025 #0°
dig_90 = 0.10 #90°
距離測定関数
距離測定関数では、Trigger端子10usのパルスを出力し、その時のEcho端子のパルス幅を持って距離を測定した。
距離は (Echoパルスの幅 x 0.0343) / 2の計算にて導出を行った。
最終的に得られた距離はreturnで戻り値として返される。
#距離確認関数
def read_dist():
trigger.low()
utime.sleep_us(2)
trigger.high()
utime.sleep(0.00001)
trigger.low()
while echo.value() == 0:
sigoff = utime.ticks_us()
while echo.value() == 1:
sigon = utime.ticks_us()
tpass = sigon - sigoff
dist = (tpass * 0.0343) / 2
return dist
サーボモータ駆動関数
サーボモータ駆動関数では、0度と90度を交互に2回動かす動作を入れた。
この動作により、針金を経由して、スプレーが駆動し、アルコールがストローの先から出る仕組みになっている。
#サーボモータ駆動関数
def move_servo():
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.5)
servo1.duty_u16(int(max_duty*dig_90))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_90))
time.sleep(0.3)
servo1.duty_u16(int(max_duty*dig_0))
time.sleep(0.5)
メインループ
こちらがメインループで、超音波距離センサーの距離5cm以内に入ったら、サーボモータが駆動する構造になっている。
サーボモータ駆動をしたのちに少し遅延してループするような仕組みをとっている。
#メインループ
while True:
dis = read_dist()
#5cm以内に手が入ったら駆動する。
if dis<5 :
move_servo()
utime.sleep(0.1)
continue
utime.sleep(0.5)
まとめ
最終的に上記プログラムを用いて、オートディスペンサーを作ることが出来ました。
現状10000mAhのバッテリーを用いて家の玄関前に置いて動作させています。
ただ今の所、バッテリーが3日くらいで切れるので、バッテリーの容量を増やす方法を別途検討している最中になります。せめて1週間持たせられるか検討中です。(バッテリーの数を増やす等で検討中)
そのうち試験を行ってみて、改良出来たらしてみようと思います。
コメント