Compare commits
No commits in common. "meyer" and "main" have entirely different histories.
|
|
@ -0,0 +1,20 @@
|
||||||
|
# USDA Pecan IOT Tablet Configuration
|
||||||
|
|
||||||
|
This repo contains separate branches for each tablet to store the
|
||||||
|
individualized software.
|
||||||
|
|
||||||
|
Each of:
|
||||||
|
|
||||||
|
- jc
|
||||||
|
- meyer
|
||||||
|
- sheller
|
||||||
|
|
||||||
|
All 3 branches implement contain the prerequisites for setting up a
|
||||||
|
Systemd service to listen to and control equipment via MQTT, as well
|
||||||
|
as sending back relevant diagnostic and statistical information.
|
||||||
|
|
||||||
|
Files:
|
||||||
|
|
||||||
|
- mqtt_listener.py: The main Python application interacting with MQTT
|
||||||
|
- mqtt_listener.service: The file to install to /etc/systemd/system/
|
||||||
|
- mqtt_start.sh: The entrypoint from Systemd to Python
|
||||||
101
mqtt_listener.py
101
mqtt_listener.py
|
|
@ -1,101 +0,0 @@
|
||||||
import paho.mqtt.client as mqtt
|
|
||||||
import re
|
|
||||||
from dynio import *
|
|
||||||
import time
|
|
||||||
|
|
||||||
# State variable to check if HOME is received before POS
|
|
||||||
home_received = False
|
|
||||||
home = 0
|
|
||||||
dxl_io = []
|
|
||||||
motor = None
|
|
||||||
|
|
||||||
# Functions to run when the corresponding command is received
|
|
||||||
def home():
|
|
||||||
global motor, home
|
|
||||||
motor.write_control_table('Torque_Limit', 200)
|
|
||||||
motor.set_velocity_mode()
|
|
||||||
print('velocity mode set')
|
|
||||||
motor.torque_enable()
|
|
||||||
print('torque enabled')
|
|
||||||
motor.set_velocity(300)
|
|
||||||
print('velocity set')
|
|
||||||
time.sleep(1)
|
|
||||||
while motor.read_control_table('Present_Speed') > 0:
|
|
||||||
pass
|
|
||||||
motor.torque_disable()
|
|
||||||
home = motor.get_position()
|
|
||||||
motor.write_control_table('Multi_Turn_Offset', -1 * home)
|
|
||||||
motor.set_extended_position_mode()
|
|
||||||
motor.torque_enable()
|
|
||||||
|
|
||||||
def set_pos(num):
|
|
||||||
global motor
|
|
||||||
motor.set_position(num)
|
|
||||||
time.sleep(0.2)
|
|
||||||
while motor.read_control_table('Present_Speed') > 0:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def disable_torque():
|
|
||||||
global motor, home_received
|
|
||||||
motor.torque_disable()
|
|
||||||
home_received = False
|
|
||||||
|
|
||||||
|
|
||||||
# The callback for when the client receives a CONNACK response from the server.
|
|
||||||
def on_connect(client, userdata, flags, rc):
|
|
||||||
print(f"Connected with result code {str(rc)}")
|
|
||||||
|
|
||||||
# Subscribing in on_connect() means that if we lose the connection and
|
|
||||||
# reconnect then subscriptions will be renewed.
|
|
||||||
client.subscribe("/meyer/#")
|
|
||||||
|
|
||||||
# Connect to Dynamixels
|
|
||||||
global dxl_io, motor
|
|
||||||
dxl_io = dxl.DynamixelIO('/dev/ttyACM0')
|
|
||||||
motor = dxl_io.new_mx106(1,1)
|
|
||||||
motor.get_position()
|
|
||||||
motor.write_control_table('Torque_Limit', 200)
|
|
||||||
|
|
||||||
|
|
||||||
# The callback for when a PUBLISH message is received from the server.
|
|
||||||
def on_message(client, userdata, msg):
|
|
||||||
global home_received, motor
|
|
||||||
|
|
||||||
message = msg.payload.decode()
|
|
||||||
if msg.topic != "/meyer/":
|
|
||||||
return
|
|
||||||
|
|
||||||
if message == "HOME":
|
|
||||||
home()
|
|
||||||
home_received = True
|
|
||||||
time.sleep(0.5)
|
|
||||||
set_pos(int(-250*53.248))
|
|
||||||
client.publish("/meyer/pos", -250.0)
|
|
||||||
elif message == "DISABLE":
|
|
||||||
disable_torque()
|
|
||||||
elif re.match(r"^POS -?\d+$", message): # This matches POS followed by a number
|
|
||||||
pos_num = int(message.split()[1]) # Extract the number from the message
|
|
||||||
pos_num *= 5.3248
|
|
||||||
|
|
||||||
if pos_num < -25000 or pos_num > 0: # Check if the number is out of range
|
|
||||||
client.publish("/meyer/error", "Error: Number out of range")
|
|
||||||
elif not home_received: # Check if HOME was received before POS
|
|
||||||
client.publish("/meyer/error", "Error: HOME command has to be run before POS")
|
|
||||||
else:
|
|
||||||
set_pos(int(pos_num))
|
|
||||||
client.publish("/meyer/pos", round(pos_num / 53.248,1))
|
|
||||||
else:
|
|
||||||
client.publish("/meyer/error", "Error: Unknown command")
|
|
||||||
|
|
||||||
|
|
||||||
client = mqtt.Client()
|
|
||||||
client.on_connect = on_connect
|
|
||||||
client.on_message = on_message
|
|
||||||
|
|
||||||
# Connect to the broker
|
|
||||||
client.connect("192.168.1.1", 1883, 60)
|
|
||||||
|
|
||||||
# Blocking call that processes network traffic, dispatches callbacks and
|
|
||||||
# handles reconnecting.
|
|
||||||
client.loop_forever()
|
|
||||||
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[Unit]
|
|
||||||
Description=MQTT Listener Service
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/home/biqu/mqtt_start.sh
|
|
||||||
WorkingDirectory=/home/biqu
|
|
||||||
StandardOutput=inherit
|
|
||||||
StandardError=inherit
|
|
||||||
Restart=always
|
|
||||||
User=biqu
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# navigate to the directory of the script
|
|
||||||
cd /home/biqu/screw_control/
|
|
||||||
|
|
||||||
# activate the python environment, if you're using one
|
|
||||||
# source /path_to_your_venv/bin/activate
|
|
||||||
|
|
||||||
# run the script
|
|
||||||
/usr/bin/python3 mqtt_listener.py
|
|
||||||
Loading…
Reference in New Issue