import machine
import time
from machine import SoftI2C, Pin
from lcd_api import LcdApi
from i2c_lcd import I2cLcd
import urequests
import network
from umqtt.simple import MQTTClient
#右超音波讀值
def right_distance():
trigPin_1.value(1)
time.sleep_us(10)
trigPin_1.value(0)
pulseTime = machine.time_pulse_us(echoPin_1, 1, echoTimeout)
if pulseTime > 0:
return pulseTime / 58
else:
return pulseTime
#左超音波讀值
def left_distance():
trigPin_2.value(1)
time.sleep_us(10)
trigPin_2.value(0)
pulseTime = machine.time_pulse_us(echoPin_2, 1, echoTimeout)
if pulseTime > 0:
return pulseTime / 58
else:
return pulseTime
#LCD顯示Under Detection後顯示Left,right 減少重複傳輸時的延遲
def home():
lcd.clear()
lcd.move_to(1,1)
lcd.putstr("Under Detection")
time.sleep(1)
lcd.clear()
lcd.move_to(0,1)
lcd.putstr("Right: ")
lcd.move_to(0,0)
lcd.putstr("left: ")
def handle_callback (topic, msg):
m = msg.decode("utf 8")
print(m)
#link
sta=network.WLAN(network.STA_IF)
sta.active(True)
sta.connect('Wokwi-GUEST','') #WIFT連線
print('Linking...')
while not sta.isconnected() :
pass
print('Link OK')
#link done
#超音波
echoTimeout = 23200# 等待截止時間
#GPIO 4 設為輸出,接超音波的Trig腳
trigPin_1 = Pin(4, Pin.OUT)
#GPIO 0 設為輸入,接超音波的Echo腳
echoPin_1 = Pin(0, Pin.IN)
trigPin_1.value(0)# 將Trig腳的電壓預設為低電位
#GPIO 12 設為輸出,接超音波的Trig腳
trigPin_2 = Pin(12, Pin.OUT)
#GPIO 14 設為輸入,接超音波的Echo腳
echoPin_2 = Pin(14, Pin.IN)
trigPin_2.value(0)# 將Trig腳的電壓預設為低電位
# 設定一測試距離的自定義副函式,單位為公分
#LCD/IIC設定
I2C_ADDR = 0x27
totalRows = 2
totalColumns = 16
#SCL=GPIO.22,SDA=GPIO.21
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)
lcd = I2cLcd(i2c, I2C_ADDR, totalRows, totalColumns)
#make webhook link
make_url='https://hook.eu2.make.com/8uhmmcmijbh9m84fbj78e95ohns9f7su'
#MQTT設定/登入
client_id = "Cg4lOjIUECEHFgwgFx80BC8"
user_name = "Cg4lOjIUECEHFgwgFx80BC8"
password = "uOdHHnXjdq27wbul2Ibb4FLX"
CHANNEL_ID = '2579454'
server = "mqtt3.thingspeak.com"
client = MQTTClient(client_id = client_id , server =server, user=user_name , password=password)
client.set_callback(handle_callback)
client.connect()
#自訂代數
alarm=0
home()#LCD顯示Under Detection後顯示Left,right
while(1):
# 開始測距
left_cm = left_distance()
right_cm = right_distance()
#左右測距0~100cm警告
if ((left_cm < 100)and(left_cm >= 0)) or ((right_cm < 100)and(right_cm >= 0)):
alarm=1
lcd.clear()
lcd.move_to(5,0)
lcd.putstr("Aleat!")
'''shell調試用
print("====Aleat====")
print('Left Distance:', left_cm, 'cm')
print('Right Distance:', right_cm, 'cm')
print("=============")
'''
#line通報
res=urequests.post(make_url+'?right='+str(right_cm)+'&left='+str(left_cm))
res.close()
elif alarm==1:
if ((left_cm >= 100)or(left_cm < 0)) and ((right_cm >= 100)or(right_cm < 0)):
#人員離開,停止警告
home()
alarm=0
if alarm==0:
#無警告時顯示測距值
if left_cm > 0:
print('Left Distance:', left_cm, 'cm')
lcd.move_to(6,0)
lcd.putstr(" ")#擦除前次數值(下方使用相同)
lcd.move_to(6,0)
lcd.putstr("%.2f cm" % left_cm)
else:
print('Out of the detection range.')
lcd.move_to(6,0)
lcd.putstr("range out")#超過顯示數值之字數可不用做擦除直接複寫(下方相同)
if right_cm > 0:
print('Right Distance:', right_cm, 'cm')
lcd.move_to(7,1)
lcd.putstr(" ")
lcd.move_to(7,1)
lcd.putstr("%.2f cm" % right_cm)
else:
print('Out of the detection range.')
lcd.move_to(7,1)
lcd.putstr("range out")
#發布至MQTT
credentials = bytes("channels/{:s}/publish".format(CHANNEL_ID), 'utf-8')
payload = bytes("field1={:.2f}&field2={:.2f}&field3={}\n".format(right_cm,left_cm,alarm), 'utf-8')
client.publish(credentials, payload)
time.sleep(5)#間隔5秒發布/讀取