Motoron Motor Controller library for Raspberry Pi
Loading...
Searching...
No Matches
i2c_current_sense_calibrate_example.py
1#!/usr/bin/env python3
2
3# This example for the Motoron M2H controllers shows how to automatically
4# measure the current sense offsets at startup and load them into the Motoron so
5# that the processed current measurements are more accurate.
6#
7# It also uses those current sense offsets to help set current limits.
8
9import time
10import motoron
11
13
14# ADC reference voltage
15reference_mv = 3300
16
17# Specifies what type of Motoron you are using, which is needed for converting
18# current sense readings to milliamps.
19type = motoron.CurrentSenseType.MOTORON_18V18
20
21# Minimum allowed VIN voltage. This example does not take current calibration
22# readings while VIN is below this configurable level.
23min_vin_voltage_mv = 6500
24
25units = motoron.current_sense_units_milliamps(type, reference_mv)
26
27def calibrate_current():
28 mc.set_speed(1, 0)
29 mc.set_speed(2, 0)
30
31 desired_sample_count = 32
32 sample_count = 0
33 totals = [ 0, 0 ]
34
35 last_time_conditions_not_met = time.monotonic()
36 while True:
37 status_mask = ((1 << motoron.STATUS_FLAG_MOTOR_FAULTING) |
38 (1 << motoron.STATUS_FLAG_NO_POWER) |
39 (1 << motoron.STATUS_FLAG_MOTOR_OUTPUT_ENABLED) |
40 (1 << motoron.STATUS_FLAG_MOTOR_DRIVING))
41 status_desired = 1 << motoron.STATUS_FLAG_MOTOR_OUTPUT_ENABLED
42
43 if ((mc.get_status_flags() & status_mask) != status_desired or
44 (mc.get_vin_voltage_mv(reference_mv) < min_vin_voltage_mv)):
45 last_time_conditions_not_met = time.monotonic()
46 sample_count = 0
47 totals = [0, 0]
48
49 if (time.monotonic() - last_time_conditions_not_met) > 0.02:
50 totals[0] += mc.get_current_sense_raw(1)
51 totals[1] += mc.get_current_sense_raw(2)
52 sample_count += 1
53 if sample_count == desired_sample_count: break
54
55 mc.set_current_sense_offset(1, round(totals[0] / desired_sample_count))
56 mc.set_current_sense_offset(2, round(totals[1] / desired_sample_count))
57 mc.set_current_sense_minimum_divisor(1, 100)
58 mc.set_current_sense_minimum_divisor(2, 100)
59
60 print(f"Current sense offsets: {mc.get_current_sense_offset(1)} {mc.get_current_sense_offset(2)}")
61
62mc.reinitialize()
63mc.clear_reset_flag()
64
65# By default, the Motoron is configured to stop the motors if
66# it does not get a motor control command for 1500 ms. You
67# can uncomment a line below to adjust this time or disable
68# the timeout feature.
69# mc.set_command_timeout_milliseconds(1000)
70# mc.disable_command_timeout()
71
72# Configure motor 1
73mc.set_max_acceleration(1, 200)
74mc.set_max_deceleration(1, 200)
75
76# Configure motor 2
77mc.set_max_acceleration(2, 200)
78mc.set_max_deceleration(2, 200)
79
80calibrate_current()
81
82# Set current limits using the offsets we just measured.
83# The second argument to calculate_current_limit is a current limit
84# in milliamps.
85mc.set_current_limit(1, motoron.calculate_current_limit(10000,
86 type, reference_mv, mc.get_current_sense_offset(1)))
87mc.set_current_limit(2, motoron.calculate_current_limit(10000,
88 type, reference_mv, mc.get_current_sense_offset(2)))
89
90try:
91 while True:
92 mc.set_speed(1, 200)
93 time.sleep(1)
94 processed = mc.get_current_sense_processed(1)
95 print(f"Motor 1 current: {processed} = {round(processed * units)} mA")
96 mc.set_speed(1, 0)
97 time.sleep(1)
98
99 mc.set_speed(2, 200)
100 time.sleep(1)
101 processed = mc.get_current_sense_processed(2)
102 print(f"Motor 2 current: {processed} = {round(processed * units)} mA")
103 mc.set_speed(2, 0)
104 time.sleep(1)
105
106except KeyboardInterrupt:
107 pass
def calculate_current_limit(milliamps, type, reference_mv, offset)
Calculates a current limit value that can be passed to the Motoron using set_current_limit().
Definition: motoron.py:1628
def current_sense_units_milliamps(type, reference_mv)
Calculates the units for the Motoron's current sense reading returned by get_current_sense_processed(...
Definition: motoron.py:1650
Represents an I2C connection to a Pololu Motoron Motor Controller.
Definition: motoron.py:1665