mirror of https://github.com/ArduPilot/ardupilot
244 lines
11 KiB
Markdown
244 lines
11 KiB
Markdown
# FETtec OneWire
|
|
|
|
FETtec OneWire is an [ESC](https://en.wikipedia.org/wiki/Electronic_speed_control) communication protocol created by Felix Niessen (former Flyduino KISS developer) from [FETtec](https://fettec.net).
|
|
It is a (bidirectional) [digital full-duplex asynchronous serial communication protocol](https://en.wikipedia.org/wiki/Asynchronous_serial_communication) running at 500Kbit/s Baudrate. It requires three wire (RX, TX and GND) connection (albeit the name OneWire) regardless of the number of ESCs connected.
|
|
Unlike bidirectional-Dshot, the FETtec OneWire protocol does not need one DMA channel per ESC for bidirectional communication.
|
|
|
|
For purchase, connection and configuration information please see the [ArduPilot FETtec OneWire wiki page](https://ardupilot.org/copter/docs/common-fettec-onewire.html).
|
|
|
|
## Features of this device driver
|
|
|
|
- use ArduPilot's coding guidelines and naming conventions
|
|
- control motor speed
|
|
- Use the AP_ESC_Telem base class to:
|
|
- copy ESC telemetry data into MAVLink telemetry
|
|
- save ESC telemetry data in dataflash logs
|
|
- use RPM telemetry for dynamic notch filter frequencies
|
|
- sum the current telemetry info from all ESCs and use it as virtual battery current monitor sensor
|
|
- average the voltage telemetry info and use it as virtual battery voltage monitor sensor
|
|
- average the temperature telemetry info and use it as virtual battery temperature monitor sensor
|
|
- Obey the safety switch. Keeps motors from turning
|
|
- Use `SERVO_FWT_MASK` to define which servo output should be routed to FETtec ESCs
|
|
- Use `SERVO_FWT_RVMASK` to define the rotation direction of the motors
|
|
- `SERVO_FWT_RVMASK` changes only take effect when disarmed
|
|
- Can be compiled when `HAL_WITH_ESC_TELEM` is disabled. No telemetry data will be available but it saves a lot of memory
|
|
- pre-arm checks:
|
|
- Check that UART is available
|
|
- check that the desired motor channels parameter (`SERVO_FWT_MASK`) is valid
|
|
- check that the desired motor poles parameter (`SERVO_FWT_POLES`) is valid
|
|
- check that the all desired ESCs are found and configured
|
|
- check that the ESCs are periodically sending telemetry data
|
|
- re-init and configure an ESC(s) if not armed (motors not spinning) when
|
|
- telemetry communication with the ESC(s) is lost
|
|
- adds a serial simulator (--serial5=sim:fetteconewireesc) of FETtec OneWire ESCs
|
|
- adds autotest (using the simulator) to:
|
|
- simulate telemetry voltage, current, temperature, RPM data using SITL internal variables
|
|
- test the safety switch functionality
|
|
- test ESC power outages
|
|
- test `SERVO_FWT_MASK` parameter validation
|
|
- fly a copter over a simulated serial link connection
|
|
|
|
|
|
## ArduPilot to ESC protocol
|
|
|
|
The FETtec OneWire protocol supports up to 24 ESCs without telemetry and up to 15 ESCs with telemetry.
|
|
|
|
There are two types of messages sent to the ESCs configuration and fast-throttle messages:
|
|
|
|
### Configuration message frame
|
|
Consists of six frame bytes + payload bytes.
|
|
|
|
```
|
|
Byte 0 is the source type
|
|
Byte 1 is the ID
|
|
Byte 2 is the frame type (Low byte)
|
|
Byte 3 is the frame type (High byte)
|
|
Byte 4 is the frame length
|
|
Byte 5-254 is the payload
|
|
Byte 6-255 is CRC (last Byte after the Payload). It uses the same CRC algorithm as Dshot.
|
|
```
|
|
|
|
#### Check if bootloader or ESC firmware is running
|
|
To check which firmware is running on the FETtec an ESCs `PackedMessage<OK>` is sent to each ESC.
|
|
If the answer frame `frame_source` is FrameSource::BOOTLOADER we are in bootloader and need to send an `PackedMessage<START_FW>` to start the ESC firmware.
|
|
If the answer frame `frame_source` is FrameSource::ESC we are already running the correct firmware and can directly configure the telemetry.
|
|
|
|
#### Start the ESC firmware
|
|
If the ESC is running on bootloader firmware we need to send an `PackedMessage<START_FW>` to start the ESC firmware.
|
|
The answer must be a `PackedMessage<OK>` with `frame_source` equal to FrameSource::ESC. If not, we need to repeat the command.
|
|
|
|
#### Configure Full/Alternative Telemetry
|
|
The telemetry can be switched to "per ESC" Mode, where one ESC answers with it's full telemetry as oneWire package including CRC and additionally the CRC Errors counted by the ESC.
|
|
To use this mode, `PackedMessage<SET_TLM_TYPE>` is send to each ESC while initializing.
|
|
If this was successful the ESC responds with `PackedMessage<OK>`.
|
|
|
|
#### Configure Fast throttle messages
|
|
To configure the fast-throttle frame structure a `PackedMessage<SET_FAST_COM_LENGTH>` is send to each ESC while initializing.
|
|
If this was successful the ESC responds with `PackedMessage<OK>`.
|
|
|
|
### Fast-throttle message frame
|
|
|
|
```
|
|
Byte 0 is the frame header
|
|
Byte 1 is the telemetry request and part of fast throttle signal
|
|
Byte N is CRC (last Byte after the Payload). It uses the same CRC algorithm as Dshot.
|
|
```
|
|
The first two bytes are frame header and telemetry request as well as the first parts of the throttle signal.
|
|
The following bytes are transmitting the throttle signals for the ESCs (11bit per ESC) followed by the CRC.
|
|
The signal is used to transfer the eleven bit throttle signals with as few bytes as possible:
|
|
|
|
```
|
|
[990 .. 0] - negative throttle, rotation in one direction (depends on the motor wiring connection). 980 minimum throttle, 00 maximum throttle
|
|
[991 .. 1009] - no rotation, dead-band
|
|
[1010 .. 2000] - positive throttle, rotation in the other direction. 1020 minimum throttle, 2000 maximum throttle
|
|
```
|
|
All motors wait for the complete message with all throttle signals before changing their output.
|
|
|
|
If telemetry is requested the ESCs will answer them in the ESC-ID order.
|
|
See *ESC to ArduPilot Protocol* section below and comments in `AP_FETtecOneWire.cpp` for details.
|
|
|
|
|
|
### Timing
|
|
|
|
Four ESCs need 90us for the fast-throttle request and telemetry reception. With four ESCs 11kHz update would be possible.
|
|
Each additional ESC adds 11 extra fast-throttle command bits, so the update rate is lowered by each additional ESC.
|
|
If you use 8 ESCs, it needs 160us including telemetry response, so 5.8kHz update rate would be possible.
|
|
The FETtec ArduPilot device driver limits the message transmit period to `_min_fast_throttle_period_us` according to the number of ESCs used.
|
|
The update() function has an extra invocation period limit so that even at very high loop rates the ESCs will still operate correctly albeit doing some decimation.
|
|
The current update rate for Copter is 400Hz (~2500us) and for other vehicles is 50Hz (~20000us) so we are bellow device driver limit.
|
|
|
|
**Note:** The FETtec ESCs firmware requires at least a 4Hz fast-throttle update rate (max. 250ms between messages) otherwise the FETtec ESC disarm (stop) the motors.
|
|
|
|
## ESC to ArduPilot protocol
|
|
|
|
OneWire ESC telemetry information is sent back to the autopilot:
|
|
|
|
- Electronic rotations per minute (eRPM/100) (must be divided by number of motor poles to translate to propeller RPM)
|
|
- Input voltage (V/10)
|
|
- Current draw (A/10)
|
|
- Power consumption (mAh)
|
|
- Temperature (°C/10)
|
|
- CRC errors (ArduPilot->ESC) counter
|
|
|
|
This information is used by ArduPilot to:
|
|
|
|
- log the status of each ESC to the SDCard or internal Flash, for post flight analysis
|
|
- send the status of each ESC to the ground station or companion computer for real-time monitoring
|
|
- Optionally dynamically change the center frequency of the notch filters used to reduce frame vibration noise in the gyros
|
|
- Optionally measure battery voltage and power consumption
|
|
|
|
|
|
### Full/Alternative Telemetry
|
|
The answer to a fast-throttle command frame is a `PackedMessage<TLM>` message frame, received and decoded in the `FETtecOneWire::handle_message_telem()` function.
|
|
The data is forwarded to the `AP_ESC_Telem` class that distributes it to other parts of the ArduPilot code.
|
|
|
|
|
|
## Function structure
|
|
|
|
There are two public top level functions `update()` and `pre_arm_check()`.
|
|
And these two call all other private internal functions.
|
|
A single (per ESC) state variable (`_escs[i]._state`) is used in both the RX and TX state machines.
|
|
Here is the call graph:
|
|
|
|
```
|
|
update()
|
|
init()
|
|
init_uart()
|
|
read_data_from_uart()
|
|
move_frame_source_in_receive_buffer()
|
|
consume_bytes()
|
|
consume_bytes()
|
|
handle_message() <-- RX state machine
|
|
buffer_contains_ok()
|
|
handle_message_telem()
|
|
configure_escs() <-- TX state machine
|
|
transmit_config_request()
|
|
transmit()
|
|
escs_set_values()
|
|
pack_fast_throttle_command()
|
|
transmit()
|
|
pre_arm_check()
|
|
```
|
|
|
|
|
|
## Device driver parameters
|
|
|
|
The `SERVO_FTW_MASK` parameter selects which servo outputs, if any, will be routed to FETtec ESCs.
|
|
You need to reboot after changing this parameter.
|
|
When `HAL_WITH_ESC_TELEM` is active (default) only the first 15 (`ESC_TELEM_MAX_ESCS`) can be used.
|
|
The FETtec ESC IDs set inside the FETtec firmware by the FETtec configuration tool are one-indexed.
|
|
These IDs must start at ID 1 and be in a single contiguous block.
|
|
You do not need to change these FETtec IDs if you change the servo output assignments inside ArduPilot the using the `SERVO_FTW_MASK` parameter.
|
|
|
|
The `SERVO_FTW_RVMASK` parameter selects which servo outputs, if any, will reverse their rotation.
|
|
This parameter effects the outputs immediately when changed and the motors are not armed.
|
|
This parameter is only visible if the `SERVO_FTW_MASK` parameter has at least one bit set.
|
|
|
|
The `SERVO_FTW_POLES` parameter selects Number of motor electrical poles.
|
|
It is used to calculate the motors RPM
|
|
This parameter effects the RPM calculation immediately when changed.
|
|
This parameter is only visible if the `SERVO_FTW_MASK` parameter has at least one bit set.
|
|
|
|
## Extra features
|
|
|
|
### Read type, firmware version and serial number
|
|
To control this you must activate the code in the header file:
|
|
```C++
|
|
// Get static info from the ESCs (optional feature)
|
|
#ifndef HAL_AP_FETTEC_ONEWIRE_GET_STATIC_INFO
|
|
#define HAL_AP_FETTEC_ONEWIRE_GET_STATIC_INFO 1
|
|
#endif
|
|
```
|
|
Or just set the `HAL_AP_FETTEC_ONEWIRE_GET_STATIC_INFO` macro in the compiler toolchain.
|
|
After that you will be able to access this information in the `_escs[]` datastructure.
|
|
|
|
### Beep
|
|
To control this you must activate the code in the header file:
|
|
```C++
|
|
// provide beep support (optional feature)
|
|
#ifndef HAL_AP_FETTEC_ESC_BEEP
|
|
#define HAL_AP_FETTEC_ESC_BEEP 1
|
|
#endif
|
|
```
|
|
|
|
Or just set the `HAL_AP_FETTEC_ESC_BEEP` macro in the compiler toolchain.
|
|
After that you will be able to call the public function:
|
|
|
|
```C++
|
|
/**
|
|
makes all connected ESCs beep
|
|
@param beep_frequency a 8 bit value from 0-255. higher make a higher beep
|
|
*/
|
|
void beep(const uint8_t beep_frequency);
|
|
```
|
|
|
|
### Multicolor RGB Led light
|
|
To control this you must activate the code in the header file:
|
|
```C++
|
|
// provide light support (optional feature)
|
|
#ifndef HAL_AP_FETTEC_ESC_LIGHT
|
|
#define HAL_AP_FETTEC_ESC_LIGHT 1
|
|
#endif
|
|
```
|
|
|
|
Or just set the `HAL_AP_FETTEC_ESC_LIGHT` macro in the compiler toolchain.
|
|
After that you will be able to call the public function:
|
|
|
|
```C++
|
|
/**
|
|
makes all connected ESCs beep
|
|
@param beep_frequency a 8 bit value from 0-255. higher make a higher beep
|
|
*/
|
|
void beep(const uint8_t beep_frequency);
|
|
|
|
/**
|
|
sets the racewire color for all ESCs
|
|
@param r red brightness
|
|
@param g green brightness
|
|
@param b blue brightness
|
|
*/
|
|
void led_color(const uint8_t r, const uint8_t g, const uint8_t b);
|
|
```
|
|
|
|
You need to call these functions on your own code according to your requirements.
|