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
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.

9




disarm_behvaior




get, set, save




uint8









The 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.
10



disarm_song_option



get, set, save



uint8







The 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.
11




manual_arming_throttle_source




get, set, save




uint8









The 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 = Hobby
3 = IQUART

12

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

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
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
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
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
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
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
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
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
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

Message Table

Type ID 16 | Serial Interface
Serial Interface

Sub ID

Short Name

Access

Data Type

Unit

Note

0

baud_rate

get, set

uint32

\(\text{Hz}\)

Default is 115200. Reliable up to 2Mbps. Set also performs a save.

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
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
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.

9




stow_status




get, set, save




uint8









The 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.
10




stow_result




get, set, save




uint8









The 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
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
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
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

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

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

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
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
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
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
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
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
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
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
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
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

Message Table

Type ID 16 | Serial Interface
Serial Interface

Sub ID

Short Name

Access

Data Type

Unit

Note

0

baud_rate

get, set

uint32

\(\text{Hz}\)

Default is 115200. Reliable up to 2Mbps. Set also performs a save.

Servo Input Parser

The Servo Input Parser is an interface between the Multi Turn Position Controller and the PWM based inputs like 1-2ms, OneShot, MultiShot, and DShot. This parser allows the user to control how ratiomatic values from the PWM input are translated. Inputs can be mapped to PWM control, voltage control, velocity control, and position control. Values are mapped between a minimum value and a maximum value, while their units are interpreted based on the mapping.

Arduino

To use Servo Input Parser in Arduino, ensure iq_module_communication.hpp is included. This allows the creation of a ServoInputParserClient object. See 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
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
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
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
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]