Fortiq M42BLS | Servo Module¶
The IQ Fortiq M42BLS module is designed for industrial and robotic applications that require maximum torque, precision, and efficiency with minimal vibration. IQ’s unique hardware design and advanced calibration techniques has allowed us to create the most compact and torque-dense industrial servomotor on the market. IQ is offering 4 versions of the Fortiq M42BLS.
Note
The Fortiq has previously been named BLS42 and now they called Fortiq M42BLS.
While the default firmware for the Fortiq M42BLS0 is the Servo Firmware, it also fully supports the following:
Step Direction Firmware
Speed Firmware
Servo Firmware¶
Multi Turn Angle Control¶
The Multi-turn Angle Controller is a non-wrapping, PID, position controller. It is capable of storing angular to linear transmission information, mimicking a linear position controller. It also features a minimum jerk trajectory generator. The controller has a 32 trajectory buffer so that transitions between trajectories are seamless.
Arduino¶
To use Multi-turn Angle Controller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
MultiTurnAngleControlClient mult(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(mult.trajectory_angular_displacement_,3.14f);
ser.set(mult.trajectory_duration_,0.5f);
ser.set(mult.trajectory_angular_displacement_,0.0f);
ser.set(mult.trajectory_duration_,0.5f);
delay(1000);
}
C++¶
To use Multi-turn Angle Controller in C++, include multi turn angle control client.hpp. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "multi_turn_angle_control_client.hpp"
float angle;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Multi-turn Angle Controller object with obj_id 0
MultiTurnAngleControlClient angle_ctrl(0);
// Use the Multi-turn Angle Controller object
angle_ctrl.obs_angular_displacement_.get(com);
angle_ctrl.ctrl_angle_.set(com,0.0f);
// Insert code for interfacing with hardware here
// Read response
angle = angle_ctrl.ctrl_angle_.get_reply();
}
Matlab¶
To use Multi-turn Angle Controller in Matlab, all IQ communication code must be included in your path. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a MultiTurnAngleControlClient object with obj_id 0
angle_ctrl = MultiTurnAngleControlClient(’com’,com);
% Use the MultiTurnAngleControlClient object
velocity_filtered = angle_ctrl.get(’obs_angular_displacement’);
angle_ctrl.set(’ctrl_angle’,0);
Python¶
To use the Multi-Turn Angle Control Client in Python, include iqmotion
and create a module that has the Multi-Turn Angle Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Multi-Turn Angle Control Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 ) # Servo Firmware uses this client
# Set the trajectory for the motor to complete 1 full rotation
fortiq.set("multi_turn_angle_control", "trajectory_angular_displacement", 2*math.pi)
# Sets trajectory duration for 2 seconds
fortiq.set("multi_turn_angle_control", "trajectory_duration", 2)
Message Table¶
Type ID 59 | Multi-turn Angle Controller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
int8 |
enum |
no_change = -1, brake=0, coast=1, pwm=2, volts=3, velocity=4, angle=5, trajectory=6 |
1 |
ctrl_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry, motor passively coasts |
||
3 |
ctrl_angle |
get, set |
float |
rad |
Angular location command |
4 |
ctrl_velocity |
get, set |
float |
rad/s |
Angular velocity command |
5 |
angle_Kp |
get, set, save |
float |
V/rad |
Proportional gain |
6 |
angle_Ki |
get, set, save |
float |
V/(rad*s) |
Integral gain |
7 |
angle_Kd |
get, set, save |
float |
V/(rad/s) |
Derivative gain |
8 |
timeout |
get, set, save |
float |
s |
The controller must receive a message within this time otherwise it is set to coast mode |
9 |
ctrl_pwm |
get, set |
float |
pwm |
Spins motor with this throttle [-1, 1] |
10 |
ctrl_volts |
get, set |
float |
V |
Spins motor with this voltage |
11 |
obs_angular_displacement |
get, set |
float |
rad |
Observed angular location |
12 |
obs_angular_velocity |
get |
float |
rad/s |
Observed angular velocity |
13 |
meter_per_rad |
get, set, save |
float |
m/rad |
Transmission between angular and linear motion |
14 |
ctrl_linear_displacement |
get, set, |
float |
m |
Linear equivalent to ctrl_angle |
15 |
ctrl_linear_velocity |
get, set, |
float |
m/s |
Linear equivalent to ctrl_velocity |
16 |
obs_linear_displacement |
get, set, |
float |
m |
Observed linear location |
17 |
obs_linear_velocity |
get |
float |
m/s |
Observed linear velocity |
18 |
angular_speed_max |
get, set, save |
float |
rad/s |
The controller will never attempt to exceed this speed |
19 |
trajectory_angular_displacement |
get, set |
float |
rad |
Final absolute displacement of trajectory. |
20 |
trajectory_angular_velocity |
get, set |
float |
rad/s |
Final velocity of the trajectory. Defaults to 0. |
21 |
trajectory_angular_acceleration |
get, set |
float |
\[rad/s^2\]
|
Final acceleration of the trajectory. Defaults to 0. |
22 |
trajectory_duration |
set |
float |
s |
Duration of trajectory. Trajectory is executed or queued once this is sent. |
23 |
trajectory_linear_displacement |
get, set |
float |
m |
Final absolute displacement of trajectory. |
24 |
trajectory_linear_velocity |
get, set |
float |
m/s |
Final velocity of the trajectory. Defaults to 0. |
25 |
trajectory_linear_acceleration |
get, set |
float |
\[m/s^2\]
|
Final acceleration of the trajectory. Defaults to 0. |
26 |
trajectory_average_speed |
get, set |
float |
\[m/s^2\]
|
Average speed of a trajectory. Trajectory is executed or queued once this is sent. Must be $>0$. |
27 |
trajectory_queue_mode |
get, set, save |
int8 |
\[m/s^2\]
|
append=0, overwrite=1 |
Brushless Drive¶
Brushless Drive is the low level driver of the motor’s phase voltage.
Arduino¶
To use Brushless Drive in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BrushlessDriveClient object.
See Table 3 for available messages. All message objects use the Short
Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
#include <iq_module_communicaiton.hpp>
IqSerial ser(Serial2);
BrushlessDriveClient mot(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(mot.drive_spin_volts_,0.1f);
}
C++¶
To use Brushless Drive in C++, include brushless drive client.hpp. This allows the creation of a BrushlessDriveClient
object.
See Table 3 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "propeller_motor_control_client.hpp"
float voltage = 3.0f; // volts
int main(){
// Make a communication interface object
// This is what creates and parses packets
GenericInterface com;
// Make a Temperature Estimator Client object with obj_id 0
BrushlessDriveClient brushless(0);
// Drives the motor at 3 Volts
brushless.drive_spin_volts_.set(com, voltage);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Brushless Drive Controller in Matlab, all IQ communication code must be included in your path.
This allows the creation of a BrushlessDriveClient object. See Table 2 for available messages. All
message strings use the Short Names. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BrushlessDriveClient object with obj_id 0
drive = BrushlessDriveClient(’com’,com);
% Use the BrushlessDriveClient object
drive.set(’drive_spin_volts’,3.0);
Python¶
To use the Brushless Drive Client in Python, include iqmotion
and create a module that has the Brushless Drive Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the BrushlessDriveClient is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("brushless_drive", "drive_spin_volts", 5) # Spins motor at 5 volts
Message Table¶
Type ID 50 | Brushless Drive
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
Note |
---|---|---|---|---|---|---|
0 |
drive_mode |
get |
uint8 |
0 = phase_pwm, 1 = phase_volts, 2 = spin_pwm, 3 = spin_volts, 4 = brake, 5 = coast |
||
1 |
drive_phase_pwm |
set |
float |
pwm |
Open loop (gimbal) mode with this trottle [-1, 1]. Use with phase_angle. |
|
2 |
drive_phase_volts |
set |
float |
V |
Open loop (gimbal) mode with this voltage. Use with phase_angle. |
|
3 |
drive_spin_pwm |
set |
float |
pwm |
Spins motor with this throttle [-1, 1] |
|
4 |
drive_spin_volts |
set |
float |
V |
Spins motor with this voltage |
|
5 |
drive_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
|||
6 |
drive_coast |
set |
Disables all drive circuitry, motor passively coasts |
|||
7 |
drive_angle_offset |
get |
float |
rad |
Analogous to motor timing. This is internally computed by the motor. |
|
8 |
drive_pwm |
get |
float |
pwm |
The applied pwm after all computation and limiting [-1, 1] |
|
9 |
drive_volts |
get |
float |
V |
The applied pwm after all computation and limiting |
|
10 |
mech_lead_angle |
get |
float |
rad |
||
11 |
obs_supply_volts |
get |
float |
V |
Observed supply voltage |
|
12 |
obs_angle |
get |
float |
rad |
Observed motor angle |
|
13 |
obs_velocity |
get |
float |
rad/s |
Observed motor velocity |
|
14 |
motor_pole_pairs |
get, set, save |
uint16 |
Number of motor pole pairs (magnets/2) |
||
15 |
motor_emf_shape |
get, set, save |
uint8 |
|||
16 |
permute_wires |
get, set, save |
uint8 |
bool |
||
17 |
calibration_angle |
get, set, save |
float |
rad |
||
18 |
lead_time |
get, set, save |
float |
s |
||
19 |
commutation_hz |
get, set, save |
uint32 |
Hz |
Frequency of commutation. Higher frequencies run faster and more efficient, but may not give the controller enough computation time. |
|
20 |
phase_angle |
get, set |
float |
rad |
Angle used for open loop (gimbal) mode. Use with drive_phase_pwm or drive_phase_volts |
|
32 |
motor_Kv |
get, set, save |
float |
RPM/V |
Motor’s voltage constant |
|
33 |
motor_R_ohm |
get, set, save |
float |
ohm |
Motor’s resistance |
|
34 |
motor_I_max |
get, set, save |
float |
A |
Max allowable motor current |
|
35 |
volts_limit |
get, set, save |
float |
V |
Max regen voltage |
|
36 |
est_motor_amps |
get |
float |
A |
Estimated motor amps |
|
37 |
est_motor_torque |
get |
float |
Nm |
Estimated motor torque |
|
38 |
motor_redline_start |
get, set, save |
float |
rad/s |
Speed at which motor begins to derate |
|
39 |
motor_redline_end |
get, set, save |
float |
rad/s |
Speed at which the motor is fully derated |
|
40 |
motor_l |
get, set, save |
float |
H |
Cross inductance |
|
41 |
derate |
get |
int32 |
PU fix16 |
Amount of derating. No derate = 65536, full derate = 0 |
|
42 |
i_soft_start |
get, set, save |
float |
A |
Current at which motor begins to derate |
|
43 |
i_soft_end |
get, set, save |
float |
A |
Current at which the motor is fully derated |
Anticogging¶
Anticogging is the process of electronically canceling out cogging torque of a motor. Each motor is loaded with its unique cog information. This class allows enabling and disabling the anticogging process. Though this class can also manipulate the cog information it is not recommended to manipulate or erase this data as it is unrecoverable.
Arduino¶
To use the Anticogging in Arduino, ensure iq module communication.hpp is included. This allows the creation of a AnticoggingClient object. See Table below for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
BrushlessDriveClient mot(0);
AnticoggingClient cog(0);
void setup() {
ser.begin();
ser.set(mot.drive_spin_volts_,0.0f);
}
void loop() {
// Spin the motor with your hand and feel Anticogging turning on and off
ser.set(cog.is_enabled_,(uint8_t)1);
delay(2000);
ser.set(cog.is_enabled_,(uint8_t)0);
delay(2000);
}
C++¶
To use the Anticogging client in C++, include anticogging client.hpp. This allows the creation of an AnticoggingClient object. See Table below for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "anticogging_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a ESC Propeller Input Parser object with obj_id 0
AnticoggingClient cog(0);
// Use the ESC Propeller Input Parser object
cog.is_enabled_.set(com, 1);
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Anticogging client in Matlab, all IQ communication code must be included in your path. This allows the creation of a AnticoggingClient object. See Table below for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an AnticoggingClient object with obj_id 0
cog = AnticoggingClient(’com’,com);
% Use the AnticoggingClient object
cog.set(’is_enabled’,1);
Python¶
To use the Anticogging Client in Python, include iqmotion
and create a module that has the Anticogging Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Anticogging Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("anticogging", "is_enabled", 1) # Turns on Anticogging
Message Table¶
Type ID 71 | Anticogging
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
table_size |
get |
uint16 |
Size of the anticogging table |
|
1 |
is_data_valid |
get |
uint8 |
bool |
Indicates if the cog information is valid. is_enabled must be called first to check the cog information. |
2 |
is_enabled |
get, set, save |
uint8 |
bool |
Indicates if anticogging is running. This will stay 0/false if the is_data_valid field is 0/false. |
3 |
erase |
set |
Erases the cog information. This is not recommended. |
||
4 |
left_shift |
get, set, save |
uint8 |
\[*2^x\]
|
Anticog multiplier. Modification is not recommended. |
Buzzer Control¶
The Buzzer Control handles all beeps and songs played by the motor. The controls mimic standard MIDI commands allowing simple translation from MIDI to Buzzer Control commands. The volume max parameter controls the absolute volume across all notes, measured in volts. To play a note on the buzzer, set the frequency by sending a ’hz’ command, set a relative volume by sending a ’volume’ command, set a note length by sending a ’duration’ command, and finally put the controller in note mode by sending ’ctrl note’.
Arduino¶
To use the Buzzer Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
BuzzerControlClient buz(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(buz.hz_,(uint16_t)1000);
ser.set(buz.volume_,(uint8_t)127);
ser.set(buz.duration_,(uint16_t)500);
ser.set(buz.ctrl_note_);
delay(1000);
}
C++¶
To use the Buzzer Control in C++, include buzzer control client.hpp. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "buzzer_control_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Buzzer Control object with obj_id 0
BuzzerControlClient buz(0);
// Use the Buzzer Control object
buz.hz_.set(com, 440); // A4
buz.volume_.set(com, 127); // Max volume
buz.duration_.set(com, 500); // 500ms
buz.ctrl_note_.set(com); // Note mode
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Buzzer Contol in Matlab, all IQ communication code must be included in your path. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BuzzerControlClient object with obj_id 0
buz = BuzzerControlClient(’com’,com);
% Use the BuzzerControlClient object
buz.set(’hz’,440); % A4
buz.set(’volume’,127); % Max volume
buz.set(’duration’,500); % 500ms
buz.set(’ctrl_note’);
Python¶
To use the Buzzer Control Client in Python, include iqmotion
and create a module that has the Buzzer Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Buzzer Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("buzzer_control", "hz", 440) # A4
fortiq.set("buzzer_control", "volume", 127) # Max Volume
fortiq.set("buzzer_control", "duration", 1000) # 1000ms
fortiq.set("buzzer_control", "ctrl_note") # Start the Note
Message Table¶
Type ID 61 | Buzzer Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
uint8 |
enum |
no_change = -1, brake=0, coast=1, note=2, song=3 |
1 |
ctrl_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry, motor passively coasts |
||
3 |
ctrl_note |
set |
Must have sent a ‘hz’ and ‘volume’ first |
||
4 |
volume_max |
get, set, save |
float |
V |
Uses this voltage command for maximum volume |
5 |
hz |
get, set |
uint16 |
hz |
Frequency of the note |
6 |
volume |
get, set |
uint8 |
0-127 |
Individual note volume as fraction of 127 |
7 |
duration |
get, set |
uint16 |
ms |
Note length. Assumed max (65535 ms) if not sent. |
Hobby Input¶
The Hobby Input gives the module the ability to read in a variety of hobby communication protocols. Supported protocols are standard 1-2ms PWM, OneShot125, OneShot42, MultiShot, and DShot (150 - 1200). The protocols are autodetected by default, but can be set to accept a single specific protocol. The values read by the Hobby Input are fed into a Parser object, such as the Servo Parser or the ESC Parser.
Arduino¶
To use Hobby Input in Arduino, ensure iq module communication.hpp is included. This allows the creation of a HobbyInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
HobbyInputClient hin(0);
void setup() {
ser.begin();
ser.set(hin.allowed_protocols_,(uint8_t)6);
ser.save(hin.allowed_protocols_);
}
void loop() {
}
C++¶
To use Hobby Input in C++, include hobby input client.hpp. This allows the creation of a HobbyInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "hobby_input_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Hobby Input object with obj_id 0
HobbyInputClient hin(0);
// Use the Hobby Input object
hin.allowed_protocols_.set(com, 3); // Set the protocol to OneShot42
hin.allowed_protocols_.save(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Hobby Input in Matlab, all IQ communication code must be included in your path. This allows the creation of a Hobby Input object. See Table 7 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a HobbyInputClient object with obj_id 0
hin = HobbyInputClient(’com’,com);
% Use the EscPropellerInputParserClient object
hin.set(’allowed_protocols’,3);
hin.save(’allowed_protocols’);
Python¶
To use the Hobby Input Client in Python, include iqmotion
and create a module that has the Hobby Input Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Hobby Input Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("hobby_input", "allowed_protocols", 4) # Set the protocol to MultiShot
fortiq.save("hobby_input", "allowed_protocols") # Save the protocol
Message Table¶
Type ID 76 | Hobby Input
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
allowed_protocols |
get, set, save |
uint8 |
enum |
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4, |
1 |
protocol |
get, set, save |
uint8 |
enum |
Persistent Memory¶
The Persistent Memory class controls the non-volatile memory. You can use this class to revert the motor to factory defaults.
Arduino¶
To use Persistent Memory in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PersistentMemoryClient mem(0);
void setup() {
ser.begin();
ser.set(mem.revert_to_default_);
}
void loop() {
}
C++¶
To use Persistent Memory in C++, include persistent memory client.hpp. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "persistent_memory_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Persistent Memory object with obj_id 0
PersistentMemoryClient mem(0);
// Use the Persistent Memory object
mem.revert_to_default_.set(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Persistent Memory in Matlab, all IQ communication code must be included in your path. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PersistentMemoryClient object with obj_id 0
mem = PersistentMemoryClient(’com’,com);
% Use the PersistentMemoryClient object
mem.set(’revert_to_default’);
Python¶
To use the Persistent Memory Client in Python, include iqmotion
and create a module that has the Persistent Memory Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Persistent Memory Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("persistent_memory", "revert_to_default") # erases saved values except for factory defaults
Message Table¶
Type ID 11 | Persistent Memory
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
erase |
set |
Erases all saved values including calibration data and product key. Highly not recommended. |
||
1 |
revert_to_default |
set |
Erases all saved values except for those set in factory. |
Power Monitor¶
The Power Monitor measures the power coming into the module. It reports input voltage and current as well as calculates power and energy consumed. A built in low pass filter with adjustable cutoff frequency smooths these values.
Arduino¶
To use Power Monitor in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PowerMonitorClient pwr(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float voltage = 0;
if(ser.get(pwr.volts_,voltage))
Serial.println(voltage);
}
C++¶
To use Power Monitor in C++, include power monitor client.hpp. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
#include "generic_interface.hpp"
#include "power_monitor_client.hpp"
float volts;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Power Monitor object with obj_id 0
PowerMontitorClient pwr(0);
// Use the Power Monitor object
pwr.volts_.get(com);
// Insert code for interfacing with hardware here
// Read response
volts = pwr.volts_.get_reply();
}
Matlab¶
To use Power Monitor in Matlab, all IQ communication code must be included in your path. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PowerMontitorClient object with obj_id 0
pwr = PowerMontitorClient(’com’,com);
% Use the PowerMontitorClient object
volts = pwr.get(’volts’);
Python¶
To use the Power Monitor Client in Python, include iqmotion
and create a module that has the Power Monitor Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Power Monitor Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
volts = fortiq.get("power_monitor", "volts") # returns the input voltage to module
print(f"Voltage coming into module: {volts}")
Message Table¶
Type ID 69 | Power Monitor
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
volts |
get |
float |
V |
Input voltage to module |
1 |
amps |
get |
float |
A |
Input amperage to module |
2 |
watts |
get |
float |
W |
Input wattage to module |
3 |
joules |
get |
float |
J |
Total energy consumed by module |
4 |
reset_joules |
set |
Sets joules to zero |
||
5 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
6 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
7 |
volts_raw |
get |
uint16 |
bit |
ADC value for the voltage measurement |
8 |
amps_raw |
get |
uint16 |
bit |
ADC value for the current measurement |
9 |
volts_gain |
get, set, save |
float |
V/bit |
Gain for the ADC to voltage conversion |
10 |
amps_gain |
get, set, save |
float |
A/bit |
Gain for the ADC to current conversion |
11 |
amps_bias |
get, set, save |
float |
bit |
Offset bias for the ADC to current conversion |
Serial Interface¶
The Serial client allows the user to change settings related to the serial communication interface, namely the baud rate. The set function of the baud rate behaves as both a set then a save. This allows the user to set and save using the initial baud rate, rather than having to disconnect and reconnect using the new baud rate in order to send a save. For this reason, the standard save function for the baud rate is disabled.
Arduino¶
To use Serial Interface in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin();
ser.set(sic.baud_rate_,(uint32_t)9600);
}
void loop() {
}
To start from 9600 baud and reset the baud back to the default 115200, use:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin(9600);
ser.set(sic.baud_rate_,(uint32_t)115200);
}
void loop() {
}
C++¶
To use Serial Interface in C++, include serial interface client.hpp. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore.
A minimal working example for the SerialInterfaceClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "serial_interface_client.hpp"
uint32_t baud_rate;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Serial Interface object with obj_id 0
SerialInterfaceClient serial_interface(0);
// Use the Serial Interface object
serial_interface.baud_rate_.get(com);
// Insert code for interfacing with hardware here
// baud_rate = serial_interface.baud_rate_.get_reply();
}
Matlab¶
To use Serial Interface in Matlab, all IQ communication code must be included in your path. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a Serial Interface object with obj_id 0
serial_interface = SerialInterfaceClient(’com’,com);
% Use the Serial Interface object
old_baud = serial_interface.get(’baud_rate’); // should be 115200
serial_interface.set(’baud_rate’, 9600);
% Note: the baud rate is now 9600. This com object uses 115200
% Make a new com object at 9600 baud to continue communication
com = MessageInterface(’COM18’,9600);
serial_interface = SerialInterfaceClient(’com’,com);
Python¶
To use the Serial Interface Client in Python, include iqmotion
and create a module that has the Serial Interface Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Serial Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
fortiq.set("serial_interface", "baud_rate", 9600) # change baud rate to 9600
Message Table¶
Type ID 16 | Serial Interface
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
baud_rate |
get, set |
uint32 |
hz |
Default is 115200. Reliable up to 2Mbps. Set also performs a save. |
Servo Input Parser¶
The Servo Input Parser is an interface between the Multi Turn Position Controller and the PWM based inputs like 1-2ms, OneShot, MultiShot, and DShot. This parser allows the user to control how ratiomatic values from the PWM input are translated. Inputs can be mapped to PWM control, voltage control, velocity control, and position control. Values are mapped between a minimum value and a maximum value, while their units are interpreted based on the mapping.
Arduino¶
To use Servo Input Parser in Arduino, ensure iq module communication.hpp is included. This allows the creation of a ServoInputParserClient object. See Table 6 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the ServoInputParserClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
ServoInputParserClient svo(0);
void setup() {
ser.begin();
ser.set(svo.mode_,(uint8_t)1); // Set to Voltage mode
ser.save(svo.mode_);
}
void loop() {
}
C++¶
To use Servo Input Parser in C++, include servo input parser client.hpp. This allows the creation of a ServoInputParserClient object. See Table 6 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the ServoInputParserClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "servo_input_parser_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Servo Input Parser object with obj_id 0
ServoInputParserClient svo(0);
// Use the Servo Input Parser object
svo.mode_.set(com, 3); // Position control mode
svo.mode_.save(com);
svo.unit_min_.set(com, -PI);
svo.unit_min_.save(com);
svo.unit_max_.set(com, PI);
svo.unit_max_.save(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Servo Input Parser in Matlab, all IQ communication code must be included in your path. This allows the creation of a ServoInputParserClient object. See Table 6 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the ServoInputParserClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a ServoInputParserClient object with obj_id 0
svo = ServoInputParserClient(’com’,com);
% Use the ServoInputParserClient object
svo.set(’mode’, 3); // Position control mode
svo.save(’mode’);
svo.set(’unit_min’, -pi);
svo.save(’unit_min’);
svo.set(’unit_max’, pi);
svo.save(’unit_max’);
Python¶
To use the Servo Input Parser Client in Python, include iqmotion
and create a module that has the Servo Input Parser Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Servo Input Parser Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
# Set Servo Limits
fortiq.set("servo_input_parser", "mode", 3) # Position Control Mode
fortiq.set("servo_input_parser", "unit_min", -math.pi) # Min position: -pi
fortiq.set("servo_input_parser", "unit_max", math.pi) # Max position: pi
# Save Servo Limits
fortiq.save("servo_input_parser", "mode")
fortiq.save("servo_input_parser", "unit_min")
fortiq.save("servo_input_parser", "unit_max")
Message Table¶
Type ID 78 | Servo Input Parser
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
mode |
get, set, save |
uint8 |
enum |
0 = PWM, 1 = Voltage, 2 = Velocity, 3 = Position |
1 |
unit_min |
get, set, save |
float |
(mode) |
Minimum value. Unit determined by mode. |
2 |
unit_max |
get, set, save |
float |
(mode) |
Maximum value. Unit determined by mode. |
System Control¶
System Control allows the user to perform low level tasks on the motor controller’s microcontroller and gather basic information. The motor’s uptime can be read and set, allowing for flexible timing and synchronizing. System Control also has a Module ID parameter, which allows motors to be bussed on a single serial line yet addressed uniquely. System Control is unique since its ID is always 0 even when the Module ID has been changed.
Arduino¶
To use System Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SystemControlClient sys(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float sys_time = 0.0f;
if(ser.get(sys.time_,sys_time))
Serial.println(sys_time);
}
C++¶
To use System Control in C++, include system control client.hpp. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "system_control_client.hpp"
float time;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a System Control object with obj_id 0
// System Control objects are always obj_id 0
SystemControlClient system_control(0);
// Use the System Control object
system_control.time_.get(com);
// Insert code for interfacing with hardware here
// time = system_control.time_.get_reply();
}
Matlab¶
To use System Control in Matlab, all IQ communication code must be included in your path. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a System Control object with obj_id 0
% System Control objects are always obj_id 0
system_control = SystemControlClient(’com’,com);
% Use the System Control object
time = system_control.get(’time’);
Python¶
To use the System Control Client in Python, include iqmotion
and create a module that has the System Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the System Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
FW = fortiq.get("system_control", "firmware_version") # Firmware Version Number
print(f"Firmware: {FW}")
Message Table¶
Type ID 5 | System Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
reboot_program |
set |
Reboots the motor controller with saved values |
||
1 |
reboot_boot_loader |
set |
Reboots into the boot loader |
||
2 |
dev_id |
get |
uint16 |
||
3 |
rev_id |
get |
uint16 |
||
4 |
uid1 |
get |
uint32 |
||
5 |
uid2 |
get |
uint32 |
||
6 |
uid3 |
get |
uint32 |
||
7 |
mem_size |
get |
uint16 |
Kb |
|
8 |
build_year |
get |
uint16 |
year |
|
9 |
build_month |
get |
uint8 |
mon |
|
10 |
build_day |
get |
uint8 |
day |
|
11 |
build_hour |
get |
uint8 |
hour |
|
12 |
build_minute |
get |
uint8 |
min |
|
13 |
build_second |
get |
uint8 |
s |
|
14 |
module_id |
get, set, save |
uint8 |
id |
The ID used for all obj_id on this module |
15 |
time |
get, set |
float |
s |
Internal clock time. If unchanged through software this is uptime |
16 |
firmware_version |
get |
uint32 |
ver |
|
17 |
hardware_version |
get, set, save |
uint32 |
ver |
|
18 |
electronics_version |
get, set, save |
uint32 |
ver |
|
19 |
firmware_valid |
get |
uint8 |
bool |
Temperature Estimator¶
The Temperature Estimator uses a conduction thermal model to estimate the temperature of components not directly sensed. In the motor modules the Temperature Estimator estimates the motor coil temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Estimator in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureEstimatorClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Estimator client in C++, include temperature estimator client.hpp. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_estimator_client.hpp"
float temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
TemperatureEstimatorClient temp_client(0);
// Use the Temperature Estimator Client
temp_client.temp_.get(com)
// [Insert code for interfacing with hardware here]
// temp = temp_client.temp_.get_reply();
}
Matlab¶
To use the Temperature Estimator client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureEstimatorClient object with obj_id 0
tes = TemperatureEstimatorClient(’com’,com);
% Use the TemperatureEstimatorClient object
coil_temp = tes.get(’temp’);
Python¶
To use the Temperature Estimator Client in Python, include iqmotion
and create a module that has the Temperature Estimator Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Estimator Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
temp = fortiq.get("temperature_estimator", "temp") # Estimated Motor Temperature
print(f"Estimated Motor Temperature: {temp}")
Message Table¶
Type ID 77 | Temperature Estimator
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
temp |
get |
float |
degC |
Temperature of the motor coils |
1 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
2 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
3 |
thermal_resistance |
get, set, save |
float |
K/W |
Model thermal resistance |
4 |
thermal_capacitance |
get, set, save |
float |
J/K |
Model thermal capacitance |
5 |
derate |
get |
Fix16 |
PU |
Amount of derating applied to motor [0 65536] where 65536 is normal operation |
Temperature Monitor UC¶
The Temperature Monitor Microcontroller reads, filters, and reports the microcontroller’s internal temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The filter’s cutoff frequency and the temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Monitor Microcontroller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureMonitorUcClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.uc_temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Monitor Microcontroller client in C++, include temperature monitor uc client.hpp. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_monitor_uc_client.hpp"
float uc_temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Monitor Microcontroller object with obj_id 0
TemperatureMonitorUcClient tuc(0);
// Use the Temperature Monitor Microcontroller object
tuc.uc_temp_.get(com);
// Insert code for interfacing with hardware here
// Read response
uc_temp = tuc.uc_temp_.get_reply();
}
Matlab¶
To use the Temperature Monitor Microcontroller client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureMonitorUcClient object with obj_id 0
tuc = TemperatureMonitorUcClient(’com’,com);
% Use the TemperatureMonitorUcClient object
uc_temp = tuc.get(’uc_temp’);
Python¶
To use the Temperature Monitor Microcontroller Client in Python, include iqmotion
and create a module that has the Temperature Monitor Microcontroller Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Monitor Microcontroller Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0 )
temp = fortiq.get("temperature_monitor_uc", "uc_temp") # Internal UC Temperature
print(f"Internal UC temperature: {temp}")
Message Table¶
Type ID 73 | Temperature Monitor Microcontroller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
uc_temp |
get |
float |
degC |
Temperature of the microcontroller |
1 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
2 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
3 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
4 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
5 |
derate |
get |
float |
PU |
Amount of derating applied to motor [0 1] |
Step Direction Firmware¶
Multi Turn Angle Control¶
The Multi-turn Angle Controller is a non-wrapping, PID, position controller. It is capable of storing angular to linear transmission information, mimicking a linear position controller. It also features a minimum jerk trajectory generator. The controller has a 32 trajectory buffer so that transitions between trajectories are seamless.
Arduino¶
To use Multi-turn Angle Controller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
MultiTurnAngleControlClient mult(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(mult.trajectory_angular_displacement_,3.14f);
ser.set(mult.trajectory_duration_,0.5f);
ser.set(mult.trajectory_angular_displacement_,0.0f);
ser.set(mult.trajectory_duration_,0.5f);
delay(1000);
}
C++¶
To use Multi-turn Angle Controller in C++, include multi turn angle control client.hpp. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "multi_turn_angle_control_client.hpp"
float angle;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Multi-turn Angle Controller object with obj_id 0
MultiTurnAngleControlClient angle_ctrl(0);
// Use the Multi-turn Angle Controller object
angle_ctrl.obs_angular_displacement_.get(com);
angle_ctrl.ctrl_angle_.set(com,0.0f);
// Insert code for interfacing with hardware here
// Read response
angle = angle_ctrl.ctrl_angle_.get_reply();
}
Matlab¶
To use Multi-turn Angle Controller in Matlab, all IQ communication code must be included in your path. This allows the creation of a MultiTurnAngleControlClient object. See Table 2 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the MultiTurnAngleControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a MultiTurnAngleControlClient object with obj_id 0
angle_ctrl = MultiTurnAngleControlClient(’com’,com);
% Use the MultiTurnAngleControlClient object
velocity_filtered = angle_ctrl.get(’obs_angular_displacement’);
angle_ctrl.set(’ctrl_angle’,0);
Python¶
To use the Multi-Turn Angle Control Client in Python, include iqmotion
and create a module that has the Multi-Turn Angle Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Multi-Turn Angle Control Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir") # Servo Firmware uses this client
# Set the trajectory for the motor to complete 1 full rotation
fortiq.set("multi_turn_angle_control", "trajectory_angular_displacement", 2*math.pi)
# Sets trajectory duration for 2 seconds
fortiq.set("multi_turn_angle_control", "trajectory_duration", 2)
Message Table¶
Type ID 59 | Multi-turn Angle Controller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
int8 |
enum |
no_change = -1, brake=0, coast=1, pwm=2, volts=3, velocity=4, angle=5, trajectory=6 |
1 |
ctrl_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry, motor passively coasts |
||
3 |
ctrl_angle |
get, set |
float |
rad |
Angular location command |
4 |
ctrl_velocity |
get, set |
float |
rad/s |
Angular velocity command |
5 |
angle_Kp |
get, set, save |
float |
V/rad |
Proportional gain |
6 |
angle_Ki |
get, set, save |
float |
V/(rad*s) |
Integral gain |
7 |
angle_Kd |
get, set, save |
float |
V/(rad/s) |
Derivative gain |
8 |
timeout |
get, set, save |
float |
s |
The controller must receive a message within this time otherwise it is set to coast mode |
9 |
ctrl_pwm |
get, set |
float |
pwm |
Spins motor with this throttle [-1, 1] |
10 |
ctrl_volts |
get, set |
float |
V |
Spins motor with this voltage |
11 |
obs_angular_displacement |
get, set |
float |
rad |
Observed angular location |
12 |
obs_angular_velocity |
get |
float |
rad/s |
Observed angular velocity |
13 |
meter_per_rad |
get, set, save |
float |
m/rad |
Transmission between angular and linear motion |
14 |
ctrl_linear_displacement |
get, set, |
float |
m |
Linear equivalent to ctrl_angle |
15 |
ctrl_linear_velocity |
get, set, |
float |
m/s |
Linear equivalent to ctrl_velocity |
16 |
obs_linear_displacement |
get, set, |
float |
m |
Observed linear location |
17 |
obs_linear_velocity |
get |
float |
m/s |
Observed linear velocity |
18 |
angular_speed_max |
get, set, save |
float |
rad/s |
The controller will never attempt to exceed this speed |
19 |
trajectory_angular_displacement |
get, set |
float |
rad |
Final absolute displacement of trajectory. |
20 |
trajectory_angular_velocity |
get, set |
float |
rad/s |
Final velocity of the trajectory. Defaults to 0. |
21 |
trajectory_angular_acceleration |
get, set |
float |
\[rad/s^2\]
|
Final acceleration of the trajectory. Defaults to 0. |
22 |
trajectory_duration |
set |
float |
s |
Duration of trajectory. Trajectory is executed or queued once this is sent. |
23 |
trajectory_linear_displacement |
get, set |
float |
m |
Final absolute displacement of trajectory. |
24 |
trajectory_linear_velocity |
get, set |
float |
m/s |
Final velocity of the trajectory. Defaults to 0. |
25 |
trajectory_linear_acceleration |
get, set |
float |
\[m/s^2\]
|
Final acceleration of the trajectory. Defaults to 0. |
26 |
trajectory_average_speed |
get, set |
float |
\[m/s^2\]
|
Average speed of a trajectory. Trajectory is executed or queued once this is sent. Must be $>0$. |
27 |
trajectory_queue_mode |
get, set, save |
int8 |
\[m/s^2\]
|
append=0, overwrite=1 |
Brushless Drive¶
Brushless Drive is the low level driver of the motor’s phase voltage.
Arduino¶
To use Brushless Drive in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BrushlessDriveClient object.
See Table 3 for available messages. All message objects use the Short
Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
#include <iq_module_communicaiton.hpp>
IqSerial ser(Serial2);
BrushlessDriveClient mot(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(mot.drive_spin_volts_,0.1f);
}
C++¶
To use Brushless Drive in C++, include brushless drive client.hpp. This allows the creation of a BrushlessDriveClient
object.
See Table 3 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "propeller_motor_control_client.hpp"
float voltage = 3.0f; // volts
int main(){
// Make a communication interface object
// This is what creates and parses packets
GenericInterface com;
// Make a Temperature Estimator Client object with obj_id 0
BrushlessDriveClient brushless(0);
// Drives the motor at 3 Volts
brushless.drive_spin_volts_.set(com, voltage);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Brushless Drive Controller in Matlab, all IQ communication code must be included in your path.
This allows the creation of a BrushlessDriveClient object. See Table 2 for available messages. All
message strings use the Short Names. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BrushlessDriveClient object with obj_id 0
drive = BrushlessDriveClient(’com’,com);
% Use the BrushlessDriveClient object
drive.set(’drive_spin_volts’,3.0);
Python¶
To use the Brushless Drive Client in Python, include iqmotion
and create a module that has the Brushless Drive Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the BrushlessDriveClient is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("brushless_drive", "drive_spin_volts", 5) # Spins motor at 5 volts
Message Table¶
Type ID 50 | Brushless Drive
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
Note |
---|---|---|---|---|---|---|
0 |
drive_mode |
get |
uint8 |
0 = phase_pwm, 1 = phase_volts, 2 = spin_pwm, 3 = spin_volts, 4 = brake, 5 = coast |
||
1 |
drive_phase_pwm |
set |
float |
pwm |
Open loop (gimbal) mode with this trottle [-1, 1]. Use with phase_angle. |
|
2 |
drive_phase_volts |
set |
float |
V |
Open loop (gimbal) mode with this voltage. Use with phase_angle. |
|
3 |
drive_spin_pwm |
set |
float |
pwm |
Spins motor with this throttle [-1, 1] |
|
4 |
drive_spin_volts |
set |
float |
V |
Spins motor with this voltage |
|
5 |
drive_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
|||
6 |
drive_coast |
set |
Disables all drive circuitry, motor passively coasts |
|||
7 |
drive_angle_offset |
get |
float |
rad |
Analogous to motor timing. This is internally computed by the motor. |
|
8 |
drive_pwm |
get |
float |
pwm |
The applied pwm after all computation and limiting [-1, 1] |
|
9 |
drive_volts |
get |
float |
V |
The applied pwm after all computation and limiting |
|
10 |
mech_lead_angle |
get |
float |
rad |
||
11 |
obs_supply_volts |
get |
float |
V |
Observed supply voltage |
|
12 |
obs_angle |
get |
float |
rad |
Observed motor angle |
|
13 |
obs_velocity |
get |
float |
rad/s |
Observed motor velocity |
|
14 |
motor_pole_pairs |
get, set, save |
uint16 |
Number of motor pole pairs (magnets/2) |
||
15 |
motor_emf_shape |
get, set, save |
uint8 |
|||
16 |
permute_wires |
get, set, save |
uint8 |
bool |
||
17 |
calibration_angle |
get, set, save |
float |
rad |
||
18 |
lead_time |
get, set, save |
float |
s |
||
19 |
commutation_hz |
get, set, save |
uint32 |
Hz |
Frequency of commutation. Higher frequencies run faster and more efficient, but may not give the controller enough computation time. |
|
20 |
phase_angle |
get, set |
float |
rad |
Angle used for open loop (gimbal) mode. Use with drive_phase_pwm or drive_phase_volts |
|
32 |
motor_Kv |
get, set, save |
float |
RPM/V |
Motor’s voltage constant |
|
33 |
motor_R_ohm |
get, set, save |
float |
ohm |
Motor’s resistance |
|
34 |
motor_I_max |
get, set, save |
float |
A |
Max allowable motor current |
|
35 |
volts_limit |
get, set, save |
float |
V |
Max regen voltage |
|
36 |
est_motor_amps |
get |
float |
A |
Estimated motor amps |
|
37 |
est_motor_torque |
get |
float |
Nm |
Estimated motor torque |
|
38 |
motor_redline_start |
get, set, save |
float |
rad/s |
Speed at which motor begins to derate |
|
39 |
motor_redline_end |
get, set, save |
float |
rad/s |
Speed at which the motor is fully derated |
|
40 |
motor_l |
get, set, save |
float |
H |
Cross inductance |
|
41 |
derate |
get |
int32 |
PU fix16 |
Amount of derating. No derate = 65536, full derate = 0 |
|
42 |
i_soft_start |
get, set, save |
float |
A |
Current at which motor begins to derate |
|
43 |
i_soft_end |
get, set, save |
float |
A |
Current at which the motor is fully derated |
Anticogging¶
Anticogging is the process of electronically canceling out cogging torque of a motor. Each motor is loaded with its unique cog information. This class allows enabling and disabling the anticogging process. Though this class can also manipulate the cog information it is not recommended to manipulate or erase this data as it is unrecoverable.
Arduino¶
To use the Anticogging in Arduino, ensure iq module communication.hpp is included. This allows the creation of a AnticoggingClient object. See Table below for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
BrushlessDriveClient mot(0);
AnticoggingClient cog(0);
void setup() {
ser.begin();
ser.set(mot.drive_spin_volts_,0.0f);
}
void loop() {
// Spin the motor with your hand and feel Anticogging turning on and off
ser.set(cog.is_enabled_,(uint8_t)1);
delay(2000);
ser.set(cog.is_enabled_,(uint8_t)0);
delay(2000);
}
C++¶
To use the Anticogging client in C++, include anticogging client.hpp. This allows the creation of an AnticoggingClient object. See Table below for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "anticogging_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a ESC Propeller Input Parser object with obj_id 0
AnticoggingClient cog(0);
// Use the ESC Propeller Input Parser object
cog.is_enabled_.set(com, 1);
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Anticogging client in Matlab, all IQ communication code must be included in your path. This allows the creation of a AnticoggingClient object. See Table below for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the AnticoggingClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an AnticoggingClient object with obj_id 0
cog = AnticoggingClient(’com’,com);
% Use the AnticoggingClient object
cog.set(’is_enabled’,1);
Python¶
To use the Anticogging Client in Python, include iqmotion
and create a module that has the Anticogging Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Anticogging Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("anticogging", "is_enabled", 1) # Turns on Anticogging
Message Table¶
Type ID 71 | Anticogging
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
table_size |
get |
uint16 |
Size of the anticogging table |
|
1 |
is_data_valid |
get |
uint8 |
bool |
Indicates if the cog information is valid. is_enabled must be called first to check the cog information. |
2 |
is_enabled |
get, set, save |
uint8 |
bool |
Indicates if anticogging is running. This will stay 0/false if the is_data_valid field is 0/false. |
3 |
erase |
set |
Erases the cog information. This is not recommended. |
||
4 |
left_shift |
get, set, save |
uint8 |
\[*2^x\]
|
Anticog multiplier. Modification is not recommended. |
Buzzer Control¶
The Buzzer Control handles all beeps and songs played by the motor. The controls mimic standard MIDI commands allowing simple translation from MIDI to Buzzer Control commands. The volume max parameter controls the absolute volume across all notes, measured in volts. To play a note on the buzzer, set the frequency by sending a ’hz’ command, set a relative volume by sending a ’volume’ command, set a note length by sending a ’duration’ command, and finally put the controller in note mode by sending ’ctrl note’.
Arduino¶
To use the Buzzer Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
BuzzerControlClient buz(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(buz.hz_,(uint16_t)1000);
ser.set(buz.volume_,(uint8_t)127);
ser.set(buz.duration_,(uint16_t)500);
ser.set(buz.ctrl_note_);
delay(1000);
}
C++¶
To use the Buzzer Control in C++, include buzzer control client.hpp. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "buzzer_control_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Buzzer Control object with obj_id 0
BuzzerControlClient buz(0);
// Use the Buzzer Control object
buz.hz_.set(com, 440); // A4
buz.volume_.set(com, 127); // Max volume
buz.duration_.set(com, 500); // 500ms
buz.ctrl_note_.set(com); // Note mode
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Buzzer Contol in Matlab, all IQ communication code must be included in your path. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BuzzerControlClient object with obj_id 0
buz = BuzzerControlClient(’com’,com);
% Use the BuzzerControlClient object
buz.set(’hz’,440); % A4
buz.set(’volume’,127); % Max volume
buz.set(’duration’,500); % 500ms
buz.set(’ctrl_note’);
Python¶
To use the Buzzer Control Client in Python, include iqmotion
and create a module that has the Buzzer Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Buzzer Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("buzzer_control", "hz", 440) # A4
fortiq.set("buzzer_control", "volume", 127) # Max Volume
fortiq.set("buzzer_control", "duration", 1000) # 1000ms
fortiq.set("buzzer_control", "ctrl_note") # Start the Note
Message Table¶
Type ID 61 | Buzzer Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
uint8 |
enum |
no_change = -1, brake=0, coast=1, note=2, song=3 |
1 |
ctrl_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry, motor passively coasts |
||
3 |
ctrl_note |
set |
Must have sent a ‘hz’ and ‘volume’ first |
||
4 |
volume_max |
get, set, save |
float |
V |
Uses this voltage command for maximum volume |
5 |
hz |
get, set |
uint16 |
hz |
Frequency of the note |
6 |
volume |
get, set |
uint8 |
0-127 |
Individual note volume as fraction of 127 |
7 |
duration |
get, set |
uint16 |
ms |
Note length. Assumed max (65535 ms) if not sent. |
Persistent Memory¶
The Persistent Memory class controls the non-volatile memory. You can use this class to revert the motor to factory defaults.
Arduino¶
To use Persistent Memory in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PersistentMemoryClient mem(0);
void setup() {
ser.begin();
ser.set(mem.revert_to_default_);
}
void loop() {
}
C++¶
To use Persistent Memory in C++, include persistent memory client.hpp. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "persistent_memory_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Persistent Memory object with obj_id 0
PersistentMemoryClient mem(0);
// Use the Persistent Memory object
mem.revert_to_default_.set(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Persistent Memory in Matlab, all IQ communication code must be included in your path. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PersistentMemoryClient object with obj_id 0
mem = PersistentMemoryClient(’com’,com);
% Use the PersistentMemoryClient object
mem.set(’revert_to_default’);
Python¶
To use the Persistent Memory Client in Python, include iqmotion
and create a module that has the Persistent Memory Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Persistent Memory Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("persistent_memory", "revert_to_default") # erases saved values except for factory defaults
Message Table¶
Type ID 11 | Persistent Memory
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
erase |
set |
Erases all saved values including calibration data and product key. Highly not recommended. |
||
1 |
revert_to_default |
set |
Erases all saved values except for those set in factory. |
Power Monitor¶
The Power Monitor measures the power coming into the module. It reports input voltage and current as well as calculates power and energy consumed. A built in low pass filter with adjustable cutoff frequency smooths these values.
Arduino¶
To use Power Monitor in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PowerMonitorClient pwr(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float voltage = 0;
if(ser.get(pwr.volts_,voltage))
Serial.println(voltage);
}
C++¶
To use Power Monitor in C++, include power monitor client.hpp. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
#include "generic_interface.hpp"
#include "power_monitor_client.hpp"
float volts;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Power Monitor object with obj_id 0
PowerMontitorClient pwr(0);
// Use the Power Monitor object
pwr.volts_.get(com);
// Insert code for interfacing with hardware here
// Read response
volts = pwr.volts_.get_reply();
}
Matlab¶
To use Power Monitor in Matlab, all IQ communication code must be included in your path. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PowerMontitorClient object with obj_id 0
pwr = PowerMontitorClient(’com’,com);
% Use the PowerMontitorClient object
volts = pwr.get(’volts’);
Python¶
To use the Power Monitor Client in Python, include iqmotion
and create a module that has the Power Monitor Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Power Monitor Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
volts = fortiq.get("power_monitor", "volts") # returns the input voltage to module
print(f"Voltage coming into module: {volts}")
Message Table¶
Type ID 69 | Power Monitor
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
volts |
get |
float |
V |
Input voltage to module |
1 |
amps |
get |
float |
A |
Input amperage to module |
2 |
watts |
get |
float |
W |
Input wattage to module |
3 |
joules |
get |
float |
J |
Total energy consumed by module |
4 |
reset_joules |
set |
Sets joules to zero |
||
5 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
6 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
7 |
volts_raw |
get |
uint16 |
bit |
ADC value for the voltage measurement |
8 |
amps_raw |
get |
uint16 |
bit |
ADC value for the current measurement |
9 |
volts_gain |
get, set, save |
float |
V/bit |
Gain for the ADC to voltage conversion |
10 |
amps_gain |
get, set, save |
float |
A/bit |
Gain for the ADC to current conversion |
11 |
amps_bias |
get, set, save |
float |
bit |
Offset bias for the ADC to current conversion |
Serial Interface¶
The Serial client allows the user to change settings related to the serial communication interface, namely the baud rate. The set function of the baud rate behaves as both a set then a save. This allows the user to set and save using the initial baud rate, rather than having to disconnect and reconnect using the new baud rate in order to send a save. For this reason, the standard save function for the baud rate is disabled.
Arduino¶
To use Serial Interface in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin();
ser.set(sic.baud_rate_,(uint32_t)9600);
}
void loop() {
}
To start from 9600 baud and reset the baud back to the default 115200, use:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin(9600);
ser.set(sic.baud_rate_,(uint32_t)115200);
}
void loop() {
}
C++¶
To use Serial Interface in C++, include serial interface client.hpp. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore.
A minimal working example for the SerialInterfaceClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "serial_interface_client.hpp"
uint32_t baud_rate;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Serial Interface object with obj_id 0
SerialInterfaceClient serial_interface(0);
// Use the Serial Interface object
serial_interface.baud_rate_.get(com);
// Insert code for interfacing with hardware here
// baud_rate = serial_interface.baud_rate_.get_reply();
}
Matlab¶
To use Serial Interface in Matlab, all IQ communication code must be included in your path. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a Serial Interface object with obj_id 0
serial_interface = SerialInterfaceClient(’com’,com);
% Use the Serial Interface object
old_baud = serial_interface.get(’baud_rate’); // should be 115200
serial_interface.set(’baud_rate’, 9600);
% Note: the baud rate is now 9600. This com object uses 115200
% Make a new com object at 9600 baud to continue communication
com = MessageInterface(’COM18’,9600);
serial_interface = SerialInterfaceClient(’com’,com);
Python¶
To use the Serial Interface Client in Python, include iqmotion
and create a module that has the Serial Interface Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Serial Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("serial_interface", "baud_rate", 9600) # change baud rate to 9600
Message Table¶
Type ID 16 | Serial Interface
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
baud_rate |
get, set |
uint32 |
hz |
Default is 115200. Reliable up to 2Mbps. Set also performs a save. |
Step Direction Input¶
The Step Direction Input allows the module to accept commands normally used by stepper motor drivers. One signal line controls the direction of motor rotation, while each rising and falling edge of the other line advances the motor’s target angle by a user programmable amount. Steps can be as small as 1/65536th of a rotation (9.5874e-05 radians). Step sizes that are a multiple of 1/65536th of a rotation will be exact, while non-multiples will be floored to the nearest multiple. There is virtually no upper limit on the step size. Use negative step sizes if the direction of the motor is reversed from desired.
Arduino¶
To use Step Direction Input in Arduino, ensure iq module communication.hpp is included. This allows the creation of a StepDirectionInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the StepDirectionInputClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
StepDirectionInputClient sdi(0);
void setup() {
ser.begin();
ser.set(sdi.angle_step_,0.125f); // set to 8 edges per rotation
ser.save(sdi.angle_step_);
}
void loop() {
}
C++¶
To use Step Direction Input in C++, include step direction input.hpp. This allows the creation of a StepDirectionInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the StepDirectionInputClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "step_direction_input_client.hpp"
float angle_step;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Step Direction Input object with obj_id 0
StepDirectionInputClient step_dir(0);
// Use the Step Direction Input object
step_dir.angle_step_.set(com,2.0f*PI/65536.0f); // Set the minimum step angle
step_dir.angle_step_.save(com);
step_dir.angle_step_.get(com);
// Insert code for interfacing with hardware here
// Read response
angle_step = step_dir.angle_step_.get_reply();
}
Matlab¶
To use Step Direction in Matlab, all IQ communication code must be included in your path. This allows the creation of a StepDirectionInputClient object. See Table 7 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the StepDirectionInputClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a MultiTurnAngleControlClient object with obj_id 0
step_dir = StepDirectionInputClient(’com’,com);
% Use the StepDirectionInputClient object
angle_step = step_dir.get(’angle_step’);
step_dir.set(’angle_step’,2*pi/65536);
step_dir.save(’angle_step’);
Python¶
To use the Step Direction Input Client in Python, include iqmotion
and create a module that has the Step Direction Input Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Step Direction Input Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
fortiq.set("step_direction_input", "angle_step", (2*math.pi)/65536)) # Set min step angle
Message Table¶
Type ID 58 | Step Direction Input
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
angle |
get, set |
float |
rad |
Current commanded angle |
1 |
angle_step |
get, set, save |
float |
rad |
Angle step per step edge |
System Control¶
System Control allows the user to perform low level tasks on the motor controller’s microcontroller and gather basic information. The motor’s uptime can be read and set, allowing for flexible timing and synchronizing. System Control also has a Module ID parameter, which allows motors to be bussed on a single serial line yet addressed uniquely. System Control is unique since its ID is always 0 even when the Module ID has been changed.
Arduino¶
To use System Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SystemControlClient sys(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float sys_time = 0.0f;
if(ser.get(sys.time_,sys_time))
Serial.println(sys_time);
}
C++¶
To use System Control in C++, include system control client.hpp. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "system_control_client.hpp"
float time;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a System Control object with obj_id 0
// System Control objects are always obj_id 0
SystemControlClient system_control(0);
// Use the System Control object
system_control.time_.get(com);
// Insert code for interfacing with hardware here
// time = system_control.time_.get_reply();
}
Matlab¶
To use System Control in Matlab, all IQ communication code must be included in your path. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a System Control object with obj_id 0
% System Control objects are always obj_id 0
system_control = SystemControlClient(’com’,com);
% Use the System Control object
time = system_control.get(’time’);
Python¶
To use the System Control Client in Python, include iqmotion
and create a module that has the System Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the System Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
FW = fortiq.get("system_control", "firmware_version") # Firmware Version Number
print(f"Firmware: {FW}")
Message Table¶
Type ID 5 | System Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
reboot_program |
set |
Reboots the motor controller with saved values |
||
1 |
reboot_boot_loader |
set |
Reboots into the boot loader |
||
2 |
dev_id |
get |
uint16 |
||
3 |
rev_id |
get |
uint16 |
||
4 |
uid1 |
get |
uint32 |
||
5 |
uid2 |
get |
uint32 |
||
6 |
uid3 |
get |
uint32 |
||
7 |
mem_size |
get |
uint16 |
Kb |
|
8 |
build_year |
get |
uint16 |
year |
|
9 |
build_month |
get |
uint8 |
mon |
|
10 |
build_day |
get |
uint8 |
day |
|
11 |
build_hour |
get |
uint8 |
hour |
|
12 |
build_minute |
get |
uint8 |
min |
|
13 |
build_second |
get |
uint8 |
s |
|
14 |
module_id |
get, set, save |
uint8 |
id |
The ID used for all obj_id on this module |
15 |
time |
get, set |
float |
s |
Internal clock time. If unchanged through software this is uptime |
16 |
firmware_version |
get |
uint32 |
ver |
|
17 |
hardware_version |
get, set, save |
uint32 |
ver |
|
18 |
electronics_version |
get, set, save |
uint32 |
ver |
|
19 |
firmware_valid |
get |
uint8 |
bool |
Temperature Estimator¶
The Temperature Estimator uses a conduction thermal model to estimate the temperature of components not directly sensed. In the motor modules the Temperature Estimator estimates the motor coil temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Estimator in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureEstimatorClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Estimator client in C++, include temperature estimator client.hpp. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_estimator_client.hpp"
float temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
TemperatureEstimatorClient temp_client(0);
// Use the Temperature Estimator Client
temp_client.temp_.get(com)
// [Insert code for interfacing with hardware here]
// temp = temp_client.temp_.get_reply();
}
Matlab¶
To use the Temperature Estimator client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureEstimatorClient object with obj_id 0
tes = TemperatureEstimatorClient(’com’,com);
% Use the TemperatureEstimatorClient object
coil_temp = tes.get(’temp’);
Python¶
To use the Temperature Estimator Client in Python, include iqmotion
and create a module that has the Temperature Estimator Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Estimator Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
temp = fortiq.get("temperature_estimator", "temp") # Estimated Motor Temperature
print(f"Estimated Motor Temperature: {temp}")
Message Table¶
Type ID 77 | Temperature Estimator
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
temp |
get |
float |
degC |
Temperature of the motor coils |
1 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
2 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
3 |
thermal_resistance |
get, set, save |
float |
K/W |
Model thermal resistance |
4 |
thermal_capacitance |
get, set, save |
float |
J/K |
Model thermal capacitance |
5 |
derate |
get |
Fix16 |
PU |
Amount of derating applied to motor [0 65536] where 65536 is normal operation |
Temperature Monitor UC¶
The Temperature Monitor Microcontroller reads, filters, and reports the microcontroller’s internal temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The filter’s cutoff frequency and the temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Monitor Microcontroller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureMonitorUcClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.uc_temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Monitor Microcontroller client in C++, include temperature monitor uc client.hpp. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_monitor_uc_client.hpp"
float uc_temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Monitor Microcontroller object with obj_id 0
TemperatureMonitorUcClient tuc(0);
// Use the Temperature Monitor Microcontroller object
tuc.uc_temp_.get(com);
// Insert code for interfacing with hardware here
// Read response
uc_temp = tuc.uc_temp_.get_reply();
}
Matlab¶
To use the Temperature Monitor Microcontroller client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureMonitorUcClient object with obj_id 0
tuc = TemperatureMonitorUcClient(’com’,com);
% Use the TemperatureMonitorUcClient object
uc_temp = tuc.get(’uc_temp’);
Python¶
To use the Temperature Monitor Microcontroller Client in Python, include iqmotion
and create a module that has the Temperature Monitor Microcontroller Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Monitor Microcontroller Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="stepdir")
temp = fortiq.get("temperature_monitor_uc", "uc_temp") # Internal UC Temperature
print(f"Internal UC temperature: {temp}")
Message Table¶
Type ID 73 | Temperature Monitor Microcontroller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
uc_temp |
get |
float |
degC |
Temperature of the microcontroller |
1 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
2 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
3 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
4 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
5 |
derate |
get |
float |
PU |
Amount of derating applied to motor [0 1] |
Speed Firmware¶
Propeller Motor Control¶
The Propeller Motor Controller is an open and closed loop controller designed to drive propeller loads. If given thrust coefficients, this controller can be commanded in units of thrust, seamlessly accepting values from flight controllers in their native units. An added benefit is the decoupling of flight controller gains from motor choice, propeller choice, battery level, and more. Thrust commands are fed into a PID velocity controller with a second order polynomial feed forward. This sits on top of a voltage controller, which compensates for varying input voltages. Finally, the core is a raw PWM controller. Any of the above controllers can be used by the user.
Note
The Propeller Motor Control will timeout and beep 3 times if it hasn’t received a command before the timeout is reached. You can extend the timeout by changing the timeout client entry
Arduino¶
To use Propeller Motor Controller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PropellerMotorControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PropellerMotorControlMessaging is:
#include <iq_module_communicaiton.hpp>
IqSerial ser(Serial2);
PropellerMotorControlClient prop(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(prop.ctrl_velocity_,50.0f);
}
C++¶
To use Propeller Motor Controller in C++, include propeller motor control client.hpp. This allows the creation of a PropellerMotorControlClient object. See Table 2 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PropellerMotorControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "propeller_motor_control_client.hpp"
float velocity = 100.0f; // rad/s
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Propeller Motor Controller object with obj_id 0
PropellerMotorControlClient prop(0);
// Use the Propeller Motor Controller object
prop.ctrl_velocity_.set(com, velocity);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Propeller Motor Controller in Matlab, all IQ communication code must be included in your path. This allows the creation of a PropellerMotorControlClient object. See Table 2 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PropellerMotorControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PropellerMotorControlClient object with obj_id 0
prop = PropellerMotorControlClient(’com’,com);
% Use the PropellerMotorControlClient object
prop.set(’ctrl_velocity’,100.0);
Python¶
To use the Propeller Motor Control Client in Python, include iqmotion
and create a module that has the Propeller Motor Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Propeller Motor Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("propeller_motor_control", "ctrl_velocity", 5) # Supplies 5V to motor
Message Table¶
Type ID 52 | Propeller Motor Controller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
int8 |
enum |
-1 = no change, 0 = brake, 1 = coast, 2 = pwm, 3 = volts, 4 = velocity, 5 = thrust |
1 |
ctrl_brake |
set |
Shorts motor leads, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry |
||
3 |
ctrl_pwm |
get, set |
float |
PWM |
[-1, 1] fraction of input voltage |
4 |
ctrl_volts |
get, set |
float |
V |
[-supply, supply] Voltage to apply to motor |
5 |
ctrl_velocity |
get, set |
float |
rad/s |
Angular velocity command |
6 |
ctrl_thrust |
get, set |
float |
N |
Thrust command (requires kt values) |
7 |
velocity_kp |
get, set, save |
float |
V/(rad/s) |
Proportional gain |
8 |
velocity_ki |
get, set, save |
float |
V/(rad) |
Integral gain |
9 |
velocity_kd |
get, set, save |
float |
V/(rad/s2) |
Derivative gain |
10 |
velocity_ff0 |
get, set, save |
float |
V |
Feed forward 0th order term |
11 |
velocity_ff1 |
get, set, save |
float |
V/(rad/s) |
Feed forward 1st order term |
12 |
velocity_ff2 |
get, set, save |
float |
V/(rad/s)2 |
Feed forward 2nd order term |
13 |
propeller_kt_pos |
get, set, save |
float |
N/(rad/s)2 |
T = ktω2thrust constant in positive direction |
14 |
propeller_kt_neg |
get, set, save |
float |
N/(rad/s)2 |
T = ktω2 thrust constant in negative direction |
15 |
timeout |
get, set, save |
float |
s |
The controller must receive a message within thistime otherwise it is set to coast mode |
16 |
input_filter_fc |
get, set, save |
uint32 |
Hz |
Low pass cutoff frequency for input commands |
Brushless Drive¶
Brushless Drive is the low level driver of the motor’s phase voltage.
Arduino¶
To use Brushless Drive in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BrushlessDriveClient object.
See Table 3 for available messages. All message objects use the Short
Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
#include <iq_module_communicaiton.hpp>
IqSerial ser(Serial2);
BrushlessDriveClient mot(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(mot.drive_spin_volts_,0.1f);
}
C++¶
To use Brushless Drive in C++, include brushless drive client.hpp. This allows the creation of a BrushlessDriveClient
object.
See Table 3 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "propeller_motor_control_client.hpp"
float voltage = 3.0f; // volts
int main(){
// Make a communication interface object
// This is what creates and parses packets
GenericInterface com;
// Make a Temperature Estimator Client object with obj_id 0
BrushlessDriveClient brushless(0);
// Drives the motor at 3 Volts
brushless.drive_spin_volts_.set(com, voltage);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Brushless Drive Controller in Matlab, all IQ communication code must be included in your path.
This allows the creation of a BrushlessDriveClient object. See Table 2 for available messages. All
message strings use the Short Names. All messages use the standard Get/Set/Save
functions.
A minimal working example for the BrushlessDriveClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BrushlessDriveClient object with obj_id 0
drive = BrushlessDriveClient(’com’,com);
% Use the BrushlessDriveClient object
drive.set(’drive_spin_volts’,3.0);
Python¶
To use the Brushless Drive Client in Python, include iqmotion
and create a module that has the Brushless Drive Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the BrushlessDriveClient is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("brushless_drive", "drive_spin_volts", 5) # Spins motor at 5 volts
Message Table¶
Type ID 50 | Brushless Drive
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
Note |
---|---|---|---|---|---|---|
0 |
drive_mode |
get |
uint8 |
0 = phase_pwm, 1 = phase_volts, 2 = spin_pwm, 3 = spin_volts, 4 = brake, 5 = coast |
||
1 |
drive_phase_pwm |
set |
float |
pwm |
Open loop (gimbal) mode with this trottle [-1, 1]. Use with phase_angle. |
|
2 |
drive_phase_volts |
set |
float |
V |
Open loop (gimbal) mode with this voltage. Use with phase_angle. |
|
3 |
drive_spin_pwm |
set |
float |
pwm |
Spins motor with this throttle [-1, 1] |
|
4 |
drive_spin_volts |
set |
float |
V |
Spins motor with this voltage |
|
5 |
drive_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
|||
6 |
drive_coast |
set |
Disables all drive circuitry, motor passively coasts |
|||
7 |
drive_angle_offset |
get |
float |
rad |
Analogous to motor timing. This is internally computed by the motor. |
|
8 |
drive_pwm |
get |
float |
pwm |
The applied pwm after all computation and limiting [-1, 1] |
|
9 |
drive_volts |
get |
float |
V |
The applied pwm after all computation and limiting |
|
10 |
mech_lead_angle |
get |
float |
rad |
||
11 |
obs_supply_volts |
get |
float |
V |
Observed supply voltage |
|
12 |
obs_angle |
get |
float |
rad |
Observed motor angle |
|
13 |
obs_velocity |
get |
float |
rad/s |
Observed motor velocity |
|
14 |
motor_pole_pairs |
get, set, save |
uint16 |
Number of motor pole pairs (magnets/2) |
||
15 |
motor_emf_shape |
get, set, save |
uint8 |
|||
16 |
permute_wires |
get, set, save |
uint8 |
bool |
||
17 |
calibration_angle |
get, set, save |
float |
rad |
||
18 |
lead_time |
get, set, save |
float |
s |
||
19 |
commutation_hz |
get, set, save |
uint32 |
Hz |
Frequency of commutation. Higher frequencies run faster and more efficient, but may not give the controller enough computation time. |
|
20 |
phase_angle |
get, set |
float |
rad |
Angle used for open loop (gimbal) mode. Use with drive_phase_pwm or drive_phase_volts |
|
32 |
motor_Kv |
get, set, save |
float |
RPM/V |
Motor’s voltage constant |
|
33 |
motor_R_ohm |
get, set, save |
float |
ohm |
Motor’s resistance |
|
34 |
motor_I_max |
get, set, save |
float |
A |
Max allowable motor current |
|
35 |
volts_limit |
get, set, save |
float |
V |
Max regen voltage |
|
36 |
est_motor_amps |
get |
float |
A |
Estimated motor amps |
|
37 |
est_motor_torque |
get |
float |
Nm |
Estimated motor torque |
|
38 |
motor_redline_start |
get, set, save |
float |
rad/s |
Speed at which motor begins to derate |
|
39 |
motor_redline_end |
get, set, save |
float |
rad/s |
Speed at which the motor is fully derated |
|
40 |
motor_l |
get, set, save |
float |
H |
Cross inductance |
|
41 |
derate |
get |
int32 |
PU fix16 |
Amount of derating. No derate = 65536, full derate = 0 |
|
42 |
i_soft_start |
get, set, save |
float |
A |
Current at which motor begins to derate |
|
43 |
i_soft_end |
get, set, save |
float |
A |
Current at which the motor is fully derated |
Buzzer Control¶
The Buzzer Control handles all beeps and songs played by the motor. The controls mimic standard MIDI commands allowing simple translation from MIDI to Buzzer Control commands. The volume max parameter controls the absolute volume across all notes, measured in volts. To play a note on the buzzer, set the frequency by sending a ’hz’ command, set a relative volume by sending a ’volume’ command, set a note length by sending a ’duration’ command, and finally put the controller in note mode by sending ’ctrl note’.
Arduino¶
To use the Buzzer Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
BuzzerControlClient buz(0);
void setup() {
ser.begin();
}
void loop() {
ser.set(buz.hz_,(uint16_t)1000);
ser.set(buz.volume_,(uint8_t)127);
ser.set(buz.duration_,(uint16_t)500);
ser.set(buz.ctrl_note_);
delay(1000);
}
C++¶
To use the Buzzer Control in C++, include buzzer control client.hpp. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "buzzer_control_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Buzzer Control object with obj_id 0
BuzzerControlClient buz(0);
// Use the Buzzer Control object
buz.hz_.set(com, 440); // A4
buz.volume_.set(com, 127); // Max volume
buz.duration_.set(com, 500); // 500ms
buz.ctrl_note_.set(com); // Note mode
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Buzzer Contol in Matlab, all IQ communication code must be included in your path. This allows the creation of a BuzzerControlClient object. See Table 5 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the BuzzerControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BuzzerControlClient object with obj_id 0
buz = BuzzerControlClient(’com’,com);
% Use the BuzzerControlClient object
buz.set(’hz’,440); % A4
buz.set(’volume’,127); % Max volume
buz.set(’duration’,500); % 500ms
buz.set(’ctrl_note’);
Python¶
To use the Buzzer Control Client in Python, include iqmotion
and create a module that has the Buzzer Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Buzzer Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("buzzer_control", "hz", 440) # A4
fortiq.set("buzzer_control", "volume", 127) # Max Volume
fortiq.set("buzzer_control", "duration", 1000) # 1000ms
fortiq.set("buzzer_control", "ctrl_note") # Start the Note
Message Table¶
Type ID 61 | Buzzer Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
ctrl_mode |
get |
uint8 |
enum |
no_change = -1, brake=0, coast=1, note=2, song=3 |
1 |
ctrl_brake |
set |
Shorts motor phases, slows motor down dissipating energy in motor |
||
2 |
ctrl_coast |
set |
Disables all drive circuitry, motor passively coasts |
||
3 |
ctrl_note |
set |
Must have sent a ‘hz’ and ‘volume’ first |
||
4 |
volume_max |
get, set, save |
float |
V |
Uses this voltage command for maximum volume |
5 |
hz |
get, set |
uint16 |
hz |
Frequency of the note |
6 |
volume |
get, set |
uint8 |
0-127 |
Individual note volume as fraction of 127 |
7 |
duration |
get, set |
uint16 |
ms |
Note length. Assumed max (65535 ms) if not sent. |
ESC Propeller Input Parser¶
The ESC Propeller Input Parser is an interface between the Propeller Motor Controller and the PWM based inputs like 1-2ms, OneShot, MultiShot, and DShot. This parser allows the user to control how ratiomatic values from the PWM input are translated. Inputs can be mapped to PWM control, voltage control, velocity control, and thrust control. Values can be interpreted as signed/unsigned and clockwise/counter clockwise.
Arduino¶
To use ESC Propeller Input Parser in Arduino, ensure iq module communication.hpp is included. This allows the creation of a EscPropellerInputParserClient object. See Table 6 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the EscPropellerInputParserClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
EscPropellerInputParserClient esc(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float vel_max = 0;
ser.get(esc.velocity_max_,vel_max);
Serial.println(vel_max);
}
C++¶
To use ESC Propeller Input Parser in C++, include esc propeller input parser client.hpp. This allows the creation of a EscPropellerInputParserClient object. See Table 6 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the EscPropellerInputParserClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "esc_propeller_input_parser_client.hpp"
float velocity_max = 1000.0f; // rad/s
void main(){
// Make a communication interface object
GenericInterface com;
// Make a ESC Propeller Input Parser object with obj_id 0
EscPropellerInputParserClient esc(0);
// Use the ESC Propeller Input Parser object
esc.velocity_max_.set(com, velocity_max);
// Insert code for interfacing with hardware here
}
Matlab¶
To use ESC Propeller Input Parser in Matlab, all IQ communication code must be included in your path. This allows the creation of a EscPropellerInputParserClient object. See Table 6 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the EscPropellerInputParserClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a EscPropellerInputParserClient object with obj_id 0
esc = EscPropellerInputParserClient(’com’,com);
% Use the EscPropellerInputParserClient object
esc.set(’velocity_max’,1000);
Python¶
To use the ESC Propeller Input Parser Client in Python, include iqmotion
and create a module that has the ESC Propeller Input Parser Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the ESC Propeller Input Parser Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("esc_propeller_input_parser", "velocity_max", 1000) # Set max Velocity to 1000rad/s
Message Table¶
Type ID 60 | ESC Propeller Input Parser
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
mode |
get, set, save |
uint8 |
enum |
0 = PWM, 1 = Voltage, 2 = Velocity, 3 = Thrust |
1 |
raw_value |
get, set |
float |
PU |
Input value [0, 1] |
2 |
map |
get, set, save |
uint8 |
enum |
0 = linear, 1 = sqrt |
3 |
sign |
get, set, save |
uint8 |
enum |
0 = unconfigured, 1 = signed positive, 2 = signed negative, 3 = unsigned positive, 4 = unsigned negative |
4 |
volts_max |
get, set, save |
float |
V |
Maximum voltage to apply to motor, raw_value scaled to [-volts_max, volts_max] or [0, volts_max] |
5 |
velocity_max |
get, set, save |
float |
rad/s |
Maximum angular velocity command, raw_value scaled to [-velocity_max, velocity_max] or [0, velocity_max] |
6 |
thrust_max |
get, set, save |
float |
N |
Maximum thrust command (requires kt values), raw_value scaled to [-thrust_max, thrust_max] or [0, thrust_max] |
Hobby Input¶
The Hobby Input gives the module the ability to read in a variety of hobby communication protocols. Supported protocols are standard 1-2ms PWM, OneShot125, OneShot42, MultiShot, and DShot (150 - 1200). The protocols are autodetected by default, but can be set to accept a single specific protocol. The values read by the Hobby Input are fed into a Parser object, such as the Servo Parser or the ESC Parser.
Arduino¶
To use Hobby Input in Arduino, ensure iq module communication.hpp is included. This allows the creation of a HobbyInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
HobbyInputClient hin(0);
void setup() {
ser.begin();
ser.set(hin.allowed_protocols_,(uint8_t)6);
ser.save(hin.allowed_protocols_);
}
void loop() {
}
C++¶
To use Hobby Input in C++, include hobby input client.hpp. This allows the creation of a HobbyInputClient object. See Table 7 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "hobby_input_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Hobby Input object with obj_id 0
HobbyInputClient hin(0);
// Use the Hobby Input object
hin.allowed_protocols_.set(com, 3); // Set the protocol to OneShot42
hin.allowed_protocols_.save(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Hobby Input in Matlab, all IQ communication code must be included in your path. This allows the creation of a Hobby Input object. See Table 7 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the HobbyInputClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a HobbyInputClient object with obj_id 0
hin = HobbyInputClient(’com’,com);
% Use the EscPropellerInputParserClient object
hin.set(’allowed_protocols’,3);
hin.save(’allowed_protocols’);
Python¶
To use the Hobby Input Client in Python, include iqmotion
and create a module that has the Hobby Input Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Hobby Input Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("hobby_input", "allowed_protocols", 4) # Set the protocol to MultiShot
fortiq.save("hobby_input", "allowed_protocols") # Save the protocol
Message Table¶
Type ID 76 | Hobby Input
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
allowed_protocols |
get, set, save |
uint8 |
enum |
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4, |
1 |
protocol |
get, set, save |
uint8 |
enum |
Persistent Memory¶
The Persistent Memory class controls the non-volatile memory. You can use this class to revert the motor to factory defaults.
Arduino¶
To use Persistent Memory in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PersistentMemoryClient mem(0);
void setup() {
ser.begin();
ser.set(mem.revert_to_default_);
}
void loop() {
}
C++¶
To use Persistent Memory in C++, include persistent memory client.hpp. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "persistent_memory_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Persistent Memory object with obj_id 0
PersistentMemoryClient mem(0);
// Use the Persistent Memory object
mem.revert_to_default_.set(com);
// Insert code for interfacing with hardware here
}
Matlab¶
To use Persistent Memory in Matlab, all IQ communication code must be included in your path. This allows the creation of a PersistentMemoryClient object. See Table 13 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PersistentMemoryClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PersistentMemoryClient object with obj_id 0
mem = PersistentMemoryClient(’com’,com);
% Use the PersistentMemoryClient object
mem.set(’revert_to_default’);
Python¶
To use the Persistent Memory Client in Python, include iqmotion
and create a module that has the Persistent Memory Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Persistent Memory Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("persistent_memory", "revert_to_default") # erases saved values except for factory defaults
Message Table¶
Type ID 11 | Persistent Memory
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
erase |
set |
Erases all saved values including calibration data and product key. Highly not recommended. |
||
1 |
revert_to_default |
set |
Erases all saved values except for those set in factory. |
Power Monitor¶
The Power Monitor measures the power coming into the module. It reports input voltage and current as well as calculates power and energy consumed. A built in low pass filter with adjustable cutoff frequency smooths these values.
Arduino¶
To use Power Monitor in Arduino, ensure iq module communication.hpp is included. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PowerMonitorClient pwr(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float voltage = 0;
if(ser.get(pwr.volts_,voltage))
Serial.println(voltage);
}
C++¶
To use Power Monitor in C++, include power monitor client.hpp. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
#include "generic_interface.hpp"
#include "power_monitor_client.hpp"
float volts;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Power Monitor object with obj_id 0
PowerMontitorClient pwr(0);
// Use the Power Monitor object
pwr.volts_.get(com);
// Insert code for interfacing with hardware here
// Read response
volts = pwr.volts_.get_reply();
}
Matlab¶
To use Power Monitor in Matlab, all IQ communication code must be included in your path. This allows the creation of a PowerMonitorClient object. See Table 9 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the PowerMonitorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PowerMontitorClient object with obj_id 0
pwr = PowerMontitorClient(’com’,com);
% Use the PowerMontitorClient object
volts = pwr.get(’volts’);
Python¶
To use the Power Monitor Client in Python, include iqmotion
and create a module that has the Power Monitor Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Power Monitor Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
volts = fortiq.get("power_monitor", "volts") # returns the input voltage to module
print(f"Voltage coming into module: {volts}")
Message Table¶
Type ID 69 | Power Monitor
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
volts |
get |
float |
V |
Input voltage to module |
1 |
amps |
get |
float |
A |
Input amperage to module |
2 |
watts |
get |
float |
W |
Input wattage to module |
3 |
joules |
get |
float |
J |
Total energy consumed by module |
4 |
reset_joules |
set |
Sets joules to zero |
||
5 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
6 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
7 |
volts_raw |
get |
uint16 |
bit |
ADC value for the voltage measurement |
8 |
amps_raw |
get |
uint16 |
bit |
ADC value for the current measurement |
9 |
volts_gain |
get, set, save |
float |
V/bit |
Gain for the ADC to voltage conversion |
10 |
amps_gain |
get, set, save |
float |
A/bit |
Gain for the ADC to current conversion |
11 |
amps_bias |
get, set, save |
float |
bit |
Offset bias for the ADC to current conversion |
Serial Interface¶
The Serial client allows the user to change settings related to the serial communication interface, namely the baud rate. The set function of the baud rate behaves as both a set then a save. This allows the user to set and save using the initial baud rate, rather than having to disconnect and reconnect using the new baud rate in order to send a save. For this reason, the standard save function for the baud rate is disabled.
Arduino¶
To use Serial Interface in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin();
ser.set(sic.baud_rate_,(uint32_t)9600);
}
void loop() {
}
To start from 9600 baud and reset the baud back to the default 115200, use:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SerialInterfaceClient sic(0);
void setup() {
ser.begin(9600);
ser.set(sic.baud_rate_,(uint32_t)115200);
}
void loop() {
}
C++¶
To use Serial Interface in C++, include serial interface client.hpp. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message objects use the Short Name with a trailing underscore.
A minimal working example for the SerialInterfaceClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "serial_interface_client.hpp"
uint32_t baud_rate;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Serial Interface object with obj_id 0
SerialInterfaceClient serial_interface(0);
// Use the Serial Interface object
serial_interface.baud_rate_.get(com);
// Insert code for interfacing with hardware here
// baud_rate = serial_interface.baud_rate_.get_reply();
}
Matlab¶
To use Serial Interface in Matlab, all IQ communication code must be included in your path. This allows the creation of a SerialInterfaceClient object. See Table 8 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SerialInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a Serial Interface object with obj_id 0
serial_interface = SerialInterfaceClient(’com’,com);
% Use the Serial Interface object
old_baud = serial_interface.get(’baud_rate’); // should be 115200
serial_interface.set(’baud_rate’, 9600);
% Note: the baud rate is now 9600. This com object uses 115200
% Make a new com object at 9600 baud to continue communication
com = MessageInterface(’COM18’,9600);
serial_interface = SerialInterfaceClient(’com’,com);
Python¶
To use the Serial Interface Client in Python, include iqmotion
and create a module that has the Serial Interface Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Serial Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
fortiq.set("serial_interface", "baud_rate", 9600) # change baud rate to 9600
Message Table¶
Type ID 16 | Serial Interface
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
baud_rate |
get, set |
uint32 |
hz |
Default is 115200. Reliable up to 2Mbps. Set also performs a save. |
System Control¶
System Control allows the user to perform low level tasks on the motor controller’s microcontroller and gather basic information. The motor’s uptime can be read and set, allowing for flexible timing and synchronizing. System Control also has a Module ID parameter, which allows motors to be bussed on a single serial line yet addressed uniquely. System Control is unique since its ID is always 0 even when the Module ID has been changed.
Arduino¶
To use System Control in Arduino, ensure iq module communication.hpp is included. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
SystemControlClient sys(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float sys_time = 0.0f;
if(ser.get(sys.time_,sys_time))
Serial.println(sys_time);
}
C++¶
To use System Control in C++, include system control client.hpp. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "system_control_client.hpp"
float time;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a System Control object with obj_id 0
// System Control objects are always obj_id 0
SystemControlClient system_control(0);
// Use the System Control object
system_control.time_.get(com);
// Insert code for interfacing with hardware here
// time = system_control.time_.get_reply();
}
Matlab¶
To use System Control in Matlab, all IQ communication code must be included in your path. This allows the creation of a SystemControlClient object. See Table 12 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the SystemControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a System Control object with obj_id 0
% System Control objects are always obj_id 0
system_control = SystemControlClient(’com’,com);
% Use the System Control object
time = system_control.get(’time’);
Python¶
To use the System Control Client in Python, include iqmotion
and create a module that has the System Control Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the System Control Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
FW = fortiq.get("system_control", "firmware_version") # Firmware Version Number
print(f"Firmware: {FW}")
Message Table¶
Type ID 5 | System Control
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
reboot_program |
set |
Reboots the motor controller with saved values |
||
1 |
reboot_boot_loader |
set |
Reboots into the boot loader |
||
2 |
dev_id |
get |
uint16 |
||
3 |
rev_id |
get |
uint16 |
||
4 |
uid1 |
get |
uint32 |
||
5 |
uid2 |
get |
uint32 |
||
6 |
uid3 |
get |
uint32 |
||
7 |
mem_size |
get |
uint16 |
Kb |
|
8 |
build_year |
get |
uint16 |
year |
|
9 |
build_month |
get |
uint8 |
mon |
|
10 |
build_day |
get |
uint8 |
day |
|
11 |
build_hour |
get |
uint8 |
hour |
|
12 |
build_minute |
get |
uint8 |
min |
|
13 |
build_second |
get |
uint8 |
s |
|
14 |
module_id |
get, set, save |
uint8 |
id |
The ID used for all obj_id on this module |
15 |
time |
get, set |
float |
s |
Internal clock time. If unchanged through software this is uptime |
16 |
firmware_version |
get |
uint32 |
ver |
|
17 |
hardware_version |
get, set, save |
uint32 |
ver |
|
18 |
electronics_version |
get, set, save |
uint32 |
ver |
|
19 |
firmware_valid |
get |
uint8 |
bool |
Temperature Estimator¶
The Temperature Estimator uses a conduction thermal model to estimate the temperature of components not directly sensed. In the motor modules the Temperature Estimator estimates the motor coil temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Estimator in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureEstimatorClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Estimator client in C++, include temperature estimator client.hpp. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_estimator_client.hpp"
float temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
TemperatureEstimatorClient temp_client(0);
// Use the Temperature Estimator Client
temp_client.temp_.get(com)
// [Insert code for interfacing with hardware here]
// temp = temp_client.temp_.get_reply();
}
Matlab¶
To use the Temperature Estimator client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureEstimatorClient object. See Table 11 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureEstimatorClient object with obj_id 0
tes = TemperatureEstimatorClient(’com’,com);
% Use the TemperatureEstimatorClient object
coil_temp = tes.get(’temp’);
Python¶
To use the Temperature Estimator Client in Python, include iqmotion
and create a module that has the Temperature Estimator Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Estimator Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
temp = fortiq.get("temperature_estimator", "temp") # Estimated Motor Temperature
print(f"Estimated Motor Temperature: {temp}")
Message Table¶
Type ID 77 | Temperature Estimator
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
temp |
get |
float |
degC |
Temperature of the motor coils |
1 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
2 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
3 |
thermal_resistance |
get, set, save |
float |
K/W |
Model thermal resistance |
4 |
thermal_capacitance |
get, set, save |
float |
J/K |
Model thermal capacitance |
5 |
derate |
get |
Fix16 |
PU |
Amount of derating applied to motor [0 65536] where 65536 is normal operation |
Temperature Monitor UC¶
The Temperature Monitor Microcontroller reads, filters, and reports the microcontroller’s internal temperature. The temperature is used to derate the motor if the temperature rises into dangerous levels. The filter’s cutoff frequency and the temperature limits can be adjusted, though this is not recommended.
Arduino¶
To use the Temperature Monitor Microcontroller in Arduino, ensure iq module communication.hpp is included. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
TemperatureMonitorUcClient tmp(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float temperature = 0.0f;
if(ser.get(tmp.uc_temp_,temperature))
Serial.println(temperature);
}
C++¶
To use the Temperature Monitor Microcontroller client in C++, include temperature monitor uc client.hpp. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message objects use the Short Name with a trailing underscore. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
Note
Interfacing with Serial looks different on different machines. Therefore, this example does not include code for interfacing with the hardware.
For more, see Full C++ Code Example (w/ LibSerial)
#include "generic_interface.hpp"
#include "temperature_monitor_uc_client.hpp"
float uc_temp;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Monitor Microcontroller object with obj_id 0
TemperatureMonitorUcClient tuc(0);
// Use the Temperature Monitor Microcontroller object
tuc.uc_temp_.get(com);
// Insert code for interfacing with hardware here
// Read response
uc_temp = tuc.uc_temp_.get_reply();
}
Matlab¶
To use the Temperature Monitor Microcontroller client in Matlab, all IQ communication code must be included in your path. This allows the creation of a TemperatureMonitorUcClient object. See Table 10 for available messages. All message strings use the Short Names. All messages use the standard Get/Set/Save functions.
A minimal working example for the TemperatureMonitorUcClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureMonitorUcClient object with obj_id 0
tuc = TemperatureMonitorUcClient(’com’,com);
% Use the TemperatureMonitorUcClient object
uc_temp = tuc.get(’uc_temp’);
Python¶
To use the Temperature Monitor Microcontroller Client in Python, include iqmotion
and create a module that has the Temperature Monitor Microcontroller Client within it’s firmware.
See Table below for available messages. All message strings use the Short Names.
All messages use the standard Get/Set/Save functions.
A minimal working example for the Temperature Monitor Microcontroller Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
fortiq = iq.Fortiq(com, 0, firmware="speed")
temp = fortiq.get("temperature_monitor_uc", "uc_temp") # Internal UC Temperature
print(f"Internal UC temperature: {temp}")
Message Table¶
Type ID 73 | Temperature Monitor Microcontroller
Sub ID |
Short Name |
Access |
Data Type |
Unit |
Note |
---|---|---|---|---|---|
0 |
uc_temp |
get |
float |
degC |
Temperature of the microcontroller |
1 |
filter_fs |
get |
uint32 |
Hz |
Low pass filter sample frequency |
2 |
filter_fc |
get, set, save |
uint32 |
Hz |
Low pass filter cutoff frequency |
3 |
otw |
get, set, save |
float |
degC |
Over temperature warning. Derating of the motor begins at this temperature. |
4 |
otlo |
get, set, save |
float |
degC |
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled. |
5 |
derate |
get |
float |
PU |
Amount of derating applied to motor [0 1] |