Compare commits
4 Commits
sync-contr
...
d943874797
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d943874797 | ||
|
|
f99eaacfec | ||
|
|
576f9ee94e | ||
|
|
3443bd1f0b |
37
limits.py
Normal file
37
limits.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
|
|
||||||
|
PATH_OPEN = 0
|
||||||
|
PATH_BLOCKED = 1
|
||||||
|
LIMIT_LOWER_RIGHT = 19
|
||||||
|
LIMIT_LOWER_LEFT = 20
|
||||||
|
LIMIT_UPPER_RIGHT = 21
|
||||||
|
|
||||||
|
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
|
||||||
|
GPIO.setup(LIMIT_LOWER_RIGHT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||||
|
GPIO.setup(LIMIT_LOWER_LEFT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||||
|
GPIO.setup(LIMIT_UPPER_RIGHT, GPIO.IN, pull_up_down=GPIO.PUD_UP)
|
||||||
|
|
||||||
|
|
||||||
|
# True = optical path blocked, False = open
|
||||||
|
|
||||||
|
def test():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
print(
|
||||||
|
'Lower Right (GPIO19):', GPIO.input(LIMIT_LOWER_RIGHT) == PATH_BLOCKED,
|
||||||
|
'| Lower Left (GPIO20):', GPIO.input(LIMIT_LOWER_LEFT) == PATH_BLOCKED,
|
||||||
|
'| Upper Right (GPIO21):', GPIO.input(LIMIT_UPPER_RIGHT) == PATH_BLOCKED,
|
||||||
|
)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt as e:
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
||||||
100
main.py
100
main.py
@@ -12,9 +12,11 @@ import aiomqtt
|
|||||||
import serial
|
import serial
|
||||||
import glob
|
import glob
|
||||||
import time
|
import time
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
|
||||||
import dyn4
|
import dyn4
|
||||||
import relays
|
import relays
|
||||||
|
import limits
|
||||||
|
|
||||||
ENCODER_PPR = 65536
|
ENCODER_PPR = 65536
|
||||||
|
|
||||||
@@ -24,6 +26,13 @@ dmm1 = None
|
|||||||
dmm2 = None
|
dmm2 = None
|
||||||
|
|
||||||
|
|
||||||
|
# 2025-10-24 facts:
|
||||||
|
# Motor1 is left
|
||||||
|
# Motor2 is right
|
||||||
|
# Positive RPM moves the crosshead down
|
||||||
|
# Negative RPM moves the crosshead up
|
||||||
|
|
||||||
|
|
||||||
MOTOR_EN1 = 1
|
MOTOR_EN1 = 1
|
||||||
MOTOR_EN2 = 2
|
MOTOR_EN2 = 2
|
||||||
DISABLED = None
|
DISABLED = None
|
||||||
@@ -128,26 +137,48 @@ async def init_motor(path, name):
|
|||||||
|
|
||||||
|
|
||||||
async def read_motor(dmm, name):
|
async def read_motor(dmm, name):
|
||||||
|
global RPM_TARGET
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return dmm.read_AbsPos32()
|
return dmm.read_AbsPos32()
|
||||||
except BaseException as e:
|
except BaseException as e:
|
||||||
# any problems, kill both motors
|
# any problems, kill both motors
|
||||||
|
RPM_TARGET = 0
|
||||||
set_motors(0)
|
set_motors(0)
|
||||||
disable_motors()
|
disable_motors()
|
||||||
|
|
||||||
logging.error('Problem reading %s: %s - %s', name, e.__class__.__name__, e)
|
logging.error('Problem reading position of %s: %s - %s', name, e.__class__.__name__, e)
|
||||||
|
await send_mqtt('server/motor_status', name + ' disconnected')
|
||||||
|
dmm = False
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def check_status(dmm, name):
|
||||||
|
global RPM_TARGET
|
||||||
|
|
||||||
|
try:
|
||||||
|
status = dmm.read_Status()
|
||||||
|
current = dmm.read_TrqCurrent()
|
||||||
|
logging.info('%s status, alarm: %s, current: %s', name, status['alarm'] or 'None', current)
|
||||||
|
except BaseException as e:
|
||||||
|
# any problems, kill both motors
|
||||||
|
RPM_TARGET = 0
|
||||||
|
set_motors(0)
|
||||||
|
disable_motors()
|
||||||
|
|
||||||
|
logging.error('Problem reading status of %s: %s - %s', name, e.__class__.__name__, e)
|
||||||
await send_mqtt('server/motor_status', name + ' disconnected')
|
await send_mqtt('server/motor_status', name + ' disconnected')
|
||||||
dmm = False
|
dmm = False
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
async def check_sync(rev1, rev2):
|
async def check_sync(rev1, rev2):
|
||||||
global dmm1, dmm2
|
global dmm1, dmm2, RPM_TARGET
|
||||||
|
|
||||||
difference = rev1 - rev2
|
difference = rev1 - rev2
|
||||||
|
|
||||||
if abs(difference) > 2.0:
|
if abs(difference) > 2.0:
|
||||||
# out of sync, kill both motors
|
# out of sync, kill both motors
|
||||||
|
RPM_TARGET = 0
|
||||||
set_motors(0)
|
set_motors(0)
|
||||||
disable_motors()
|
disable_motors()
|
||||||
|
|
||||||
@@ -176,6 +207,12 @@ async def monitor_dyn4():
|
|||||||
dmm2 = await init_motor('/dev/ttyUSB1', 'Motor2')
|
dmm2 = await init_motor('/dev/ttyUSB1', 'Motor2')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if dmm1:
|
||||||
|
await check_status(dmm1, 'Motor1')
|
||||||
|
|
||||||
|
if dmm2:
|
||||||
|
await check_status(dmm2, 'Motor2')
|
||||||
|
|
||||||
pos1 = await read_motor(dmm1, 'Motor1')
|
pos1 = await read_motor(dmm1, 'Motor1')
|
||||||
if pos1 is False:
|
if pos1 is False:
|
||||||
dmm1 = False
|
dmm1 = False
|
||||||
@@ -202,25 +239,25 @@ async def monitor_dyn4():
|
|||||||
kp = 0.01
|
kp = 0.01
|
||||||
difference = rev1 - rev2
|
difference = rev1 - rev2
|
||||||
|
|
||||||
if abs(difference) > 0.25:
|
#if abs(difference) > 0.25:
|
||||||
if RPM_TARGET > 0:
|
# if RPM_TARGET > 0:
|
||||||
if rev1 > rev2:
|
# if rev1 > rev2:
|
||||||
motor1_scaler = 1.0 - kp * abs(difference)
|
# motor1_scaler = 1.0 - kp * abs(difference)
|
||||||
motor1_scaler = min(motor1_scaler, 1.0) # clamp to range 0.5 - 1.0
|
# motor1_scaler = min(motor1_scaler, 1.0) # clamp to range 0.5 - 1.0
|
||||||
motor1_scaler = max(motor1_scaler, 0.5)
|
# motor1_scaler = max(motor1_scaler, 0.5)
|
||||||
elif rev2 > rev1:
|
# elif rev2 > rev1:
|
||||||
motor2_scaler = 1.0 - kp * abs(difference)
|
# motor2_scaler = 1.0 - kp * abs(difference)
|
||||||
motor2_scaler = min(motor2_scaler, 1.0) # clamp to range 0.5 - 1.0
|
# motor2_scaler = min(motor2_scaler, 1.0) # clamp to range 0.5 - 1.0
|
||||||
motor2_scaler = max(motor2_scaler, 0.5)
|
# motor2_scaler = max(motor2_scaler, 0.5)
|
||||||
elif RPM_TARGET < 0:
|
# elif RPM_TARGET < 0:
|
||||||
if rev1 < rev2:
|
# if rev1 < rev2:
|
||||||
motor1_scaler = 1.0 - kp * abs(difference)
|
# motor1_scaler = 1.0 - kp * abs(difference)
|
||||||
motor1_scaler = min(motor1_scaler, 1.0) # clamp to range 0.5 - 1.0
|
# motor1_scaler = min(motor1_scaler, 1.0) # clamp to range 0.5 - 1.0
|
||||||
motor1_scaler = max(motor1_scaler, 0.5)
|
# motor1_scaler = max(motor1_scaler, 0.5)
|
||||||
elif rev2 < rev1:
|
# elif rev2 < rev1:
|
||||||
motor2_scaler = 1.0 - kp * abs(difference)
|
# motor2_scaler = 1.0 - kp * abs(difference)
|
||||||
motor2_scaler = min(motor2_scaler, 1.0) # clamp to range 0.5 - 1.0
|
# motor2_scaler = min(motor2_scaler, 1.0) # clamp to range 0.5 - 1.0
|
||||||
motor2_scaler = max(motor2_scaler, 0.5)
|
# motor2_scaler = max(motor2_scaler, 0.5)
|
||||||
|
|
||||||
motor1_rpm = int(RPM_TARGET * motor1_scaler)
|
motor1_rpm = int(RPM_TARGET * motor1_scaler)
|
||||||
motor2_rpm = int(RPM_TARGET * motor2_scaler)
|
motor2_rpm = int(RPM_TARGET * motor2_scaler)
|
||||||
@@ -229,6 +266,27 @@ async def monitor_dyn4():
|
|||||||
logging.info('Pos difference: %s, rev1: %s, rev2: %s, scaler1: %s, scaler2: %s, target: %s, rpm1: %s, rpm2: %s',
|
logging.info('Pos difference: %s, rev1: %s, rev2: %s, scaler1: %s, scaler2: %s, target: %s, rpm1: %s, rpm2: %s',
|
||||||
difference, rev1, rev2, motor1_scaler, motor2_scaler, RPM_TARGET, motor1_rpm, motor2_rpm)
|
difference, rev1, rev2, motor1_scaler, motor2_scaler, RPM_TARGET, motor1_rpm, motor2_rpm)
|
||||||
|
|
||||||
|
|
||||||
|
# check limit switches
|
||||||
|
if ONE_MOTOR:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
GOING_DOWNWARD = motor1_rpm > 0 or motor2_rpm > 0
|
||||||
|
GOING_UPWARD = motor1_rpm < 0 or motor2_rpm < 0
|
||||||
|
|
||||||
|
if GOING_DOWNWARD:
|
||||||
|
if GPIO.input(limits.LIMIT_LOWER_RIGHT) == limits.PATH_BLOCKED or GPIO.input(limits.LIMIT_LOWER_LEFT) == limits.PATH_BLOCKED:
|
||||||
|
motor1_rpm = 0
|
||||||
|
motor2_rpm = 0
|
||||||
|
logging.info('Lower limit switch hit, preventing downward travel.')
|
||||||
|
|
||||||
|
if GOING_UPWARD:
|
||||||
|
if GPIO.input(limits.LIMIT_UPPER_RIGHT) == limits.PATH_BLOCKED:
|
||||||
|
motor1_rpm = 0
|
||||||
|
motor2_rpm = 0
|
||||||
|
logging.info('Upper limit switch hit, preventing upward travel.')
|
||||||
|
|
||||||
|
|
||||||
if ONE_MOTOR:
|
if ONE_MOTOR:
|
||||||
logging.debug('Setting motor1: %s', motor1_rpm)
|
logging.debug('Setting motor1: %s', motor1_rpm)
|
||||||
dmm1.set_speed(motor1_rpm)
|
dmm1.set_speed(motor1_rpm)
|
||||||
|
|||||||
Reference in New Issue
Block a user