Motoron Motor Controller library for Raspberry Pi
Loading...
Searching...
No Matches
rs485_careful_example.py
1#!/usr/bin/env python3
2
3# This example shows how to control multiple Motoron Motor Controllers in a
4# half-duplex RS-485 network while checking for errors.
5#
6# This is similar to serial_careful_example.py but it uses the
7# "Multi-device write" command to efficiently send speeds to multiple Motorons
8# and it uses the "Multi-device error check" command to efficiently check for
9# errors on multiple Motorons.
10#
11# The error checking code only works if each addressed Motoron can see the
12# repsonses sent by the other Motorons (e.g. they are in a half-duplex RS-485
13# network).
14#
15# This code assumes you have configured the Motorons to send 7-bit responses,
16# which is important because it prevents a Motoron from interpreting a response
17# from another Motoron as a command.
18#
19# You will need to change the following variables to match your configuration:
20# port, starting_device_number, device_count, motors_per_device.
21
22import sys
23import time
24import motoron
25import serial
26
27port = serial.Serial("/dev/serial0", 115200, timeout=0.1, write_timeout=0.1)
28
29# Define the range of Motoron device numbers to control.
30# (Note that this code does send some compact protocol commands which will
31# affect all Motorons regardless of their device number.)
32starting_device_number = 17
33device_count = 3
34
35# Define the number of motor channels per Motoron.
36# It is OK if some of the Motorons in the system have fewer channels than this.
37motors_per_device = 2
38
39mc = motoron.MotoronSerial(port=port)
40mc.expect_7bit_responses()
41# mc.use_14bit_device_number()
42
43# Define which status flags the Motoron should treat as errors.
44error_mask = (
45 (1 << motoron.STATUS_FLAG_PROTOCOL_ERROR) |
46 (1 << motoron.STATUS_FLAG_CRC_ERROR) |
47 (1 << motoron.STATUS_FLAG_COMMAND_TIMEOUT_LATCHED) |
48 (1 << motoron.STATUS_FLAG_MOTOR_FAULT_LATCHED) |
49 (1 << motoron.STATUS_FLAG_NO_POWER_LATCHED) |
50 (1 << motoron.STATUS_FLAG_UART_ERROR) |
51 (1 << motoron.STATUS_FLAG_RESET) |
52 (1 << motoron.STATUS_FLAG_COMMAND_TIMEOUT))
53
54# Reinititlize all the Motorons at once using the compact protocol.
55mc.reinitialize()
56mc.clear_reset_flag()
57mc.set_error_response(motoron.ERROR_RESPONSE_COAST)
58mc.set_error_mask(error_mask)
59mc.set_command_timeout_milliseconds(1000)
60for motor in range(1, motors_per_device + 1):
61 mc.set_max_acceleration(motor, 100)
62 mc.set_max_deceleration(motor, 100)
63
64# Device-specific initializations (optional).
65mc.device_number = starting_device_number
66mc.set_max_acceleration(1, 800)
67mc.set_max_deceleration(1, 800)
68
69# Go back to using the compact protocol.
70mc.device_number = None
71
72def encode_speeds(speeds):
73 b = []
74 for speed in speeds: b += [ speed & 0x7F, speed >> 7 & 0x7F ]
75 return b
76
77speeds = [0] * device_count * motors_per_device
78
79try:
80 while True:
81 # Check for errors on all the Motorons.
82 error_index = mc.multi_device_error_check(
83 starting_device_number, device_count)
84 if error_index != device_count:
85 mc.device_number = starting_device_number + error_index
86 print("Error check failed for device %d." % mc.device_number, file=sys.stderr)
87 status = mc.get_status_flags()
88 print("Status from device %d: 0x%x" % (mc.device_number, status),
89 file=sys.stderr)
90 mc.device_number = None
91 mc.coast_now()
92 sys.exit(1)
93
94 # Calculate motor speeds that will drive each motor forward briefly and
95 # repeat every 4 seconds.
96 millis = int(time.monotonic() * 1000)
97 for i in range(len(speeds)):
98 phase = (millis - 512 * i) % 4096
99 speeds[i] = 400 if phase <= 500 else 0
100
101 # Send the motor speeds.
102 mc.multi_device_write(starting_device_number, device_count,
103 motoron.CMD_SET_ALL_SPEEDS, encode_speeds(speeds))
104
105except KeyboardInterrupt:
106 mc.device_number = None
107 mc.coast_now()
108 pass
109except Exception:
110 mc.device_number = None
111 mc.coast_now()
112 raise
Represents a serial connection to a Pololu Motoron Motor Controller.
Definition: motoron.py:1761