我有一个带有传感器和一个执行器的Arduino板。它通过USB线连接到Raspberry Pi。
这个想法是,通常Arduino将在Serial上打印数据。这是由Raspberry Pi在这个Python脚本的帮助下检索的。如果在云端遇到任何事件,或者如果我单击云上的按钮,则应该触发Arduino端的执行器。
我有以下MQTT客户端代码。
#!/usr/bin/env python
import logging
import time
import json
import serial
import paho.mqtt.client as mqtt
MQTT_BROKER = "things.ubidots.com"
MQTT_PORT = 1883 # Default MQTT Port is 1883
MQTT_KEEPALIVE_INTERVAL = 45 # In seconds
MQTT_USER_NAME = "Broker_User_Name"
MQTT_USER_PASSWORD = "Broker_User_Password"
PUB_TOPIC1 = "/v1.6/devices/mqtt/temperature"
SUB_TOPIC1 = "/v1.6/devices/mqtt/temperature"
PUB_TOPIC2 = "/v1.6/devices/mqtt/humidity"
SUB_TOPIC2 = "/v1.6/devices/mqtt/humidity"
PUB_TOPIC3 = "/v1.6/devices/mqtt/luminance"
SUB_TOPIC3 = "/v1.6/devices/mqtt/luminance"
PUB_TOPIC4 = "/v1.6/devices/mqtt/ADC"
SUB_TOPIC4 = "/v1.6/devices/mqtt/ADC"
PUB_TOPIC5 = "/v1.6/devices/mqtt/Battery_Status"
SUB_TOPIC5 = "/v1.6/devices/mqtt/Battery_Status"
Quqlity_of_Service = 0
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler('MQTT_log_file.log') # create a file handler
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') # create a logging format
handler.setFormatter(formatter)
logger.addHandler(handler)# add the handlers to the logger
logger.info("")
logger.info("######## Program started ########")
MQTT_MSG1 = 0
MQTT_MSG2 = 0
MQTT_MSG3 = 0
MQTT_MSG4 = 0
MQTT_MSG5 = 0
msg_body = ""
rc = 0 # For error checking
time.sleep(0.3)
pub_sub_option = int(raw_input("Do you want to be:\n 1.Publisher\n 2.Subscriber\n 3.Both\n :"))
logger.info("\nPublisher and Subscriber Option: {}".format(pub_sub_option))
if pub_sub_option == 1:
print("")
print("You have selected only Publisher")
print("")
elif pub_sub_option == 2:
print("")
print("You have selected only Subscriber")
print("")
elif pub_sub_option == 3:
print("")
print("You have selected both Publisher and Subscriber")
print("")
else:
print("")
print("Please select the correct option.")
print("")
if pub_sub_option == 1:
publisher_check = 1
subscriber_check = 0
elif pub_sub_option == 2:
publisher_check = 0
subscriber_check = 1
elif pub_sub_option == 3:
publisher_check = 1
subscriber_check = 1
serial_data = serial.Serial(port='/dev/ttyACM0', baudrate=115200) # Read the Sensor Data
logger.debug("Serial Data: {}".format(serial_data))
# ----# Json Data Converter Function #----
def json_data_publish(PUB_TOPIC, sensor_variable, Quqlity_of_Service):
message = {'value': sensor_variable}
logger.debug("Json Data Publisher Value: {}".format(message))
mqttc.publish(PUB_TOPIC, json.dumps(message), Quqlity_of_Service)
def connack_string(connack_code):
"""Return the string associated with a CONNACK result"""
if connack_code == 0:
return "Connection Accepted."
elif connack_code == 1:
return "Connection Refused: unacceptable protocol version."
elif connack_code == 2:
return "Connection Refused: identifier rejected."
elif connack_code == 3:
return "Connection Refused: broker unavailable."
elif connack_code == 4:
return "Connection Refused: bad user name or password."
elif connack_code == 5:
return "Connection Refused: not authorised."
else:
return "Connection Refused: unknown reason."
# Define on_connect event Handler
def on_connect(client, userdata, flags, rc):
logger.debug(connack_string(int(rc)))
print(connack_string(int(rc)))
# Define on_message event Handler for Topic 1
def on_message(client, userdata, msg):
logger.debug("Control is in On_Message")
received_topic = str(msg.topic)
received_message = str(msg.payload.decode())
if received_topic != "" and received_message != "":
if received_topic == SUB_TOPIC1:
received_temp_data = int(received_message)
print("The Received Temperature Data is: {}\n".format(received_temp_data))
logger.debug("The Received Temperature Data is: {}".format(received_temp_data))
elif received_topic == SUB_TOPIC2:
received_humid_data = int(received_message)
print("The Received Humidity Data is: {}\n".format(received_humid_data))
logger.debug("The Received Humidity Data is: {}".format(received_humid_data))
# Define on_publish event Handler
def on_publish(client, userdata, mid):
pass
# Initiate MQTT Client
mqttc = mqtt.Client()
logger.debug("MQTT Client is Initialized")
# Connect with MQTT Broker
mqttc.username_pw_set(MQTT_USER_NAME, MQTT_USER_PASSWORD)
mqttc.connect(MQTT_BROKER, MQTT_PORT, MQTT_KEEPALIVE_INTERVAL)
logger.debug("Connected to MQTT Broker")
# Register Event Handlers
mqttc.on_connect = on_connect
logger.debug("Control is in On_Connect Event Handler")
mqttc.on_message = on_message
logger.debug("Control is in On_Message Event Handler")
# subscribe for topic
if subscriber_check == 1:
mqttc.subscribe(SUB_TOPIC1, Quqlity_of_Service)
mqttc.subscribe(SUB_TOPIC2, Quqlity_of_Service)
mqttc.subscribe(SUB_TOPIC3, Quqlity_of_Service)
mqttc.subscribe(SUB_TOPIC4, Quqlity_of_Service)
mqttc.subscribe(SUB_TOPIC5, Quqlity_of_Service)
while rc == 0:
try:
rc = mqttc.loop()
if publisher_check == 1:
# ---- # Data from Real Sensors #----
data = serial_data.readline(20)
pieces = data.split(":")
if pieces[0] == "Temperature":
MQTT_MSG1 = pieces[1]
if pieces[0] == "Humidity":
MQTT_MSG2 = pieces[1]
if pieces[0] == "Luminance":
MQTT_MSG3 = pieces[1]
if pieces[0] == "ADC":
MQTT_MSG4 = pieces[1]
if pieces[0] == "Battery_Status":
MQTT_MSG5 = pieces[1]
logger.debug("Json Enabled")
json_data_publish(PUB_TOPIC1, MQTT_MSG1, Quqlity_of_Service)
print("Temperature {} Published\n".format(MQTT_MSG1))
logger.debug("Temperature {} Published with QOS = {}".format(MQTT_MSG1, Quqlity_of_Service))
time.sleep(1)
json_data_publish(PUB_TOPIC2, MQTT_MSG2, Quqlity_of_Service)
print("Humidity {} Published\n".format(MQTT_MSG2))
logger.debug("Humidity {} Published with QOS = {}".format(MQTT_MSG2, Quqlity_of_Service))
time.sleep(1)
json_data_publish(PUB_TOPIC3, MQTT_MSG3, Quqlity_of_Service)
print("Luminance {} Published\n".format(MQTT_MSG3))
logger.debug("Luminance {} Published with QOS = {}".format(MQTT_MSG3, Quqlity_of_Service))
time.sleep(1)
json_data_publish(PUB_TOPIC4, MQTT_MSG4, Quqlity_of_Service)
print("ADC {} Published\n".format(MQTT_MSG4))
logger.debug("ADC {} Published with QOS = {}".format(MQTT_MSG4, Quqlity_of_Service))
time.sleep(1)
json_data_publish(PUB_TOPIC5, MQTT_MSG5, Quqlity_of_Service)
print("Battery_Status {} Published\n".format(MQTT_MSG5))
logger.debug("Battery_Status {} Published with QOS = {}".format(MQTT_MSG5, Quqlity_of_Service))
time.sleep(1)
except KeyboardInterrupt:
print("\nThe Process is Terminated")
break
此代码可用作
但通常在我的设置中它总是在模式3(发布者和订阅者)中操作,因为我想触发执行器。
代码上传数据没有任何问题。但接收它时会出现问题。接收数据时会有延迟。但是,如果我从我的笔记本电脑运行与订户(模式2)相同的代码,它就能完美运行。一旦上传数据,就会收到我的笔记本电脑。
如果我能以更有效的方式编写相同的代码,请告诉我。
答案 0 :(得分:0)
我猜测延迟是在while循环中的sleep方法中。为什么不将代码分成'sub'和'pub'代码并在Raspberry Pi上单独运行它们。我不是Python专家,但我认为一切都在一个线程下运行,因此,当你睡觉时,它暂停了唯一的线程。