Behaviour for servo-specific control table definitions.
Each servo model has a different memory layout (control table) that defines the addresses, sizes, and conversions for readable/writable parameters.
Implementing a Control Table
defmodule MyServo do
@behaviour Feetech.ControlTable
@impl true
def model_name, do: "MyServo"
@impl true
def registers do
%{
id: {5, 1, nil},
goal_position: {42, 2, :position},
present_position: {56, 2, :position}
}
end
endConversion Types
The third element of each register tuple specifies how to convert between raw register values and user-friendly values:
nil- No conversion, raw integer value:bool- 0/1 to false/truefloat- Scale factor (e.g.,0.1for voltage in 0.1V units):position- Steps to radians (unsigned, servo-specific):position_signed- Steps to radians with sign-magnitude encoding (bit 15 = sign):speed- Speed units to rad/s:speed_signed- Signed speed to rad/s (sign-magnitude, bit 15 = sign):load_signed- Signed load percentage (sign-magnitude, bit 10 = sign):mode- Operating mode enum:baud_rate- Baud rate enum{:sign_magnitude, sign_bit}- Raw sign-magnitude with specified sign bit{module, decode_fun, encode_fun}- Custom conversion functions
Summary
Types
Memory address in control table
Number of bytes for register
Conversion specification for translating between raw and user values.
Register definition tuple
Register name atom
Map of register names to their definitions
Functions
Decodes raw bytes from a register to a user value.
Decodes raw bytes to an integer (no conversion).
Encodes a user value to raw bytes for writing to a register.
Encodes a raw integer value to bytes (no conversion).
Looks up a register definition by name.
Types
@type address() :: non_neg_integer()
Memory address in control table
@type byte_length() :: 1 | 2 | 4
Number of bytes for register
@type conversion() :: nil | :bool | :position | :position_signed | :speed | :speed_signed | :load_signed | :mode | :baud_rate | float() | {:sign_magnitude, non_neg_integer()} | {module(), atom(), atom()}
Conversion specification for translating between raw and user values.
@type register_def() :: {address(), byte_length(), conversion()}
Register definition tuple
@type register_name() :: atom()
Register name atom
@type registers() :: %{required(register_name()) => register_def()}
Map of register names to their definitions
Callbacks
Functions
@spec decode(module(), register_name(), binary()) :: {:ok, term()} | {:error, atom()}
Decodes raw bytes from a register to a user value.
Decodes raw bytes to an integer (no conversion).
@spec encode(module(), register_name(), term()) :: {:ok, binary()} | {:error, atom()}
Encodes a user value to raw bytes for writing to a register.
@spec encode_raw(module(), register_name(), integer()) :: {:ok, binary()} | {:error, atom()}
Encodes a raw integer value to bytes (no conversion).
@spec get_register(module(), register_name()) :: {:ok, register_def()} | {:error, :unknown_register}
Looks up a register definition by name.