Vertiq 81-08 | Speed Module¶
The Vertiq 81-08 150Kv is built for high performance commercial UAV and robotic applications. Its default firmware is the Speed Firmware. This extremely compact, lightweight module is designed for roboticists with strict space and weight requirements. With position sensing and advanced calibration and control algorithms, we’re able to drive the motor in a way that increases efficiency, torque output, and responsiveness. Vertiq motors also output advanced telemetry for motor and vehicle health monitoring.
Note
While the default firmware for the Vertiq 81-08 150Kv is the Speed firmware, it also fully supports the following:
Servo firmware
Speed Firmware¶
Arming Handler¶
Vertiq Advanced Speed modules can support an Advanced Arming feature, allowing the user to control the armed state of the module with throttle commands or manually and to configure specific behaviors to occur at armed state transitions. Modules will not react to throttle messages until they have been armed, providing improved safety. The configurable behaviors on armed state transitions allow users to easily integrate advanced behaviors into their setup just by controlling the throttle messages they send, simplifying flight controller integration.
Arduino¶
To use the Arming Handler in Arduino, ensure arming_handler_client.hpp is included. This allows the creation of a ArmingHandlerClient object. See the Message 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 ArmingHandlerClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
ArmingHandlerClient armingHandler(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
int alwaysArmed = 0;
if(ser.get(armingHandler.always_armed, alwaysArmed))
Serial.println(alwaysArmed);
}
C++¶
To use the Arming Handler client in C++, include arming_handler_client.hpp. This allows the creation of an ArmingHandler object. See the Message 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 ArmingHandlerClient 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 "arming_handler_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Arming Handler object with obj_id 0
ArmingHandlerClient armingHandler(0);
// Use the Arming Handler Client
armingHandler.always_armed_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Arming Handler client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a ArmingHandlerClient object. See the Message 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 ArmingHandlerClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a ArmingHandlerClient object with obj_id 0
ArmingHandler = ArmingHandlerClient(’com’,com);
% Use the ArmingHandlerClient object
alwaysArmed = ArmingHandler.get(’always_armed’);
Python¶
To use the Arming Handler Client in Python, import iqmotion
and create a module that has the Arming Handler Client within its firmware.
See the 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 Arming Handler Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0)
always_armed_status = vertiq.get("arming_handler", "always_armed")
print(f"Always armed status: {always_armed_status}")
Message Table¶
- Type ID 86 | Arming Handler
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
1
always_armed
get, set, save
uint8
If True, handler will automatically arm when the first throttle message is received.
2
arm_on_throttle
get, set, save
uint8
If True, throttle will be used to arm.
3
arm_throttle_upper_limit
get, set, save
float
\(\text{PU}\)
Upper limit for throttle to arm.
4
arm_throttle_lower_limit
get, set, save
float
\(\text{PU}\)
Lower limit for throttle to arm.
5
disarm_on_throttle
get, set, save
uint8
If True, throttle will be used to disarm.
6
disarm_throttle_upper_limit
get, set, save
float
\(\text{PU}\)
Upper limit for throttle to disarm.
7
disarm_throttle_lower_limit
get, set, save
float
\(\text{PU}\)
Lower limit for throttle to disarm.
8
consecutive_arming_throttles_to_arm
get, set, save
uint32
\(\text{throttles}\)
Number of consecutive throttles before arming.
9disarm_behvaiorget, set, saveuint8The state that determines how the module will try to come to a stop and what that final drive mode will be. See row below for each state:0 = Coast: The module will coast when it begins disarming by spinning freely and letting drag + friction slow it down. After the song, its final state will remain coasting.1 = 0V to Coast: The Module will drive itself to 0V when it begins disarming, actively trying to come to a rapid stop. After the song, its final state will be to coast.2 = 0V to Brake: The Module will drive itself to 0V when it begins disarming, actively trying to come to a rapid stop. After the song, its final state will be to brake.3 = Stow: The module will trigger a move to the stow postiion when it begins disarming. After the song, its final state will be determined by whatever the stow postiion feature is configured to do after completing a stow.10disarm_song_optionget, set, saveuint8The state that determines if and how many times the module will play its disarm song after coming to a stop. See row below for each state:0 = Never Play: The disarm song is skipped entirely, and the module will transition directly to its final state after stopping.1 = Play Once: The disarm song will play once, and then the module will transition to its final state.2 = Play Continuously: The disarm song will play continuously until the module is armed again or commanded to sping without arming through IQUART. The song will never finish, so the module will never transtion to its final state.11manual_arming_throttle_sourceget, set, saveuint8The throttle source used as its armed throttle source for manual arming. The default manual throttle source is Unknown. In order to use manual arming, a throttle source must be set first. See row below for each state:0 = Unknown: Default configuration. There will be no throttle source if you manually arm, so don’t leave this as Unknown if you are manuall arming.1 = Hobby2 = DroneCAN3 = IQUART12
motor_armed
get, set
uint8
Returns True if motor is armed.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path.
This allows the creation of a BrushlessDriveClient object. See the Message 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:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BrushlessDriveClient object with obj_id 0
BrushlessDrive = BrushlessDriveClient(’com’,com);
% Use the BrushlessDriveClient object
BrushlessDrive.set(’drive_spin_volts’,3.0);
Python¶
To use the Brushless Drive Client in Python, import iqmotion
and create a module that has the Brushless Drive Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.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
0
drive_mode
get
uint8
\(\text{Enum}\)
0 = phase_pwm, 1 = phase_volts, 2 = spin_pwm, 3 = spin_volts, 4 = brake, 5 = coast
1
drive_phase_pwm
set
float
\(\text{PWM}\)
This value is used in open loop (gimbal) mode with this throttle [-1, 1] and is used with phase_angle.
2
drive_phase_volts
set
float
\(\text{V}\)
This value is used in open loop (gimbal) mode with this voltage and is used with phase_angle.
3
drive_spin_pwm
set
float
\(\text{PWM}\)
This spins motor with this throttle [-1, 1].
4
drive_spin_volts
set
float
\(\text{V}\)
This spins motor with this voltage.
5
drive_brake
set
This shorts the motor phases, which slows the motor down by dissipating energy in the motor.
6
drive_coast
set
This disables all drive circuitry, which causes the motor to coast passively.
7
drive_angle_offset
get
float
\(\text{rad}\)
This is analogous to motor timing. This is internally computed by the motor.
8
drive_pwm
get
float
\(\text{PWM}\)
This is the applied PWM after all computation and limiting [-1, 1].
9
drive_volts
get
float
\(\text{V}\)
This is the applied PWM after all computation and limiting.
10
mech_lead_angle
get
float
\(\text{rad}\)
This is the lag compensation used.
11
obs_supply_volts
get
float
\(\text{V}\)
This is the observed supply voltage.
12
obs_angle
get
float
\(\text{rad}\)
This is the observed motor angle.
13
obs_velocity
get
float
\(\frac{\text{rad}}{\text{s}}\)
This is the observed motor velocity.
14
motor_pole_pairs
get, set, save
uint16
\(\text{PP}\)
This is the number of motor pole pairs (magnets/2).
15
motor_emf_shape
get, set, save
uint8
The default setting is sinusoidal EMF. Some firmwares have trapezoidal or custom shapes.
16
permute_wires
get, set, save
uint8
\(\text{bool}\)
This is factory set. Do not change.
17
calibration_angle
get, set, save
float
\(\text{rad}\)
This is factory set. Do not change.
18
lead_time
get, set, save
float
\(s\)
This is factory set. Do not change.
19
commutation_hz
get, set, save
uint32
\(Hz\)
This is the frequency of commutation. Higher frequencies run faster and more efficiently, but may not give the controller enough computation time.
20
phase_angle
get, set
float
\(\text{rad}\)
This is the angle used for open loop (gimbal) mode and is used with drive_phase_pwm or drive_phase_volts.
21
drive_volts_addition
get, set
float
\(\text{V}\)
This is the amount of voltage applied for anticogging or buzzing.
22
angle_adjust_enable
get, set, save
uint8
\(\text{bool}\)
This setting enables closed loop timing angle adjustment.
23
motor_emf_calc
get
float
\(\text{V}\)
This is the computed emf from closed loop angle calculation.
24
angle_adjustment
get
float
\(\text{rad}\)
This is the angle adjustment from closed loop calculation.
25
angle_adjust_max
get, set, save
float
\(\text{rad}\)
This is the maximum angle the closed loop calculation is allowed to adjust.
26
angle_adjust_kp
get, set, save
float
This is the proportional gain for angle adjustment.
27
angle_adjust_ki
get, set, save
float
This is the integral gain for angle adjustment.
32
motor_Kv
get, set, save
float
\(\frac{\text{RPM}}{V}\)
This is the motor’s voltage constant.
33
motor_R_ohm
get, set, save
float
\(\text{ohm}\)
This is the motor’s resistance.
34
motor_I_max
get, set, save
float
\(A\)
This is the max allowable motor current.
35
volts_limit
get, set, save
float
\(V\)
This is the max regen voltage.
36
est_motor_amps
get
float
\(A\)
This is the estimated motor amps.
37
est_motor_torque
get
float
\(N * m\)
This is the estimated motor torque.
38
motor_redline_start
get, set, save
float
\(\frac{\text{rad}}{s}\)
This is the speed at which motor begins to derate.
39
motor_redline_end
get, set, save
float
\(\frac{\text{rad}}{s}\)
This is the speed at which the motor is fully derated.
40
motor_l
get, set, save
float
\(H\)
This is the cross inductance.
41
derate
get
int32
\(PU_{fix16}\)
This is the amount of derating. No derate = 65536, full derate = 0.
42
motor_i_soft_start
get, set, save
float
\(A\)
This is the current at which motor begins to derate.
43
motor_i_soft_end
get, set, save
float
\(A\)
This is the current at which the motor is fully derated.
44
emf
get
float
\(\text{V}\)
This reports the estimated back-EMF voltage produced by the motor based on its velocity.
45
volts_at_max_amps
get
float
\(\text{V}\)
This is the drive voltage that is expected to be applied at the motor’s maximum safe current based on motor resistance. This is used to limit the maximum current applied to the motor. This returns a model based voltage that is based on the maximum allowed motor amps.
46
slew_volts_per_second
get, set, save
float
\(\frac{V}{s}\)
This is the maximum allowed rate of change for the drive voltage when the slew rate is enabled. E.g. If this is 100, Then the drive voltage of the motor cannot change faster than 100 V/s.
47
slew_enable
get, set, save
float
\(\text{V}\)
This enables a voltage slew rate on the motor’s drive voltage.
48
motoring_supply_current_limit
get, set, save
float
\(A\)
On modules that support dynamic supply current limiting, this entry determines the current limit for the current from the supply when the module is “motoring”, i.e. the drive voltage is greater than the back-EMF, as opposed to when it is regenerating. Note this is the current from the supply, so it would be the current from your battery or power supply.
49
regen_supply_current_limit
get, set, save
float
\(A\)
On modules that support dynamic supply current limiting, this entry determines the current limit for the current back to the supply when the module is regenerating, i.e. the back-EMF is greater than the drive voltage, as opposed to when it is motoring. Note this is the current from the supply, so it would be the current from your battery or power supply.
50
supply_current_limit_enable
get, set, save
uint8
\(\text{bool}\)
This enables or disables dynamic supply current limiting. Limiting is enabled when true, and disabled when false.
51
regen_limiting
get
uint8
\(\text{bool}\)
When dynamic supply current limiting is enabled, this reports whether the drive voltage is currently being limited due to the regeneration current back through the supply. True means that the limiter is currently controlling the drive voltage because the regeneration supply current is at or above the limit, false means the regeneration current is low enough that the limiter has not activated.
52
regen_limit_adjust
get
float
\(\text{V}\)
This reports the adjustment voltage being applied to the dynamic supply current limited volts by the closed loop controller due to the regeneration limit. The adjustment adapts to improve the accuracy of the supply current limiting.
53
motoring_limiting
get
uint8
\(\text{bool}\)
When dynamic supply current limiting is enabled, this reports whether the drive voltage is currently being limited due to the motoring supply current. True means that the limiter is currently controlling the drive voltage because the supply current is at or above the limit, false means the supply current is low enough that the limiter has not activated.
54
motoring_limit_adjust
get
float
\(\text{V}\)
This reports the adjustment voltage being applied to the dynamic supply current limited volts by the closed loop controller due to the motoring limit. The adjustment adapts to improve the accuracy of the supply current limiting.
55
regen_limit_kp
get, set, save
float
\(\frac{V}{A}\)
This is the P gain for the closed loop controller of the regeneration dynamic supply current limiter.
56
regen_limit_ki
get, set, save
float
\(\frac{V*s}{A}\)
This is the I gain for the closed loop controller of the regeneration dynamic supply current limiter.
57
regen_limit_max
get, set, save
float
\(\text{V}\)
This is the maximum amount of drive voltage adjustment that the closed loop portion of the regeneration dynamic supply current limiter will apply to the calculated voltage limit.
58
motoring_limit_kp
get, set, save
float
\(\frac{V}{A}\)
This is the P gain for the closed loop controller of the motoring dynamic supply current limiter.
59
motoring_limit_ki
get, set, save
float
\(\frac{V*s}{A}\)
This is the I gain for the closed loop controller of the motoring dynamic supply current limiter.
60
motoring_limit_max
get, set, save
float
\(\text{V}\)
This is the maximum amount of drive voltage adjustment the closed loop portion of the motoring dynamic supply current limiter will apply to the calculated voltage limit.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a BuzzerControlClient object. See the Message 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 BuzzerControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BuzzerControlClient object with obj_id 0
BuzzerControl = BuzzerControlClient(’com’,com);
% Use the BuzzerControlClient object
BuzzerControl.set(’hz’,440); % A4
BuzzerControl.set(’volume’,127); % Max volume
BuzzerControl.set(’duration’,500); % 500ms
BuzzerControl.set(’ctrl_note’);
Python¶
To use the Buzzer Control Client in Python, import iqmotion
and create a module that has the Buzzer Control Client within its 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("buzzer_control", "hz", 440) # A4
vertiq.set("buzzer_control", "volume", 127) # Max Volume
vertiq.set("buzzer_control", "duration", 1000) # 1000ms
vertiq.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
int8
\(\text{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
\(\text{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.
Coil Temperature Estimator¶
The Coil Temperature Estimator is a convection and conduction based thermal model to estimate the temperature of motor coils when they are not directly sensed. 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. The convection coefficient should be tuned for the specific propeller used on the motor. A convection coefficient for an average sized propeller for the given motor is loaded by default. Consider changing the convection coefficient if a relatively large or small propeller is used, or if extreme performance and accuracy are required.
Arduino¶
To use the Coil Temperature Estimator in Arduino, ensure coil_temperature_estimator_client.hpp is included. This allows the creation of a CoilTemperatureEstimatorClient object. See the Message 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 CoilTemperatureEstimatorClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
CoilTemperatureEstimatorClient 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.t_coil_, temperature))
Serial.println(temperature);
}
C++¶
To use the Coil Temperature Estimator client in C++, include coil_temperature_estimator_client.hpp. This allows the creation of a CoilTemperatureEstimator object. See the Message 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 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 "coil_temperature_estimator_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
CoilTemperatureEstimatorClient 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 Coil Temperature Estimator client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a CoilTemperatureEstimatorClient object. See the Message 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 CoilTemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a CoilTemperatureEstimatorClient object with obj_id 0
CoilTemperatureEstimator = CoilTemperatureEstimatorClient(’com’,com);
% Use the CoilTemperatureEstimatorClient object
coilTemp = CoilTemperatureEstimator.get(’t_coil’);
Python¶
To use the Coil Temperature Estimator Client in Python, import iqmotion
and create a module that has the Coil Temperature Estimator Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
coil_temp = vertiq.get("coil_temperature_estimator", "t_coil") # Estimated Motor Temperature
print(f"Estimated Motor Temperature: {coil_temp}")
Message Table¶
- Type ID 83 | Coil Temperature Estimator
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
t_coil
get
float
\(^{\circ}C\)
This is the estimated temperature of the motor coils.
1
t_alu
get
float
\(^{\circ}C\)
This is the estimated temperature of the stator aluminum.
2
t_amb
get, set, save
float
\(^{\circ}C\)
This is the estimated temperature of the ambient air, which is usually conservative.
3
h_coil_amb_free_conv
get, set, save
float
This is the free convection heat transfer coefficient used when the motor is not spinning.
4
h_coil_stator_cond
get, set, save
float
This is the conduction heat transfer coefficient between the coils and the stator aluminum.
5
h_coil_amb_forced_conv
get
float
This is the the present calculated force heat transfer convection coefficient.
6
c_coil
get, set, save
float
This is the thermal heat capacitance/mass of the coils.
7
h_coil_amb_forced_conv_coeff
get, set, save
float
This is the forced convection coefficient calculation coefficient. h_forced_conv = h_conv_coeff * sqrt(speed)
8
otw
get, set, save
float
\(^{\circ}C\)
This is the over temperature warning. The motor begins to derate at this temperature.
9
otlo
get, set, save
float
\(^{\circ}C\)
This is the over temperature lock out. The derating of the motor ends at this temperature, where the motor is fully disabled.
10
derate
get
float
This is the amount of derating applied to motor [0, 1] where 1 is normal operation.
11
q_coil_joule
get
float
\(W\)
This is the present heating power in coils.
12
q_coil_amb_conv
get
float
\(W\)
This is the present ambient convective cooling power.
13
q_coil_stator_cond
get
float
\(W\)
This is the present stator conductive cooling power.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a EscPropellerInputParserClient object. See the Message 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 EscPropellerInputParserClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a EscPropellerInputParserClient object with obj_id 0
EscPropellerInputParser = EscPropellerInputParserClient(’com’,com);
% Use the EscPropellerInputParserClient object
EscPropellerInputParser.set(’velocity_max’,1000);
Python¶
To use the ESC Propeller Input Parser Client in Python, import iqmotion
and create a module that has the ESC Propeller Input Parser Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.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
\(\text{Enum}\)
0 = PWM, 1 = Voltage, 2 = Velocity, 3 = Thrust
1
raw_value
get, set
float
\(\text{PU}\)
Input value [0, 1]
3
sign
get, set, save
uint8
\(\text{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
\(\frac{\text{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]
7
safe_factor
get, set, save
float
\(\text{PU}\)
Setting the Save Factor between 0.0 and 1.0 will scale down the values coming from the FC. Default value is 1.0
8
flip_negative
get, set, save
uint8
\(\text{Bool}\)
Allows the FC and ESC to agree on the meaning of signals coming out of ESC
9
zero_spin_throttle
get, set, save
float
\(\text{PU}\)
The throttle percentage defines what throttle command percentage the zero spin throttle regions begin.
10
zero_spin_tolerance
get, set, save
float
\(\text{PU}\)
Defines how far below the Zero Spin Throttle Percentage the zero spin throttle region will extend for positive throttle commands.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a Hobby Input object. See the Message 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 HobbyInputClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a HobbyInputClient object with obj_id 0
HobbyInput = HobbyInputClient(’com’,com);
% Use the EscPropellerInputParserClient object
HobbyInput.set(’allowed_protocols’,3);
HobbyInput.save(’allowed_protocols’);
Python¶
To use the Hobby Input Client in Python, import iqmotion
and create a module that has the Hobby Input Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("hobby_input", "allowed_protocols", 4) # Set the protocol to MultiShot
vertiq.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
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4
1
protocol
get, set
uint8
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4. The currently active protocol for hobby input. Should not generally need to be set by users, sending hobby input sets this automatically.
2
calibrated protocol
get
uint8
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4. The analog hobby protocol that the module was most recently calibrated with.
3
calibrated_high_ticks_us
get, set, save
uint8
\(\mu s\)
The number of microseconds of the calibrated protocol considered to be a 100% throttle command.
4
calibrated_low_ticks_us
get, set, save
uint8
\(\mu s\)
The number of microseconds of the calibrated protocol considered to be a 0% throttle command.
5
reset_calibration
set
Clears calibration data
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 the Message Table below for available messages. All message objects use the Short Name with a trailing underscore.
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 the Message Table below for available messages. All message objects use the Short Name with a trailing underscore.
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 Vertiq communication code must be included in your path. This allows the creation of a MultiTurnAngleControlClient object. See the Message Table below for available messages. All message strings use the Short Names.
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
MultiTurnAngleControl = MultiTurnAngleControlClient(’com’,com);
% Use the MultiTurnAngleControlClient object
velocityFiltered = MultiTurnAngleControl.get(’obs_angular_displacement’);
MultiTurnAngleControl.set(’ctrl_angle’,0);
Python¶
To use the Multi-Turn Angle Control Client in Python, import iqmotion
and create a module that has the Multi-Turn Angle Control Client within its firmware.
See the Message Table below for available messages. All message strings use the Short Names.
A minimal working example for the Multi-Turn Angle Control Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0, firmware="servo") # Servo Firmware uses this client
# Set the trajectory for the motor to complete 1 full rotation
vertiq.set("multi_turn_angle_control", "trajectory_angular_displacement", 2*math.pi)
# Sets trajectory duration for 2 seconds
vertiq.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
\(\text{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
\(\text{rad}\)
Angular location command
4
ctrl_velocity
get, set
float
\(\frac{\text{rad}}{s}\)
Angular velocity command
5
angle_Kp
get, set, save
float
\(\frac{V}{\text{rad}}\)
Proportional gain
6
angle_Ki
get, set, save
float
\(\frac{V}{\text{rad}*s}\)
Integral gain
7
angle_Kd
get, set, save
float
\(\frac{V}{(\frac{\text{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
\(\text{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
\(\text{rad}\)
This represents the total distance that the module has spun measured in radians. Unless this value is set explicitly, it represents the distance, positive or negative, that the module has spun away from zero_angle. If this value is set, all future displacement controls and readings will be measured in reference to the set displacement.
12
obs_angular_velocity
get
float
\(\frac{\text{rad}}{s}\)
Observed angular velocity
13
meter_per_rad
get, set, save
float
\(\frac{m}{\text{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
\(\frac{m}{s}\)
Linear equivalent to ctrl_velocity
16
obs_linear_displacement
get, set,
float
\(m\)
Observed linear location
17
obs_linear_velocity
get
float
\(\frac{m}{s}\)
Observed linear velocity
18
angular_speed_max
get, set, save
float
\(\frac{\text{rad}}{s}\)
The controller will never attempt to exceed this speed.
19
trajectory_angular_displacement
get, set
float
\(\text{rad}\)
Final absolute displacement of trajectory.
20
trajectory_angular_velocity
get, set
float
\(\frac{\text{rad}}{s}\)
Final velocity of the trajectory. Defaults to 0.
21
trajectory_angular_acceleration
get, set
float
\(\frac{\text{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
\(\frac{m}{s}\)
Final velocity of the trajectory. Defaults to 0.
25
trajectory_linear_acceleration
get, set
float
\(\frac{m}{s^2}\)
Final acceleration of the trajectory. Defaults to 0.
26
trajectory_average_speed
get, set
float
\(\frac{\text{rad}}{s}\)
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
\(\text{Enum}\)
append=0, overwrite=1
29
ff
get, set
uint32
\(V_{fix16}\)
Feed forward term
30
sample_zero_angle
set
Sets the module’s current postiion as the zero angle.
31
zero_angle
get, set, save
float
\(\text{rad}\)
The encoder position the module considers to be 0 radians. Since this is an encoder position, zero_angle is constrained to [-pi, pi]. Unless obs_angular_displacement is set explicitly, this is the position regarded as 0 radians, and all displacements are measured in comparison to this point.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a PersistentMemoryClient object. See the Message 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 PersistentMemoryClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PersistentMemoryClient object with obj_id 0
PersistentMemory = PersistentMemoryClient(’com’,com);
% Use the PersistentMemoryClient object
PersistentMemory.set(’revert_to_default’);
Python¶
To use the Persistent Memory Client in Python, import iqmotion
and create a module that has the Persistent Memory Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("persistent_memory", "factory_default_key_1", 12345678) # Set first key before erasing calibration data
vertiq.set("persistent_memory", "factory_default_key_2", 11223344) # Set second key before erasing calibration data
vertiq.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.
2
format_key_1
set
uint32
\(12345678\)
(Required) Set 12345678 to perform erase or revert_to_default.
3
format_key_2
set
uint32
\(11223344\)
(Required) Set 11223344 to perform erase or revert_to_default.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a PowerMonitorClient object. See the Message 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 PowerMonitorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PowerMontitorClient object with obj_id 0
PowerMonitor = PowerMontitorClient(’com’,com);
% Use the PowerMontitorClient object
volts = PowerMonitor.get(’volts’);
Python¶
To use the Power Monitor Client in Python, import iqmotion
and create a module that has the Power Monitor Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
volts = vertiq.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
\(\text{Hz}\)
Low pass filter sample frequency
6
filter_fc
get, set, save
uint32
\(\text{Hz}\)
Low pass filter cutoff frequency
7
volts_raw
get
uint16
\(\text{bit}\)
ADC value for the voltage measurement
8
amps_raw
get
uint16
\(\text{bit}\)
ADC value for the current measurement
9
volts_gain
get, set, save
float
\(\frac{V}{bit}\)
Gain for the ADC to voltage conversion
10
amps_gain
get, set, save
float
\(\frac{A}{bit}\)
Gain for the ADC to current conversion
11
amps_bias
get, set, save
float
\(\text{bit}\)
Offset bias for the ADC to current conversion
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a PropellerMotorControlClient object. See the Message 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 PropellerMotorControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PropellerMotorControlClient object with obj_id 0
PropellerMotorControl = PropellerMotorControlClient(’com’,com);
% Use the PropellerMotorControlClient object
PropellerMotorControl.set(’ctrl_velocity’,100.0);
Python¶
To use the Propeller Motor Control Client in Python, import iqmotion
and create a module that has the Propeller Motor Control Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.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
\(\text{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
\(\text{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
\(\frac{\text{rad}}{s}\)
Angular velocity command
6
ctrl_thrust
get, set
float
\(N\)
Thrust command (requires kt values)
7
velocity_kp
get, set, save
float
\(\frac{V}{(\frac{\text{rad}}{s})}\)
Proportional gain
8
velocity_ki
get, set, save
float
\(\frac{V}{\text{rad}}\)
Integral gain
9
velocity_kd
get, set, save
float
\(\frac{V}{(\frac{\text{rad}}{s^2})}\)
Derivative gain
10
velocity_ff0
get, set, save
float
\(V\)
Feed forward 0th order term
11
velocity_ff1
get, set, save
float
\(\frac{V}{(\frac{\text{rad}}{s})}\)
Feed forward 1st order term
12
velocity_ff2
get, set, save
float
\(\frac{V}{(\frac{\text{rad}}{s})^2}\)
Feed forward 2nd order term
13
propeller_kt_pos
get, set, save
float
\(\frac{N}{(\frac{\text{rad}}{s})^2}\)
T = ktω2thrust constant in positive direction
14
propeller_kt_neg
get, set, save
float
\(\frac{N}{(\frac{\text{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
\(\text{Hz}\)
Low pass cutoff frequency for input commands
17
timeout_meaning
get, set, save
uint8
\(\text{Enum}\)
This indicates if a timeout is intended to be used as an intentional disarm or as an error.
18
timeout_behavior
get, set, save
uint8
\(\text{Enum}\)
This detemines what behavior to perform when a timeout error occurs.
19
timeout_song_option
get, set, save
uint8
\(\text{Enum}\)
This determines how many times the timeout song will play on a timeout error.
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 the Message 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 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 the Message Table below 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 Vertiq communication code must be included in your path. This allows the creation of a SerialInterfaceClient object. See the Message 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 SerialInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a Serial Interface object with obj_id 0
SerialInterface = SerialInterfaceClient(’com’,com);
% Use the Serial Interface object
oldBaud = SerialInterface.get(’baud_rate’); // should be 115200
SerialInterface.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);
SerialInterface = SerialInterfaceClient(’com’,com);
newBaud = SerialInterface.get(’baud_rate’); // should be 9600
Python¶
To use the Serial Interface Client in Python, import iqmotion
and create a module that has the Serial Interface Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("serial_interface", "baud_rate", 9600) # change baud rate to 9600
Stopping Handler¶
A Vertiq module is considered stopped when it has been below its stopping speed continuously for some stopping time. Anytime the module’s velocity goes above the stopping speed, it will reset the countdown on the stopping time.
Arduino¶
To use the Stopping Handler in Arduino, ensure stopping_handler_client.hpp is included. This allows the creation of a StoppingHandlerClient object. See the Message 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 StoppingHandlerClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
StoppingHandlerClient stoppingHandler(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float stoppedSpeed = 0.0f;
if(ser.get(stoppingHandler.stopped_speed_, stoppedSpeed))
Serial.println(stoppedSpeed);
}
C++¶
To use the Stopping Handler client in C++, include stopping_handler_client.hpp. This allows the creation of a StoppingHandler object. See the Message 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 StoppingHandlerClient 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 "stopping_handler_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
StoppingHandlerClient temp_client(0);
// Use the Temperature Estimator Client
temp_client.stopped_speed_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the Stopping Handler client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a StoppingHandlerClient object. See the Message 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 StoppingHandlerClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a StoppingHandlerClient object with obj_id 0
StoppingHandler = StoppingHandlerClient(’com’,com);
% Use the StoppingHandlerClient object
stoppedSpeed = StoppingHandler.get(’stopped_speed’);
Python¶
To use the Stopping Handler Client in Python, import iqmotion
and create a module that has the Stopping Handler Client within its firmware.
See the Message 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 Stopping Handler Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0)
stopped_speed = vertiq.get("stopping_handler", "stopped_speed")
print(f"Stopped speed: {stopped_speed}")
Message Table¶
- Type ID 87 | Stopping Handler
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
stopped_speed
get, set, save
float
\(\frac{\text{rad}}{s}\)
The speed at which the module needs to spin at or below to be considered stopped.
1
stopped_time
get, set, save
float
\(s\)
The amount of time the module needs to spin at its stopped_speed to be considered stopped.
Stow User Interface¶
The Stow Position feature allows a Vertiq module to return to a configurable position on a transition from armed to disarmed, on timeouts, or when given an explicit command to stow. This can be useful for holding propellers in an aerodynamic position, or preparing vehicles for storage. Users can control what this position is, when the module should attempt to move into the stow position, how aggressively it moves to the stow position, and the module’s behavior once it reaches the stow position.
Arduino¶
To use the Stow User Interface in Arduino, ensure stow_user_interface_client.hpp is included. This allows the creation of a StowUserInterfaceClient object. See the Message 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 StowUserInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
StowUserInterfaceClient stowUserInterface(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float zeroAngle = 0.0f;
if(ser.get(stowUserInterface.zero_angle_, zeroAngle))
Serial.println(zeroAngle);
}
C++¶
To use the Stow User Interface client in C++, include stow_user_interface_client.hpp. This allows the creation of a StowUserInterface object. See the Message 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 StowUserInterfaceClient 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 "stow_user_interface_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
StowUserInterfaceClient stowUserInterface(0);
// Use the Temperature Estimator Client
stowUserInterface.zero_angle_.get(com)
// [Insert code for interfacing with hardware here]
}
Matlab¶
To use the Stow User Interface client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a StowUserInterfaceClient object. See the Message 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 StowUserInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a StowUserInterfaceClient object with obj_id 0
StowUserInterface = StowUserInterfaceClient(’com’,com);
% Use the StowUserInterfaceClient object
zeroAngle = StowUserInterface.get(’zero_angle’);
Python¶
To use the Stow User Interface Client in Python, import iqmotion
and create a module that has the Stow User Interface Client within its firmware.
See the Message 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 Stow User Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0)
zero_angle = vertiq.get("stow_user_interface", "zero_angle")
print(f"Zero angle: {zero_angle}")
Message Table¶
- Type ID 85 | Stow User Interface
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
zero_angle
get, set, save
float
\(\text{rad}\)
The anglular position that the module considers as its ‘zero’ position.
1
target_angle
get, set, save
float
\(\text{rad}\)
The angular postion of the stow postition with reference to the zero angle.
2
target_acceleration
get, set, save
float
\(\frac{\text{rad}}{s^2}\)
The maximum acceleration allowed when moving to the stow position.
3
sample_zero
set
Sets the module’s current postiion as the zero angle.
4
stow
set
Setting this triggers the module to stow.
5
stow_kp
get, set, save
float
\(\frac{V}{\text{rad}}\)
The proportional gain to use in the closed loop position controller moving the module to the stow position. A higher gain can lead to a more accurate position, but can also cause oscillation.
6
stow_ki
get, set, save
float
\(\frac{V}{\text{rad}*s}\)
The integral gain to use in the closed loop position controller moving the module to the stow position.
7
stow_kd
get, set, save
float
\(\frac{V}{(\frac{\text{rad}}{s})}\)
The differential gain to use in the closed loop position controller moving the module to the stow position.
8
hold_stow
get, set, save
uint8
If True, module will actively hold the stole angle once it is reached. If False, the module will coast.
9stow_statusget, set, saveuint8The current state of stowing. See row below for each state:0 = Idle: No stowing happening and module is ready for new commands.1 = In Progress: A move to the stow position is in progress but the module has not reached its stow postition yet.2 = In Progress: A move to the stow position is in progress but the module has not reached its stow postition yet.3 = Holding: The module is actively holding its stow postion.10stow_resultget, set, saveuint8The result of how the previous stow attempt ended. See row below for each possible result:0 = No Result: No previous stow attempts. Default result after module reboot.1 = Completed: The previous stow attempt successfully made it to its stow postion without issue.2 = Interrupted: The previous stow attempt was interrupted before compeleting.3 = Error: An unexpected error occurred during the previous stow attempt.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a SystemControlClient object. See the Message 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 SystemControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a System Control object with obj_id 0
SystemControl = SystemControlClient(’com’,com);
% Use the System Control object
time = SystemControl.get(’time’);
Python¶
To use the System Control Client in Python, import iqmotion
and create a module that has the System Control Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
FW = vertiq.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
\(\text{Kb}\)
8
build_year
get
uint16
\(\text{year}\)
9
build_month
get
uint8
\(\text{mon}\)
10
build_day
get
uint8
\(\text{day}\)
11
build_hour
get
uint8
\(\text{hour}\)
12
build_minute
get
uint8
\(\text{min}\)
13
build_second
get
uint8
\(s\)
14
module_id
get, set, save
uint8
\(\text{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
\(\text{ver}\)
17
hardware_version
get, set, save
uint32
\(\text{ver}\)
18
electronics_version
get, set, save
uint32
\(\text{ver}\)
19
firmware_valid
get
uint8
\(\text{bool}\)
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a TemperatureMonitorUcClient object. See the Message 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 TemperatureMonitorUcClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureMonitorUcClient object with obj_id 0
TemperatureMonitorUc = TemperatureMonitorUcClient(’com’,com);
% Use the TemperatureMonitorUcClient object
ucTemp = TemperatureMonitorUc.get(’uc_temp’);
Python¶
To use the Temperature Monitor Microcontroller Client in Python, import iqmotion
and create a module that has the Temperature Monitor Microcontroller Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
temp = vertiq.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
\(^{\circ}C\)
Temperature of the microcontroller
1
filter_fs
get
uint32
\(\text{Hz}\)
Low pass filter sample frequency
2
filter_fc
get, set, save
uint32
\(\text{Hz}\)
Low pass filter cutoff frequency
3
otw
get, set, save
float
\(^{\circ}C\)
Over temperature warning. Derating of the motor begins at this temperature.
4
otlo
get, set, save
float
\(^{\circ}C\)
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled.
5
derate
get
float
\(\text{PU}\)
Amount of derating applied to motor [0 1]
UAVCAN Node¶
This client is used to configure the DroneCAN interface on a Vertiq module.
Arduino¶
To use the UAVCAN Node in Arduino, ensure uavcan_node_client.hpp is included. This allows the creation of a UavcanNodeClient object. See the Message 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 UavcanNodeClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
UavcanNodeClient uavcanNode(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
int uavcanNodeId = 0;
if(ser.get(uavcanNode.uavcan_node_id_, uavcanNodeId))
Serial.println(uavcanNodeId);
}
C++¶
To use the UAVCAN Node client in C++, include uavcan_node_client.hpp. This allows the creation of an UavcanNode object. See the Message 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 UavcanNodeClient 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 "uavcan_node_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a UAVCAN Node object with obj_id 0
UavcanNodeClient uavcanNode(0);
// Use the UAVCAN Node Client
uavcanNode.uavcan_node_id_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the UAVCAN Node client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a UavcanNodeClient object. See the Message 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 UavcanNodeClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a UavcanNodeClient object with obj_id 0
UavcanNode = UavcanNodeClient(’com’,com);
% Use the UavcanNodeClient object
uavcanNodeId = UavcanNode.get(’uavcan_node_id’);
Python¶
To use the UAVCAN Node Client in Python, import iqmotion
and create a module that has the Arming Handler Client within its firmware.
See the 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 UAVCAN Node Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0)
uavcan_node_id = vertiq.get("uavcan_node", "uavcan_node_id")
print(f"UAVCAN Node ID: {uavcan_node_id}")
Message Table¶
- Type ID 80 | UAVCAN Node
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
uavcan_node_id
get, set, save
uint32
\(\text{ID [1, 127]}\)
This ID is used by the module to uniquely identify itself on the DroneCAN bus. The module must be power cycled in order for a new ID to take effect. Each module on the bus must have a unique ID. While the IDs can be a number between 1 and 127, it is recommended to avoid using 1 as this is commonly used by flight controllers.
1
uavcan_esc_index
get, set, save
uint32
\(\text{Index [0, 19]}\)
This is used to identify the module when ESC commands are sent on the DroneCAN bus. Each ESC/module on the bus requires a unique index to identify which commands are intended for it. The ESC indexes range from 0 to 19, with the first module starting at index 0.
2
zero_behavior
get, set, save
uint32
\(\text{Enum}\)
This determines how the module reacts to receiving a zero setpoint from a DroneCAN Raw Command when DroneCAN is bypassing arming. 0 = coast, 1 = Brake, 2 = Normal Controller
3
last_error_code
get
uint8
\(\text{Error Code}\)
This represents the error code of the last CAN failure. 0 means no error.
4
receive_error_counter
get
uint8
\(\text{Number of errors}\)
This counter increments with each CAN receive error.
5
transmit_error_counter
get
uint8
\(\text{Number of errors}\)
This counter increments with each CAN transmit error.
6
bus_off_flag
get
uint8
\(\text{Bool}\)
This flag indicates if the bus turned itself off due to errors. 1 means the bus is off.
7
error_passive_flag
get
uint8
\(\text{Bool}\)
This flag indicates if the error limit to enter passive mode has been reached. 1 means the module is past the passiv error limit.
8
error_warning_flag
get
uint8
\(\text{Bool}\)
This flag indicates if the error warning limit has been reached. 1 means there has been enough errors to trigger a warning.
9
telemetry_frequency
get, set, save
uint32
\(\text{Hz}\)
This represents the frequency with which telemetry will be sent to the DroneCAN bus.
10
bit_rate
get, set, save
uint32
\(\frac{\text{Bit}}{s}\)
This represents the bitrate used by the DroneCAN bus.
11
bypass_arming
get, set, save
uint8
\(\text{Bool}\)
This setting allows the module to bypass arming with DroneCAN throttle messages. DroneCAN messages will not be impacted by the arming state, will not cause arming state transistions, and will use the zero behavior setting.
Servo Firmware¶
ADC Interface¶
Vertiq’s ADC Interface provides access to an on-board Analog to Digital Converter (ADC). An ADC makes it possible for your module to read input analog voltages. The ADC handles voltages from 0.0V to 3.3V with a 12-bit resolution. For example, if you input 1V to the ADC interface, reading the voltage would return 1V, and reading the “raw value” would return 1241 (\(\frac{V_{\text{in}} * 4096}{3.3}\)).
The ADC interface provides read-only access to both the voltage read and the raw ADC value.
Arduino¶
To use the ADC Interface in Arduino, ensure adc_interface_client.hpp is included. This allows the creation of a AdcInterfaceClient object. See the Message 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 AdcInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
AdcInterfaceClient adcInterface(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float adcVoltage = 0.0f;
if(ser.get(adcInterface.adc_voltage_, adcVoltage))
Serial.println(adcVoltage);
}
C++¶
To use the ADC Interface client in C++, include adc_interface_client.hpp. This allows the creation of an AdcInterface object. See the Message 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 AdcInterfaceClient 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 "adc_interface_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a ADC Interface object with obj_id 0
AdcInterfaceClient adcInterface(0);
// Use the ADC Interface Client
adcInterface.adc_voltage_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the ADC Interface client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a AdcInterfaceClient object. See the Message 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 AdcInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a AdcInterfaceClient object with obj_id 0
AdcInterface = AdcInterfaceClient(’com’,com);
% Use the AdcInterfaceClient object
adcVoltage = AdcInterface.get(’adc_voltage’);
Python¶
To use the ADC Interface Client in Python, import iqmotion
and create a fortiq module.
See the 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 ADC Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0, firmware="servo")
adc_voltage = vertiq.get("adc_interface", "adc_voltage")
print(f"adc voltage : {adc_voltage}")
Message Table¶
Type ID 91 | ADC Interface
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
adc_voltage
get
float
\({\text{Volts}}\)
Read only access to input analog voltage
1
raw_value
get
uint16
Read only access to raw ADC value. Ex: 1V to ADC interface would return 1241: (\(\frac{V_{\text{in}} * 4096}{3.3}\))
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 the Message 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 the Message 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 Vertiq communication code must be included in your path. This allows the creation of a AnticoggingClient object. See the Message 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
Anticogging = AnticoggingClient(’com’,com);
% Use the AnticoggingClient object
Anticogging.set(’is_enabled’,1);
Python¶
To use the Anticogging Client in Python, import iqmotion
and create a module that has the Anticogging Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0, firmware="servo")
vertiq.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
\(\text{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
\(\text{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.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path.
This allows the creation of a BrushlessDriveClient object. See the Message 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:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BrushlessDriveClient object with obj_id 0
BrushlessDrive = BrushlessDriveClient(’com’,com);
% Use the BrushlessDriveClient object
BrushlessDrive.set(’drive_spin_volts’,3.0);
Python¶
To use the Brushless Drive Client in Python, import iqmotion
and create a module that has the Brushless Drive Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.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
0
drive_mode
get
uint8
\(\text{Enum}\)
0 = phase_pwm, 1 = phase_volts, 2 = spin_pwm, 3 = spin_volts, 4 = brake, 5 = coast
1
drive_phase_pwm
set
float
\(\text{PWM}\)
This value is used in open loop (gimbal) mode with this throttle [-1, 1] and is used with phase_angle.
2
drive_phase_volts
set
float
\(\text{V}\)
This value is used in open loop (gimbal) mode with this voltage and is used with phase_angle.
3
drive_spin_pwm
set
float
\(\text{PWM}\)
This spins motor with this throttle [-1, 1].
4
drive_spin_volts
set
float
\(\text{V}\)
This spins motor with this voltage.
5
drive_brake
set
This shorts the motor phases, which slows the motor down by dissipating energy in the motor.
6
drive_coast
set
This disables all drive circuitry, which causes the motor to coast passively.
7
drive_angle_offset
get
float
\(\text{rad}\)
This is analogous to motor timing. This is internally computed by the motor.
8
drive_pwm
get
float
\(\text{PWM}\)
This is the applied PWM after all computation and limiting [-1, 1].
9
drive_volts
get
float
\(\text{V}\)
This is the applied PWM after all computation and limiting.
10
mech_lead_angle
get
float
\(\text{rad}\)
This is the lag compensation used.
11
obs_supply_volts
get
float
\(\text{V}\)
This is the observed supply voltage.
12
obs_angle
get
float
\(\text{rad}\)
This is the observed motor angle.
13
obs_velocity
get
float
\(\frac{\text{rad}}{\text{s}}\)
This is the observed motor velocity.
14
motor_pole_pairs
get, set, save
uint16
\(\text{PP}\)
This is the number of motor pole pairs (magnets/2).
15
motor_emf_shape
get, set, save
uint8
The default setting is sinusoidal EMF. Some firmwares have trapezoidal or custom shapes.
16
permute_wires
get, set, save
uint8
\(\text{bool}\)
This is factory set. Do not change.
17
calibration_angle
get, set, save
float
\(\text{rad}\)
This is factory set. Do not change.
18
lead_time
get, set, save
float
\(s\)
This is factory set. Do not change.
19
commutation_hz
get, set, save
uint32
\(Hz\)
This is the frequency of commutation. Higher frequencies run faster and more efficiently, but may not give the controller enough computation time.
20
phase_angle
get, set
float
\(\text{rad}\)
This is the angle used for open loop (gimbal) mode and is used with drive_phase_pwm or drive_phase_volts.
21
drive_volts_addition
get, set
float
\(\text{V}\)
This is the amount of voltage applied for anticogging or buzzing.
22
angle_adjust_enable
get, set, save
uint8
\(\text{bool}\)
This setting enables closed loop timing angle adjustment.
23
motor_emf_calc
get
float
\(\text{V}\)
This is the computed emf from closed loop angle calculation.
24
angle_adjustment
get
float
\(\text{rad}\)
This is the angle adjustment from closed loop calculation.
25
angle_adjust_max
get, set, save
float
\(\text{rad}\)
This is the maximum angle the closed loop calculation is allowed to adjust.
26
angle_adjust_kp
get, set, save
float
This is the proportional gain for angle adjustment.
27
angle_adjust_ki
get, set, save
float
This is the integral gain for angle adjustment.
32
motor_Kv
get, set, save
float
\(\frac{\text{RPM}}{V}\)
This is the motor’s voltage constant.
33
motor_R_ohm
get, set, save
float
\(\text{ohm}\)
This is the motor’s resistance.
34
motor_I_max
get, set, save
float
\(A\)
This is the max allowable motor current.
35
volts_limit
get, set, save
float
\(V\)
This is the max regen voltage.
36
est_motor_amps
get
float
\(A\)
This is the estimated motor amps.
37
est_motor_torque
get
float
\(N * m\)
This is the estimated motor torque.
38
motor_redline_start
get, set, save
float
\(\frac{\text{rad}}{s}\)
This is the speed at which motor begins to derate.
39
motor_redline_end
get, set, save
float
\(\frac{\text{rad}}{s}\)
This is the speed at which the motor is fully derated.
40
motor_l
get, set, save
float
\(H\)
This is the cross inductance.
41
derate
get
int32
\(PU_{fix16}\)
This is the amount of derating. No derate = 65536, full derate = 0.
42
motor_i_soft_start
get, set, save
float
\(A\)
This is the current at which motor begins to derate.
43
motor_i_soft_end
get, set, save
float
\(A\)
This is the current at which the motor is fully derated.
44
emf
get
float
\(\text{V}\)
This reports the estimated back-EMF voltage produced by the motor based on its velocity.
45
volts_at_max_amps
get
float
\(\text{V}\)
This is the drive voltage that is expected to be applied at the motor’s maximum safe current based on motor resistance. This is used to limit the maximum current applied to the motor. This returns a model based voltage that is based on the maximum allowed motor amps.
46
slew_volts_per_second
get, set, save
float
\(\frac{V}{s}\)
This is the maximum allowed rate of change for the drive voltage when the slew rate is enabled. E.g. If this is 100, Then the drive voltage of the motor cannot change faster than 100 V/s.
47
slew_enable
get, set, save
float
\(\text{V}\)
This enables a voltage slew rate on the motor’s drive voltage.
48
motoring_supply_current_limit
get, set, save
float
\(A\)
On modules that support dynamic supply current limiting, this entry determines the current limit for the current from the supply when the module is “motoring”, i.e. the drive voltage is greater than the back-EMF, as opposed to when it is regenerating. Note this is the current from the supply, so it would be the current from your battery or power supply.
49
regen_supply_current_limit
get, set, save
float
\(A\)
On modules that support dynamic supply current limiting, this entry determines the current limit for the current back to the supply when the module is regenerating, i.e. the back-EMF is greater than the drive voltage, as opposed to when it is motoring. Note this is the current from the supply, so it would be the current from your battery or power supply.
50
supply_current_limit_enable
get, set, save
uint8
\(\text{bool}\)
This enables or disables dynamic supply current limiting. Limiting is enabled when true, and disabled when false.
51
regen_limiting
get
uint8
\(\text{bool}\)
When dynamic supply current limiting is enabled, this reports whether the drive voltage is currently being limited due to the regeneration current back through the supply. True means that the limiter is currently controlling the drive voltage because the regeneration supply current is at or above the limit, false means the regeneration current is low enough that the limiter has not activated.
52
regen_limit_adjust
get
float
\(\text{V}\)
This reports the adjustment voltage being applied to the dynamic supply current limited volts by the closed loop controller due to the regeneration limit. The adjustment adapts to improve the accuracy of the supply current limiting.
53
motoring_limiting
get
uint8
\(\text{bool}\)
When dynamic supply current limiting is enabled, this reports whether the drive voltage is currently being limited due to the motoring supply current. True means that the limiter is currently controlling the drive voltage because the supply current is at or above the limit, false means the supply current is low enough that the limiter has not activated.
54
motoring_limit_adjust
get
float
\(\text{V}\)
This reports the adjustment voltage being applied to the dynamic supply current limited volts by the closed loop controller due to the motoring limit. The adjustment adapts to improve the accuracy of the supply current limiting.
55
regen_limit_kp
get, set, save
float
\(\frac{V}{A}\)
This is the P gain for the closed loop controller of the regeneration dynamic supply current limiter.
56
regen_limit_ki
get, set, save
float
\(\frac{V*s}{A}\)
This is the I gain for the closed loop controller of the regeneration dynamic supply current limiter.
57
regen_limit_max
get, set, save
float
\(\text{V}\)
This is the maximum amount of drive voltage adjustment that the closed loop portion of the regeneration dynamic supply current limiter will apply to the calculated voltage limit.
58
motoring_limit_kp
get, set, save
float
\(\frac{V}{A}\)
This is the P gain for the closed loop controller of the motoring dynamic supply current limiter.
59
motoring_limit_ki
get, set, save
float
\(\frac{V*s}{A}\)
This is the I gain for the closed loop controller of the motoring dynamic supply current limiter.
60
motoring_limit_max
get, set, save
float
\(\text{V}\)
This is the maximum amount of drive voltage adjustment the closed loop portion of the motoring dynamic supply current limiter will apply to the calculated voltage limit.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a BuzzerControlClient object. See the Message 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 BuzzerControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a BuzzerControlClient object with obj_id 0
BuzzerControl = BuzzerControlClient(’com’,com);
% Use the BuzzerControlClient object
BuzzerControl.set(’hz’,440); % A4
BuzzerControl.set(’volume’,127); % Max volume
BuzzerControl.set(’duration’,500); % 500ms
BuzzerControl.set(’ctrl_note’);
Python¶
To use the Buzzer Control Client in Python, import iqmotion
and create a module that has the Buzzer Control Client within its 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("buzzer_control", "hz", 440) # A4
vertiq.set("buzzer_control", "volume", 127) # Max Volume
vertiq.set("buzzer_control", "duration", 1000) # 1000ms
vertiq.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
int8
\(\text{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
\(\text{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.
Coil Temperature Estimator¶
The Coil Temperature Estimator is a convection and conduction based thermal model to estimate the temperature of motor coils when they are not directly sensed. 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. The convection coefficient should be tuned for the specific propeller used on the motor. A convection coefficient for an average sized propeller for the given motor is loaded by default. Consider changing the convection coefficient if a relatively large or small propeller is used, or if extreme performance and accuracy are required.
Arduino¶
To use the Coil Temperature Estimator in Arduino, ensure coil_temperature_estimator_client.hpp is included. This allows the creation of a CoilTemperatureEstimatorClient object. See the Message 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 CoilTemperatureEstimatorClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
CoilTemperatureEstimatorClient 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.t_coil_, temperature))
Serial.println(temperature);
}
C++¶
To use the Coil Temperature Estimator client in C++, include coil_temperature_estimator_client.hpp. This allows the creation of a CoilTemperatureEstimator object. See the Message 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 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 "coil_temperature_estimator_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Temperature Estimator object with obj_id 0
CoilTemperatureEstimatorClient 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 Coil Temperature Estimator client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a CoilTemperatureEstimatorClient object. See the Message 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 CoilTemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a CoilTemperatureEstimatorClient object with obj_id 0
CoilTemperatureEstimator = CoilTemperatureEstimatorClient(’com’,com);
% Use the CoilTemperatureEstimatorClient object
coilTemp = CoilTemperatureEstimator.get(’t_coil’);
Python¶
To use the Coil Temperature Estimator Client in Python, import iqmotion
and create a module that has the Coil Temperature Estimator Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
coil_temp = vertiq.get("coil_temperature_estimator", "t_coil") # Estimated Motor Temperature
print(f"Estimated Motor Temperature: {coil_temp}")
Message Table¶
- Type ID 83 | Coil Temperature Estimator
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
t_coil
get
float
\(^{\circ}C\)
This is the estimated temperature of the motor coils.
1
t_alu
get
float
\(^{\circ}C\)
This is the estimated temperature of the stator aluminum.
2
t_amb
get, set, save
float
\(^{\circ}C\)
This is the estimated temperature of the ambient air, which is usually conservative.
3
h_coil_amb_free_conv
get, set, save
float
This is the free convection heat transfer coefficient used when the motor is not spinning.
4
h_coil_stator_cond
get, set, save
float
This is the conduction heat transfer coefficient between the coils and the stator aluminum.
5
h_coil_amb_forced_conv
get
float
This is the the present calculated force heat transfer convection coefficient.
6
c_coil
get, set, save
float
This is the thermal heat capacitance/mass of the coils.
7
h_coil_amb_forced_conv_coeff
get, set, save
float
This is the forced convection coefficient calculation coefficient. h_forced_conv = h_conv_coeff * sqrt(speed)
8
otw
get, set, save
float
\(^{\circ}C\)
This is the over temperature warning. The motor begins to derate at this temperature.
9
otlo
get, set, save
float
\(^{\circ}C\)
This is the over temperature lock out. The derating of the motor ends at this temperature, where the motor is fully disabled.
10
derate
get
float
This is the amount of derating applied to motor [0, 1] where 1 is normal operation.
11
q_coil_joule
get
float
\(W\)
This is the present heating power in coils.
12
q_coil_amb_conv
get
float
\(W\)
This is the present ambient convective cooling power.
13
q_coil_stator_cond
get
float
\(W\)
This is the present stator conductive cooling power.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a Hobby Input object. See the Message 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 HobbyInputClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a HobbyInputClient object with obj_id 0
HobbyInput = HobbyInputClient(’com’,com);
% Use the EscPropellerInputParserClient object
HobbyInput.set(’allowed_protocols’,3);
HobbyInput.save(’allowed_protocols’);
Python¶
To use the Hobby Input Client in Python, import iqmotion
and create a module that has the Hobby Input Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("hobby_input", "allowed_protocols", 4) # Set the protocol to MultiShot
vertiq.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
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4
1
protocol
get, set
uint8
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4. The currently active protocol for hobby input. Should not generally need to be set by users, sending hobby input sets this automatically.
2
calibrated protocol
get
uint8
\(\text{Enum}\)
Standard PWM = 1, OneShot125 = 2, OneShot42 = 3, MultiShot = 4. The analog hobby protocol that the module was most recently calibrated with.
3
calibrated_high_ticks_us
get, set, save
uint8
\(\mu s\)
The number of microseconds of the calibrated protocol considered to be a 100% throttle command.
4
calibrated_low_ticks_us
get, set, save
uint8
\(\mu s\)
The number of microseconds of the calibrated protocol considered to be a 0% throttle command.
5
reset_calibration
set
Clears calibration data
GPIO Controller¶
Vertiq’s GPIO interface provides a flexible method of interacting with a module’s user-specific GPIO pins. Each GPIO can be set to input or output, which can be switched on-the-fly, if desired. Each pin set as an input may choose whether or not to use an internal pull resistor (up or down), as well as the type of pull used. Each pin set as an output may choose whether to output in a Push-Pull or Open-Drain configuration.
Arduino¶
To use the GPIO Controller in Arduino, ensure gpio_controller_client.hpp is included. This allows the creation of a GpioControllerClient object. See the Message 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 GpioControllerClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
GpioControllerClient gpioController(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
int modeRegister = 0;
if(ser.get(gpioController.mode_register_, modeRegister))
Serial.println(modeRegister);
}
C++¶
To use the GPIO Controller client in C++, include gpio_controller_client.hpp. This allows the creation of an GpioController object. See the Message 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 GpioControllerClient 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 "gpio_controller_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a GPIO Controller object with obj_id 0
GpioControllerClient gpioController(0);
// Use the GPIO Controller Client
gpioController.mode_register_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the GPIO Controller client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a GpioControllerClient object. See the Message 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 GpioControllerClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a GpioControllerClient object with obj_id 0
GpioController = GpioControllerClient(’com’,com);
% Use the GpioControllerClient object
modeRegister = GpioController.get(’mode_register’);
Python¶
To use the GPIO Controller Client in Python, import iqmotion
and create a fortiq module.
See the 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 GPIO Controller Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0, firmware="servo")
mode_register = vertiq.get("gpio_controller", "mode_register")
print(f"mode register: {mode_register}")
Message Table¶
- Type ID 90 | GPIO Controller
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
mode_register
get, set, save
uint8
Access to the GPIO Modes register
1
inputs_register
get
uint8
Access to the GPIO Inputs register
2
outputs_register
get, set, save
uint8
Access to the GPIO Outputs Register
3
use_pull_register
get, set, save
uint8
Access to the GPIO Use-Pull Register
4
pull_type_register
get, set, save
uint8
Access to the GPIO Pull Type Register
5
push_pull_open_drain_register
get, set, save
uint8
Access to the GPIO PP/OD Register
6
addressable_gpio_mode
set
uint8
Addressable write access to a single GPIO’s Mode
7
addressable_outputs
set
uint8
Addressable write access to a single GPIO’s Output
8
addressable_use_pull
set
uint8
Addressable write access to a single GPIO’s Use Pull Value
9
addressable_pull_type
set
uint8
Addressable write access to a single GPIO’s PUll Type
10
addressable_push_pull_open_drain
get, set, save
uint8
Addressable write access to a single GPIO’s PP/OD Mode
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 the Message Table below for available messages. All message objects use the Short Name with a trailing underscore.
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 the Message Table below for available messages. All message objects use the Short Name with a trailing underscore.
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 Vertiq communication code must be included in your path. This allows the creation of a MultiTurnAngleControlClient object. See the Message Table below for available messages. All message strings use the Short Names.
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
MultiTurnAngleControl = MultiTurnAngleControlClient(’com’,com);
% Use the MultiTurnAngleControlClient object
velocityFiltered = MultiTurnAngleControl.get(’obs_angular_displacement’);
MultiTurnAngleControl.set(’ctrl_angle’,0);
Python¶
To use the Multi-Turn Angle Control Client in Python, import iqmotion
and create a module that has the Multi-Turn Angle Control Client within its firmware.
See the Message Table below for available messages. All message strings use the Short Names.
A minimal working example for the Multi-Turn Angle Control Client is:
import iqmotion as iq
import math
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0, firmware="servo") # Servo Firmware uses this client
# Set the trajectory for the motor to complete 1 full rotation
vertiq.set("multi_turn_angle_control", "trajectory_angular_displacement", 2*math.pi)
# Sets trajectory duration for 2 seconds
vertiq.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
\(\text{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
\(\text{rad}\)
Angular location command
4
ctrl_velocity
get, set
float
\(\frac{\text{rad}}{s}\)
Angular velocity command
5
angle_Kp
get, set, save
float
\(\frac{V}{\text{rad}}\)
Proportional gain
6
angle_Ki
get, set, save
float
\(\frac{V}{\text{rad}*s}\)
Integral gain
7
angle_Kd
get, set, save
float
\(\frac{V}{(\frac{\text{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
\(\text{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
\(\text{rad}\)
This represents the total distance that the module has spun measured in radians. Unless this value is set explicitly, it represents the distance, positive or negative, that the module has spun away from zero_angle. If this value is set, all future displacement controls and readings will be measured in reference to the set displacement.
12
obs_angular_velocity
get
float
\(\frac{\text{rad}}{s}\)
Observed angular velocity
13
meter_per_rad
get, set, save
float
\(\frac{m}{\text{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
\(\frac{m}{s}\)
Linear equivalent to ctrl_velocity
16
obs_linear_displacement
get, set,
float
\(m\)
Observed linear location
17
obs_linear_velocity
get
float
\(\frac{m}{s}\)
Observed linear velocity
18
angular_speed_max
get, set, save
float
\(\frac{\text{rad}}{s}\)
The controller will never attempt to exceed this speed.
19
trajectory_angular_displacement
get, set
float
\(\text{rad}\)
Final absolute displacement of trajectory.
20
trajectory_angular_velocity
get, set
float
\(\frac{\text{rad}}{s}\)
Final velocity of the trajectory. Defaults to 0.
21
trajectory_angular_acceleration
get, set
float
\(\frac{\text{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
\(\frac{m}{s}\)
Final velocity of the trajectory. Defaults to 0.
25
trajectory_linear_acceleration
get, set
float
\(\frac{m}{s^2}\)
Final acceleration of the trajectory. Defaults to 0.
26
trajectory_average_speed
get, set
float
\(\frac{\text{rad}}{s}\)
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
\(\text{Enum}\)
append=0, overwrite=1
29
ff
get, set
uint32
\(V_{fix16}\)
Feed forward term
30
sample_zero_angle
set
Sets the module’s current postiion as the zero angle.
31
zero_angle
get, set, save
float
\(\text{rad}\)
The encoder position the module considers to be 0 radians. Since this is an encoder position, zero_angle is constrained to [-pi, pi]. Unless obs_angular_displacement is set explicitly, this is the position regarded as 0 radians, and all displacements are measured in comparison to this point.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a PersistentMemoryClient object. See the Message 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 PersistentMemoryClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PersistentMemoryClient object with obj_id 0
PersistentMemory = PersistentMemoryClient(’com’,com);
% Use the PersistentMemoryClient object
PersistentMemory.set(’revert_to_default’);
Python¶
To use the Persistent Memory Client in Python, import iqmotion
and create a module that has the Persistent Memory Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("persistent_memory", "factory_default_key_1", 12345678) # Set first key before erasing calibration data
vertiq.set("persistent_memory", "factory_default_key_2", 11223344) # Set second key before erasing calibration data
vertiq.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.
2
format_key_1
set
uint32
\(12345678\)
(Required) Set 12345678 to perform erase or revert_to_default.
3
format_key_2
set
uint32
\(11223344\)
(Required) Set 11223344 to perform erase or revert_to_default.
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a PowerMonitorClient object. See the Message 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 PowerMonitorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PowerMontitorClient object with obj_id 0
PowerMonitor = PowerMontitorClient(’com’,com);
% Use the PowerMontitorClient object
volts = PowerMonitor.get(’volts’);
Python¶
To use the Power Monitor Client in Python, import iqmotion
and create a module that has the Power Monitor Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
volts = vertiq.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
\(\text{Hz}\)
Low pass filter sample frequency
6
filter_fc
get, set, save
uint32
\(\text{Hz}\)
Low pass filter cutoff frequency
7
volts_raw
get
uint16
\(\text{bit}\)
ADC value for the voltage measurement
8
amps_raw
get
uint16
\(\text{bit}\)
ADC value for the current measurement
9
volts_gain
get, set, save
float
\(\frac{V}{bit}\)
Gain for the ADC to voltage conversion
10
amps_gain
get, set, save
float
\(\frac{A}{bit}\)
Gain for the ADC to current conversion
11
amps_bias
get, set, save
float
\(\text{bit}\)
Offset bias for the ADC to current conversion
Power Safety¶
The Power Safety protects the motor by checking various parameters in the motor, such as voltage and current, to make sure the values are within a specific range. If the values are above or below the thresholds, the motor will coast and lock down to prevent any commands from being processed. The motor will unlock once the parameters are back within the thresholds.
Arduino¶
To use Power Safety in Arduino, ensure iq_module_communication.hpp is included. This allows the creation of a PowerSafetyClient object. See the Message 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 PowerSafetyClient 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);
PowerSafetyClient ps(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
float current_fault = 0;
if(ser.get(ps.fault_now_, current_fault))
Serial.println(current_fault);
}
C++¶
To use Power Safety in C++, include power monitor client.hpp. This allows the creation of a PowerSafetyClient object. See the Message 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 PowerSafetyClient is:
#include "generic_interface.hpp"
#include "power_safety_client.hpp"
float volts;
void main(){
// Make a communication interface object
GenericInterface com;
// Make a Power Safety object with obj_id 0
PowerSafetyClient ps(0);
// Use the Power Safety object
ps.fault_now_.get(com);
// Insert code for interfacing with hardware here
// Read response
volts = ps.fault_now_.get_reply();
}
Matlab¶
To use Power Safety in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a PowerSafetyClient object. See the Message 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 PowerSafetyClient is:
% Make a communication interface object
com = MessageInterface('COM18', 115200);
% Make a Power Safety object with obj_id 0
PowerSafety = PowerSafetyClient('com', com);
% Use the Power Safety object
faultNow = PowerSafety.get('fault_now');
Python¶
To use the Power Safety Client in Python, import iqmotion
and create a module that has the Power Safety Client within its firmware.
See the Message 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 Safety Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0)
fault_now = vertiq.get("power_safety", "fault_now")
print(f"current fault: {fault_now}")
Message Table¶
- Type ID 83 | Power Safety
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
fault_now
get
uint8
\(\text{Bitmask}\)
The fault(s) that are currently triggering
1
fault_ever
get, set, save
uint8
\(\text{Bitmask}\)
Record of all faults that were triggered since last modified by user. The user can clear all of the records by setting the value to 0, or individual faults by properly setting bitmask value
2
fault_latching
get, set, save
uint8
\(\text{Bitmask}\)
Determines if the motor is latching. When latching, if there are any bits set in fault_ever, motor will stay in Safe Mode until they are cleared. When not latching, motor will enter and exit Safe Mode only on current faults based on fault_now
3
volt_input_low
get, set, save
float
\(V\)
Minimum threshold value for voltage
4
volt_input_high
get, set, save
float
\(V\)
Maximum threshold value for voltage
5
vref_int_low
get, set, save
float
\(V\)
Minimum threshold value for reference voltage
6
vref_int_high
get, set, save
float
\(V\)
Maximum threshold value for reference voltage
7
current_input_low
get, set, save
float
\(A\)
Minimum threshold value for current
8
current_input_high
get, set, save
float
\(A\)
Maximum threshold value for current
9
motor_current_low
get, set, save
float
\(A\)
Minimum threshold value for motor current
10
motor_current_high
get, set, save
float
\(A\)
Maximum threshold value for motor current
11
temperature_uc_low
get, set, save
float
\(^{\circ}C\)
Minimum threshold value for microcontroller temperature
12
temperature_uc_high
get, set, save
float
\(^{\circ}C\)
Maximum threshold value for microcontroller temperature
13
temperature_coil_low
get, set, save
float
\(^{\circ}C\)
Minimum threshold value for coil temperature
14
temperature_coil_high
get, set, save
float
\(^{\circ}C\)
Maximum threshold value for coil temperature
PWM Interface¶
Vertiq’s high power PWM output interface provides access to a PWM output driver with read/write accessibility to the frequency, duty cycle, and mode. At the hardware level, this driver is an open-drain MOSFET without an internal pull up resistor. The mode parameter determines which portion of the PWM cycle the duty cycle represents, high or low, and is dependent on your application’s hardware setup.
Arduino¶
To use the PWM Interface in Arduino, ensure pwm_interface_client.hpp is included. This allows the creation of a PwmInterfaceClient object. See the Message 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 PwmInterfaceClient is:
#include <iq_module_communication.hpp>
IqSerial ser(Serial2);
PwmInterfaceClient pwmInterface(0);
void setup() {
ser.begin();
// Initialize Serial (for displaying information on the terminal)
Serial.begin(115200);
}
void loop() {
int pwmFrequency = 0;
if(ser.get(pwmInterface.pwm_frequency_, pwmFrequency))
Serial.println(pwmFrequency);
}
C++¶
To use the PWM Interface client in C++, include pwm_interface_client.hpp. This allows the creation of an PwmInterface object. See the Message 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 PwmInterfaceClient 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 "pwm_interface_client.hpp"
void main(){
// Make a communication interface object
GenericInterface com;
// Make a PWM Interface object with obj_id 0
PwmInterfaceClient pwmInterface(0);
// Use the PWM Interface Client
pwmInterface.pwm_frequency_.get(com)
// Insert code for interfacing with hardware here
}
Matlab¶
To use the PWM Interface client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a PwmInterfaceClient object. See the Message 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 PwmInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a PwmInterfaceClient object with obj_id 0
PwmInterface = PwmInterfaceClient(’com’,com);
% Use the PwmInterfaceClient object
pwmFrequency = PwmInterface.get(’pwm_frequency’);
Python¶
To use the PWM Interface Client in Python, import iqmotion
and create a fortiq module.
See the 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 PWM Interface Client is:
import iqmotion as iq
com = iq.SerialCommunicator("/dev/ttyUSB0")
vertiq = iq.Vertiq8108(com, 0, firmware="servo")
pwm_frequency = vertiq.get("pwm_interface", "pwm_frequency")
print(f"pwm frequency: {pwm_frequency}")
Message Table¶
- Type ID 92 | PWM Interface
¶ Sub ID
Short Name
Access
Data Type
Unit
Note
0
pwm_frequency
get, set, save
uint32
\(\text{Hz}\)
Frequency between 1Hz and 5000Hz
1
duty_cycle
get, set, save
uint8
The percentage of the full cycle that represents high or low
2
pwm_mode
get, set, save
uint8
Determines which portion of PWM cycle represents high or low
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 the Message 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 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 the Message Table below 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 Vertiq communication code must be included in your path. This allows the creation of a SerialInterfaceClient object. See the Message 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 SerialInterfaceClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a Serial Interface object with obj_id 0
SerialInterface = SerialInterfaceClient(’com’,com);
% Use the Serial Interface object
oldBaud = SerialInterface.get(’baud_rate’); // should be 115200
SerialInterface.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);
SerialInterface = SerialInterfaceClient(’com’,com);
newBaud = SerialInterface.get(’baud_rate’); // should be 9600
Python¶
To use the Serial Interface Client in Python, import iqmotion
and create a module that has the Serial Interface Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
vertiq.set("serial_interface", "baud_rate", 9600) # change baud rate to 9600
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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a ServoInputParserClient object. See the Message 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 ServoInputParserClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a ServoInputParserClient object with obj_id 0
ServoInputParser = ServoInputParserClient(’com’,com);
% Use the ServoInputParserClient object
ServoInputParser.set(’mode’, 3); // Position control mode
ServoInputParser.save(’mode’);
ServoInputParser.set(’unit_min’, -pi);
ServoInputParser.save(’unit_min’);
ServoInputParser.set(’unit_max’, pi);
ServoInputParser.save(’unit_max’);
Python¶
To use the Servo Input Parser Client in Python, import iqmotion
and create a module that has the Servo Input Parser Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0, firmware="servo")
# Set Servo Limits
vertiq.set("servo_input_parser", "mode", 3) # Position Control Mode
vertiq.set("servo_input_parser", "unit_min", -math.pi) # Min position: -pi
vertiq.set("servo_input_parser", "unit_max", math.pi) # Max position: pi
# Save Servo Limits
vertiq.save("servo_input_parser", "mode")
vertiq.save("servo_input_parser", "unit_min")
vertiq.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
\(\text{Enum}\)
0 = PWM, 1 = Voltage, 2 = Velocity, 3 = Position
1
unit_min
get, set, save
float
\(\text{(mode)}\)
Minimum value. Unit determined by mode.
2
unit_max
get, set, save
float
\(\text{(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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a SystemControlClient object. See the Message 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 SystemControlClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make a System Control object with obj_id 0
SystemControl = SystemControlClient(’com’,com);
% Use the System Control object
time = SystemControl.get(’time’);
Python¶
To use the System Control Client in Python, import iqmotion
and create a module that has the System Control Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
FW = vertiq.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
\(\text{Kb}\)
8
build_year
get
uint16
\(\text{year}\)
9
build_month
get
uint8
\(\text{mon}\)
10
build_day
get
uint8
\(\text{day}\)
11
build_hour
get
uint8
\(\text{hour}\)
12
build_minute
get
uint8
\(\text{min}\)
13
build_second
get
uint8
\(s\)
14
module_id
get, set, save
uint8
\(\text{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
\(\text{ver}\)
17
hardware_version
get, set, save
uint32
\(\text{ver}\)
18
electronics_version
get, set, save
uint32
\(\text{ver}\)
19
firmware_valid
get
uint8
\(\text{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 the Message 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 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 the Message 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 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"
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]
}
Matlab¶
To use the Temperature Estimator client in Matlab, all Vertiq communication code must be included in your path. This allows the creation of a TemperatureEstimatorClient object. See the Message 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 TemperatureEstimatorClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureEstimatorClient object with obj_id 0
TemperatureEstimator = TemperatureEstimatorClient(’com’,com);
% Use the TemperatureEstimatorClient object
coilTemp = TemperatureEstimator.get(’temp’);
Python¶
To use the Temperature Estimator Client in Python, import iqmotion
and create a module that has the Temperature Estimator Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
temp = vertiq.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
\(^{\circ}C\)
Temperature of the motor coils
1
otw
get, set, save
float
\(^{\circ}C\)
Over temperature warning. Derating of the motor begins at this temperature.
2
otlo
get, set, save
float
\(^{\circ}C\)
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
\(\frac{K}{W}\)
Model thermal resistance
4
thermal_capacitance
get, set, save
float
\(\frac{J}{K}\)
Model thermal capacitance
5
derate
get
Fix16
\(\text{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 the Message 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 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 the Message 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 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 Vertiq communication code must be included in your path. This allows the creation of a TemperatureMonitorUcClient object. See the Message 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 TemperatureMonitorUcClient is:
% Make a communication interface object
com = MessageInterface(’COM18’,115200);
% Make an TemperatureMonitorUcClient object with obj_id 0
TemperatureMonitorUc = TemperatureMonitorUcClient(’com’,com);
% Use the TemperatureMonitorUcClient object
ucTemp = TemperatureMonitorUc.get(’uc_temp’);
Python¶
To use the Temperature Monitor Microcontroller Client in Python, import iqmotion
and create a module that has the Temperature Monitor Microcontroller Client within its firmware.
See the Message 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")
vertiq = iq.Vertiq8108(com, 0)
temp = vertiq.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
\(^{\circ}C\)
Temperature of the microcontroller
1
filter_fs
get
uint32
\(\text{Hz}\)
Low pass filter sample frequency
2
filter_fc
get, set, save
uint32
\(\text{Hz}\)
Low pass filter cutoff frequency
3
otw
get, set, save
float
\(^{\circ}C\)
Over temperature warning. Derating of the motor begins at this temperature.
4
otlo
get, set, save
float
\(^{\circ}C\)
Over temperature lock out. Derating of the motor end at this temperature, where the motor is fully disabled.
5
derate
get
float
\(\text{PU}\)
Amount of derating applied to motor [0 1]