Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-os nRF24L01P
MX12.h@14:1b41c5adf46e, 2022-10-13 (annotated)
- Committer:
- evedelegue
- Date:
- Thu Oct 13 10:39:25 2022 +0000
- Revision:
- 14:1b41c5adf46e
- Parent:
- 9:67d737d8a349
je ne sais plus si je l'avais bien commit;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
evedelegue | 9:67d737d8a349 | 1 | /** |
evedelegue | 9:67d737d8a349 | 2 | * @file MX12.h |
evedelegue | 9:67d737d8a349 | 3 | * @brief this header file contains all required definitions and |
evedelegue | 9:67d737d8a349 | 4 | * basic utilities functions to manage au bus of servomotor |
evedelegue | 9:67d737d8a349 | 5 | * Dynaminel MX12 |
evedelegue | 9:67d737d8a349 | 6 | */ |
evedelegue | 9:67d737d8a349 | 7 | #ifndef MBED_MX12_H_ |
evedelegue | 9:67d737d8a349 | 8 | #define MBED_MX12_H_ |
evedelegue | 9:67d737d8a349 | 9 | |
evedelegue | 9:67d737d8a349 | 10 | #include "mbed.h" |
evedelegue | 9:67d737d8a349 | 11 | |
evedelegue | 9:67d737d8a349 | 12 | #define MX12_PACKET_MAX_SIZE 32 |
evedelegue | 9:67d737d8a349 | 13 | #define MX12_MAX_MOTOR_COUNT 16 |
evedelegue | 9:67d737d8a349 | 14 | |
evedelegue | 9:67d737d8a349 | 15 | #define MX12_SPEED_QUANTA_RPM 0.916 /* Data from MX12 e-manual */ |
evedelegue | 9:67d737d8a349 | 16 | #define MX12_ABSOLUTE_MAX_SPEED_RAD_S 98.13 |
evedelegue | 9:67d737d8a349 | 17 | |
evedelegue | 9:67d737d8a349 | 18 | |
evedelegue | 9:67d737d8a349 | 19 | |
evedelegue | 9:67d737d8a349 | 20 | /* Dynamixel protocol v1.0 : Instructions |
evedelegue | 9:67d737d8a349 | 21 | ******************************************/ |
evedelegue | 9:67d737d8a349 | 22 | #define PROTOCOL_INSTRUCTION_PING 0x01 |
evedelegue | 9:67d737d8a349 | 23 | #define PROTOCOL_INSTRUCTION_READ 0x02 |
evedelegue | 9:67d737d8a349 | 24 | #define PROTOCOL_INSTRUCTION_WRITE 0x03 |
evedelegue | 9:67d737d8a349 | 25 | #define PROTOCOL_INSTRUCTION_REG_WRITE 0x04 |
evedelegue | 9:67d737d8a349 | 26 | #define PROTOCOL_INSTRUCTION_ACTION 0x05 |
evedelegue | 9:67d737d8a349 | 27 | #define PROTOCOL_INSTRUCTION_FACTORY_RESET 0x06 |
evedelegue | 9:67d737d8a349 | 28 | #define PROTOCOL_INSTRUCTION_REBOOT 0x08 |
evedelegue | 9:67d737d8a349 | 29 | #define PROTOCOL_INSTRUCTION_SYNC_WRITE 0x83 |
evedelegue | 9:67d737d8a349 | 30 | #define PROTOCOL_INSTRUCTION_BULK_READ 0x92 |
evedelegue | 9:67d737d8a349 | 31 | |
evedelegue | 9:67d737d8a349 | 32 | /* Dynamixel protocol v1.0 : Contro table content |
evedelegue | 9:67d737d8a349 | 33 | ************************************************/ |
evedelegue | 9:67d737d8a349 | 34 | #define CONTROL_TABLE_MODEL_NUMBER 0 |
evedelegue | 9:67d737d8a349 | 35 | #define CONTROL_TABLE_FIRMWARE_VERSION 2 |
evedelegue | 9:67d737d8a349 | 36 | #define CONTROL_TABLE_ID 3 |
evedelegue | 9:67d737d8a349 | 37 | #define CONTROL_TABLE_BAUD_RATE 4 |
evedelegue | 9:67d737d8a349 | 38 | #define CONTROL_TABLE_RETURN_DELAY_TIME 5 |
evedelegue | 9:67d737d8a349 | 39 | #define CONTROL_TABLE_CW_ANGLE_LIMIT 6 |
evedelegue | 9:67d737d8a349 | 40 | #define CONTROL_TABLE_CCW_ANGLE_LIMIT 8 |
evedelegue | 9:67d737d8a349 | 41 | #define CONTROL_TABLE_TEMPERATURE_LIMIT 11 |
evedelegue | 9:67d737d8a349 | 42 | #define CONTROL_TABLE_MIN_VOLTAGE_LIMIT 12 |
evedelegue | 9:67d737d8a349 | 43 | #define CONTROL_TABLE_MAX_VOLTAGE_LIMIT 13 |
evedelegue | 9:67d737d8a349 | 44 | #define CONTROL_TABLE_MAX_TORQUE 14 |
evedelegue | 9:67d737d8a349 | 45 | #define CONTROL_TABLE_STATUS_RETURN_LEVEL 16 |
evedelegue | 9:67d737d8a349 | 46 | #define CONTROL_TABLE_ALARM_LED 17 |
evedelegue | 9:67d737d8a349 | 47 | #define CONTROL_TABLE_SHUTDOWN 18 |
evedelegue | 9:67d737d8a349 | 48 | #define CONTROL_TABLE_MULTITURN_OFFSET 20 |
evedelegue | 9:67d737d8a349 | 49 | #define CONTROL_TABLE_RESOLUTION_DIVIDER 22 |
evedelegue | 9:67d737d8a349 | 50 | #define CONTROL_TABLE_TORQUE_ENABLE 24 |
evedelegue | 9:67d737d8a349 | 51 | #define CONTROL_TABLE_LED 25 |
evedelegue | 9:67d737d8a349 | 52 | #define CONTROL_TABLE_P_GAIN 26 |
evedelegue | 9:67d737d8a349 | 53 | #define CONTROL_TABLE_I_GAIN 27 |
evedelegue | 9:67d737d8a349 | 54 | #define CONTROL_TABLE_D_GAIN 28 |
evedelegue | 9:67d737d8a349 | 55 | #define CONTROL_TABLE_GOAL_POSITION 30 |
evedelegue | 9:67d737d8a349 | 56 | #define CONTROL_TABLE_MOVING_SPEED 32 |
evedelegue | 9:67d737d8a349 | 57 | #define CONTROL_TABLE_TORQUE_LIMIT 34 |
evedelegue | 9:67d737d8a349 | 58 | #define CONTROL_TABLE_PRESENT_POSITION 36 |
evedelegue | 9:67d737d8a349 | 59 | #define CONTROL_TABLE_PRESENT_SPEED 38 |
evedelegue | 9:67d737d8a349 | 60 | #define CONTROL_TABLE_PRESENT_LOAD 40 |
evedelegue | 9:67d737d8a349 | 61 | #define CONTROL_TABLE_PRESENT_VOLTAGE 42 |
evedelegue | 9:67d737d8a349 | 62 | #define CONTROL_TABLE_PRESENT_TEMPERATURE 43 |
evedelegue | 9:67d737d8a349 | 63 | #define CONTROL_TABLE_REGISTRED_INSTRUCTION 44 |
evedelegue | 9:67d737d8a349 | 64 | #define CONTROL_TABLE_MOVING 46 |
evedelegue | 9:67d737d8a349 | 65 | #define CONTROL_TABLE_LOCK 47 |
evedelegue | 9:67d737d8a349 | 66 | #define CONTROL_TABLE_PUNCH 48 |
evedelegue | 9:67d737d8a349 | 67 | #define CONTROL_TABLE_GOAL_ACCELERATION 73 |
evedelegue | 9:67d737d8a349 | 68 | |
evedelegue | 9:67d737d8a349 | 69 | /** |
evedelegue | 9:67d737d8a349 | 70 | * @brief Class to communicate with Dynamixel MX12 servomotors |
evedelegue | 9:67d737d8a349 | 71 | * |
evedelegue | 9:67d737d8a349 | 72 | * @details |
evedelegue | 9:67d737d8a349 | 73 | * |
evedelegue | 9:67d737d8a349 | 74 | * The servomotors are daisy chained to a serial link of the target |
evedelegue | 9:67d737d8a349 | 75 | * microcontroller. The class ensures the initialization of serial link |
evedelegue | 9:67d737d8a349 | 76 | * and the management of communications mainly to control rotational |
evedelegue | 9:67d737d8a349 | 77 | * speed of servomotors. |
evedelegue | 9:67d737d8a349 | 78 | * |
evedelegue | 9:67d737d8a349 | 79 | * Transmission of messages to the servomotors is blocking while |
evedelegue | 9:67d737d8a349 | 80 | * reception is non-blocking thanks to the use of an interrupt routine. |
evedelegue | 9:67d737d8a349 | 81 | * |
evedelegue | 9:67d737d8a349 | 82 | * @author Titouan Soulard (creator and maintainer until April 2021) |
evedelegue | 9:67d737d8a349 | 83 | * @author Bruno Denis (Doxygen documentation and code rearrangement) |
evedelegue | 9:67d737d8a349 | 84 | * |
evedelegue | 9:67d737d8a349 | 85 | * @see Control table of Dynamixel MX12 servomotor |
evedelegue | 9:67d737d8a349 | 86 | * @see https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/ |
evedelegue | 9:67d737d8a349 | 87 | * @see Dynamixel protocol v1.0 manual |
evedelegue | 9:67d737d8a349 | 88 | * @see https://emanual.robotis.com/docs/en/dxl/protocol1/ |
evedelegue | 9:67d737d8a349 | 89 | * |
evedelegue | 9:67d737d8a349 | 90 | * Example of class usage to send two instruction packets to servomotor #1 |
evedelegue | 9:67d737d8a349 | 91 | * with one second gap. First ask to move at 10% of maximum speed and the |
evedelegue | 9:67d737d8a349 | 92 | * stop the movement. |
evedelegue | 9:67d737d8a349 | 93 | * |
evedelegue | 9:67d737d8a349 | 94 | * @code |
evedelegue | 9:67d737d8a349 | 95 | * #include "mbed.h" |
evedelegue | 9:67d737d8a349 | 96 | * #include "MX12.h" |
evedelegue | 9:67d737d8a349 | 97 | * |
evedelegue | 9:67d737d8a349 | 98 | * #define SERVO_TX_PIN PC_4 |
evedelegue | 9:67d737d8a349 | 99 | * #define SERVO_RX_PIN PC_5 |
evedelegue | 9:67d737d8a349 | 100 | * #define SERVO_BAUD 115200 |
evedelegue | 9:67d737d8a349 | 101 | * #define SERVO_ID 1 |
evedelegue | 9:67d737d8a349 | 102 | * |
evedelegue | 9:67d737d8a349 | 103 | * #define DELAY_1000ms 1000 |
evedelegue | 9:67d737d8a349 | 104 | * #define DELAY_1ms 1 |
evedelegue | 9:67d737d8a349 | 105 | * |
evedelegue | 9:67d737d8a349 | 106 | * MX12 servo_bus(SERVO_TX_PIN, SERVO_RX_PIN, SERVO_BAUD); |
evedelegue | 9:67d737d8a349 | 107 | * float relative_speed; |
evedelegue | 9:67d737d8a349 | 108 | * |
evedelegue | 9:67d737d8a349 | 109 | * int main() |
evedelegue | 9:67d737d8a349 | 110 | * { |
evedelegue | 9:67d737d8a349 | 111 | * // Set speed of SERVO_ID servomotor to 10% |
evedelegue | 9:67d737d8a349 | 112 | * // Send on servo_bus to SERVO_ID motor the instruction "moving speed" |
evedelegue | 9:67d737d8a349 | 113 | * // with parameter 0.1 (10% of maximum speed) |
evedelegue | 9:67d737d8a349 | 114 | * relative_speed = 0.1; |
evedelegue | 9:67d737d8a349 | 115 | * servo_bus.SetSpeed(SERVO_ID, relative_speed); |
evedelegue | 9:67d737d8a349 | 116 | * |
evedelegue | 9:67d737d8a349 | 117 | * // wait for one second |
evedelegue | 9:67d737d8a349 | 118 | * thread_sleep_for(DELAY_1000ms); |
evedelegue | 9:67d737d8a349 | 119 | * |
evedelegue | 9:67d737d8a349 | 120 | * // set speed of SERVO_ID servomotor to 0% |
evedelegue | 9:67d737d8a349 | 121 | * relative_speed = 0.0; |
evedelegue | 9:67d737d8a349 | 122 | * servo_bus.SetSpeed(SERVO_ID, relative_speed); |
evedelegue | 9:67d737d8a349 | 123 | * |
evedelegue | 9:67d737d8a349 | 124 | * // infinite loop |
evedelegue | 9:67d737d8a349 | 125 | * while (true) thread_sleep_for(DELAY_1000ms); |
evedelegue | 9:67d737d8a349 | 126 | * } |
evedelegue | 9:67d737d8a349 | 127 | * @endcode |
evedelegue | 9:67d737d8a349 | 128 | * |
evedelegue | 9:67d737d8a349 | 129 | * @warning |
evedelegue | 9:67d737d8a349 | 130 | * Warning: receipt of packets from servomotors has not been tested |
evedelegue | 9:67d737d8a349 | 131 | * (hardwre problem). However, sending move speed instruction is operational. |
evedelegue | 9:67d737d8a349 | 132 | * |
evedelegue | 9:67d737d8a349 | 133 | * @warning |
evedelegue | 9:67d737d8a349 | 134 | * Warning: Error field of status packet if decoded by GetStatus() returns |
evedelegue | 9:67d737d8a349 | 135 | * an enumation type "Status". As several errors can be reported |
evedelegue | 9:67d737d8a349 | 136 | * simultaneously the type enum is not suitable (B. Denis 11/2021). |
evedelegue | 9:67d737d8a349 | 137 | * |
evedelegue | 9:67d737d8a349 | 138 | * @bug |
evedelegue | 9:67d737d8a349 | 139 | * Bug: GetStatus() method has a hazardous behavior because it provides |
evedelegue | 9:67d737d8a349 | 140 | * a result by reading the content of the variable _current_frame |
evedelegue | 9:67d737d8a349 | 141 | * which can be modified at any time by the private ISR _Rx_interrupt(). |
evedelegue | 9:67d737d8a349 | 142 | * |
evedelegue | 9:67d737d8a349 | 143 | */ |
evedelegue | 9:67d737d8a349 | 144 | class MX12 |
evedelegue | 9:67d737d8a349 | 145 | { |
evedelegue | 9:67d737d8a349 | 146 | public: |
evedelegue | 9:67d737d8a349 | 147 | |
evedelegue | 9:67d737d8a349 | 148 | /** Error status occurred during the operation of servomotor. |
evedelegue | 9:67d737d8a349 | 149 | * |
evedelegue | 9:67d737d8a349 | 150 | * @warning |
evedelegue | 9:67d737d8a349 | 151 | * Enumaration type is not suitable for all error status because |
evedelegue | 9:67d737d8a349 | 152 | * it can denote only one error at a time (B. Denis 11/2021) |
evedelegue | 9:67d737d8a349 | 153 | */ |
evedelegue | 9:67d737d8a349 | 154 | enum Status { |
evedelegue | 9:67d737d8a349 | 155 | InstructionError, /**< In case of sending an undefined instruction |
evedelegue | 9:67d737d8a349 | 156 | or delivering the action instruction |
evedelegue | 9:67d737d8a349 | 157 | without the Reg Write instruction */ |
evedelegue | 9:67d737d8a349 | 158 | OverloadError, /**< When the current load cannot be controlled |
evedelegue | 9:67d737d8a349 | 159 | by the set Torque */ |
evedelegue | 9:67d737d8a349 | 160 | ChecksumError, /**< When the Checksum of the transmitted |
evedelegue | 9:67d737d8a349 | 161 | Instruction Packet is incorrect */ |
evedelegue | 9:67d737d8a349 | 162 | RangeError, /**< When an instruction is out of the range |
evedelegue | 9:67d737d8a349 | 163 | for use */ |
evedelegue | 9:67d737d8a349 | 164 | OverheatingError, /**< When internal temperature of servomotor |
evedelegue | 9:67d737d8a349 | 165 | is out of the range of operating |
evedelegue | 9:67d737d8a349 | 166 | temperature set in the Control table */ |
evedelegue | 9:67d737d8a349 | 167 | AngleLimitError, /**< When Goal Position is written out of the |
evedelegue | 9:67d737d8a349 | 168 | range from CW Angle Limit to CCW Angle |
evedelegue | 9:67d737d8a349 | 169 | Limit */ |
evedelegue | 9:67d737d8a349 | 170 | InputVoltageError, /**< When the applied voltage is out of the |
evedelegue | 9:67d737d8a349 | 171 | range of operating voltage set in the |
evedelegue | 9:67d737d8a349 | 172 | Control table */ |
evedelegue | 9:67d737d8a349 | 173 | Unknown, /**< Combination of several errors (Caution: |
evedelegue | 9:67d737d8a349 | 174 | limit of enum approach to code errors) */ |
evedelegue | 9:67d737d8a349 | 175 | Ok ///< no error |
evedelegue | 9:67d737d8a349 | 176 | }; |
evedelegue | 9:67d737d8a349 | 177 | |
evedelegue | 9:67d737d8a349 | 178 | /** Enumeration of states of the medium acces control (MAC) |
evedelegue | 9:67d737d8a349 | 179 | * of the master-slave protocol of the communication between |
evedelegue | 9:67d737d8a349 | 180 | * the robot controller (master) and the servomotors (slaves). |
evedelegue | 9:67d737d8a349 | 181 | */ |
evedelegue | 9:67d737d8a349 | 182 | enum SerialState { |
evedelegue | 9:67d737d8a349 | 183 | Writing, /**< Robot controller send an "instruction packet" |
evedelegue | 9:67d737d8a349 | 184 | (request) to a servomotor */ |
evedelegue | 9:67d737d8a349 | 185 | Reading, /**< Robot controller receive a "status packet" from a |
evedelegue | 9:67d737d8a349 | 186 | requested servomotor */ |
evedelegue | 9:67d737d8a349 | 187 | Idle ///< Robot controller ready for a new cycle request-answer |
evedelegue | 9:67d737d8a349 | 188 | }; |
evedelegue | 9:67d737d8a349 | 189 | |
evedelegue | 9:67d737d8a349 | 190 | /** Structure of store status packet (also known as return packet) |
evedelegue | 9:67d737d8a349 | 191 | * according tne Dynamixel protocol v1.0, which are messages sent |
evedelegue | 9:67d737d8a349 | 192 | * by servomotors to contriller in response of an instruction packet |
evedelegue | 9:67d737d8a349 | 193 | */ |
evedelegue | 9:67d737d8a349 | 194 | struct Status_packet { |
evedelegue | 9:67d737d8a349 | 195 | unsigned char raw[MX12_PACKET_MAX_SIZE]; /**< bytes received */ |
evedelegue | 9:67d737d8a349 | 196 | unsigned char n_byte; /**< Number of received byte */ |
evedelegue | 9:67d737d8a349 | 197 | unsigned char servo_id; /**< Identifier field denoted servomotor |
evedelegue | 9:67d737d8a349 | 198 | * involved in the message */ |
evedelegue | 9:67d737d8a349 | 199 | unsigned char length; /**< Length field of status packet */ |
evedelegue | 9:67d737d8a349 | 200 | unsigned char error; /**< Error field of status packet */ |
evedelegue | 9:67d737d8a349 | 201 | unsigned char n_param; /**< Number of received parameter*/ |
evedelegue | 9:67d737d8a349 | 202 | unsigned char param[MX12_PACKET_MAX_SIZE]; /**< array of received |
evedelegue | 9:67d737d8a349 | 203 | * parameters */ |
evedelegue | 9:67d737d8a349 | 204 | unsigned char received_checksum; /**< Received checksum field */ |
evedelegue | 9:67d737d8a349 | 205 | unsigned char calculated_checksum; /**< Calculated checksum */ |
evedelegue | 9:67d737d8a349 | 206 | bool parsed; /**< status packet is correctly parsed */ |
evedelegue | 9:67d737d8a349 | 207 | bool valid; /**< received_checksum == calculated_checksum */ |
evedelegue | 9:67d737d8a349 | 208 | }; |
evedelegue | 9:67d737d8a349 | 209 | |
evedelegue | 9:67d737d8a349 | 210 | /** |
evedelegue | 9:67d737d8a349 | 211 | * @brief Discrete states of the packet parser. |
evedelegue | 9:67d737d8a349 | 212 | * |
evedelegue | 9:67d737d8a349 | 213 | * @detail |
evedelegue | 9:67d737d8a349 | 214 | * Each value corresponding to a field that the parser |
evedelegue | 9:67d737d8a349 | 215 | * can identify according the Dynamixel protocol v1.0. |
evedelegue | 9:67d737d8a349 | 216 | * Enumeration include field of instruction packets |
evedelegue | 9:67d737d8a349 | 217 | * (packets sent to servomotors) and field of status packets |
evedelegue | 9:67d737d8a349 | 218 | * (packets received from servomotors). |
evedelegue | 9:67d737d8a349 | 219 | */ |
evedelegue | 9:67d737d8a349 | 220 | enum PacketField { |
evedelegue | 9:67d737d8a349 | 221 | Header1, ///< Heading1 field of instruction or status packet |
evedelegue | 9:67d737d8a349 | 222 | Header2, ///< Heading2 field of instruction or status packet |
evedelegue | 9:67d737d8a349 | 223 | Id, ///< ID field of instruction or status packet |
evedelegue | 9:67d737d8a349 | 224 | Length, ///< Length field of status packet |
evedelegue | 9:67d737d8a349 | 225 | Error, ///< Error status field of status packet |
evedelegue | 9:67d737d8a349 | 226 | Instruction, ///< Instruction field of instruction packet |
evedelegue | 9:67d737d8a349 | 227 | Data, ///< expect to read parameter fields of status packet |
evedelegue | 9:67d737d8a349 | 228 | Checksum ///< expect to read Checksum field of status packet |
evedelegue | 9:67d737d8a349 | 229 | }; |
evedelegue | 9:67d737d8a349 | 230 | |
evedelegue | 9:67d737d8a349 | 231 | /** Structure to store the current state of packet parserComplement to the ParsingState enumeration to store the reading |
evedelegue | 9:67d737d8a349 | 232 | * progress of each section of the status packet. |
evedelegue | 9:67d737d8a349 | 233 | */ |
evedelegue | 9:67d737d8a349 | 234 | struct ParserState { |
evedelegue | 9:67d737d8a349 | 235 | MX12::PacketField expected_field; ///< next expected field |
evedelegue | 9:67d737d8a349 | 236 | unsigned char byte_index; ///< index of byte already parsed |
evedelegue | 9:67d737d8a349 | 237 | unsigned char param_index; ///< index of parameter already parsed |
evedelegue | 9:67d737d8a349 | 238 | }; |
evedelegue | 9:67d737d8a349 | 239 | |
evedelegue | 9:67d737d8a349 | 240 | /** Create an instance of MX12 and attach it to a serial link |
evedelegue | 9:67d737d8a349 | 241 | * |
evedelegue | 9:67d737d8a349 | 242 | * @param tx board pin used for transmission in UART daisy chain link |
evedelegue | 9:67d737d8a349 | 243 | * to servomotors |
evedelegue | 9:67d737d8a349 | 244 | * @param rx board pin used for reception in UART daisy chain link |
evedelegue | 9:67d737d8a349 | 245 | * to servomotors |
evedelegue | 9:67d737d8a349 | 246 | * @param baud modulation rate of UART signal, unit: Baud |
evedelegue | 9:67d737d8a349 | 247 | * to servomotors |
evedelegue | 9:67d737d8a349 | 248 | */ |
evedelegue | 9:67d737d8a349 | 249 | MX12(PinName tx, PinName rx, int baud=115200); |
evedelegue | 9:67d737d8a349 | 250 | |
evedelegue | 9:67d737d8a349 | 251 | /** Send desired normalized speed to a specific servomotor |
evedelegue | 9:67d737d8a349 | 252 | * |
evedelegue | 9:67d737d8a349 | 253 | * @param mot_id a unique value in the daisy chain network to identify |
evedelegue | 9:67d737d8a349 | 254 | * each servomotor |
evedelegue | 9:67d737d8a349 | 255 | * @param speed a float between -1 and 1 that represents the percentage |
evedelegue | 9:67d737d8a349 | 256 | * of maximum requested speed |
evedelegue | 9:67d737d8a349 | 257 | */ |
evedelegue | 9:67d737d8a349 | 258 | void SetSpeed(unsigned char mot_id, float speed); |
evedelegue | 9:67d737d8a349 | 259 | |
evedelegue | 9:67d737d8a349 | 260 | /** Send desired ablosute speed to a specific servomotor |
evedelegue | 9:67d737d8a349 | 261 | * |
evedelegue | 9:67d737d8a349 | 262 | * @param mot_id a unique value in the daisy chain network to identify |
evedelegue | 9:67d737d8a349 | 263 | * each servomotor |
evedelegue | 9:67d737d8a349 | 264 | * @param speed desired speed in radians per second |
evedelegue | 9:67d737d8a349 | 265 | */ |
evedelegue | 9:67d737d8a349 | 266 | void SetSpeed_rad_s(unsigned char mot_id, float speed); |
evedelegue | 9:67d737d8a349 | 267 | |
evedelegue | 9:67d737d8a349 | 268 | /** Informs about the availability of the bus for a new transmission |
evedelegue | 9:67d737d8a349 | 269 | * of instruction packet (Method Access Control) |
evedelegue | 9:67d737d8a349 | 270 | * |
evedelegue | 9:67d737d8a349 | 271 | * @returns true if bus ready for a new transmission, otherwise false |
evedelegue | 9:67d737d8a349 | 272 | */ |
evedelegue | 9:67d737d8a349 | 273 | char IsAvailable(void); |
evedelegue | 9:67d737d8a349 | 274 | |
evedelegue | 9:67d737d8a349 | 275 | /** |
evedelegue | 9:67d737d8a349 | 276 | * @brief Build and send an instruction packet to a servomotor |
evedelegue | 9:67d737d8a349 | 277 | * according Dynamixel Protocol 1.0 |
evedelegue | 9:67d737d8a349 | 278 | * |
evedelegue | 9:67d737d8a349 | 279 | * @detail This method is limited to only two kind of instruction : |
evedelegue | 9:67d737d8a349 | 280 | * read data from a servomoteur et write data on servomotor. |
evedelegue | 9:67d737d8a349 | 281 | * Ping, Reg Write, Action, Factory Reset, Rebbot, Sync Write |
evedelegue | 9:67d737d8a349 | 282 | * and Bulk Read are not supported. |
evedelegue | 9:67d737d8a349 | 283 | * |
evedelegue | 9:67d737d8a349 | 284 | * For the method to issue a read instruction, set the data |
evedelegue | 9:67d737d8a349 | 285 | * parameter to NULL, otherwise the method issue a |
evedelegue | 9:67d737d8a349 | 286 | * write instruction |
evedelegue | 9:67d737d8a349 | 287 | * |
evedelegue | 9:67d737d8a349 | 288 | * @param[in] mot_id indicates the ID of the device (servomotor) that |
evedelegue | 9:67d737d8a349 | 289 | * should receive the Instruction Packet and process it |
evedelegue | 9:67d737d8a349 | 290 | * @param[in] address data address in the "Control Table of RAM Area" |
evedelegue | 9:67d737d8a349 | 291 | * of a servomotor MX12 |
evedelegue | 9:67d737d8a349 | 292 | * (https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/#control-table-of-ram-area). |
evedelegue | 9:67d737d8a349 | 293 | * @param[in] len if it is a write instruction, size in bytes |
evedelegue | 9:67d737d8a349 | 294 | * of the data to write in the "Control Table of RAM Area" |
evedelegue | 9:67d737d8a349 | 295 | * @param[in] data array of char containing parameter of Danamixel |
evedelegue | 9:67d737d8a349 | 296 | * protocol that are the instruction’s auxiliary data field. |
evedelegue | 9:67d737d8a349 | 297 | * Set to NULL for read instruction, otherwise the method issue |
evedelegue | 9:67d737d8a349 | 298 | * a write instruction |
evedelegue | 9:67d737d8a349 | 299 | * |
evedelegue | 9:67d737d8a349 | 300 | * @see https://emanual.robotis.com/docs/en/dxl/protocol1/ |
evedelegue | 9:67d737d8a349 | 301 | * |
evedelegue | 9:67d737d8a349 | 302 | * Structure of instruction Packet |
evedelegue | 9:67d737d8a349 | 303 | * |
evedelegue | 9:67d737d8a349 | 304 | * <PRE> |
evedelegue | 9:67d737d8a349 | 305 | * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum| |
evedelegue | 9:67d737d8a349 | 306 | * |-------|-------|---------|------|-----------|---------------|--------| |
evedelegue | 9:67d737d8a349 | 307 | * | 0xFF | 0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM | |
evedelegue | 9:67d737d8a349 | 308 | * | cmd[0]| cmd[1]| cmd[2] |cmd[3]| cmd[4] |cmd[5]... | | |
evedelegue | 9:67d737d8a349 | 309 | * \\__ ___/ \\_ _/ \\__ __/ |
evedelegue | 9:67d737d8a349 | 310 | * \/ \/ \/ |
evedelegue | 9:67d737d8a349 | 311 | * mot_id address data |
evedelegue | 9:67d737d8a349 | 312 | * (len = N-1) |
evedelegue | 9:67d737d8a349 | 313 | * </PRE> |
evedelegue | 9:67d737d8a349 | 314 | */ |
evedelegue | 9:67d737d8a349 | 315 | void rw(unsigned char mot_id, char address, char len, char *data); |
evedelegue | 9:67d737d8a349 | 316 | |
evedelegue | 9:67d737d8a349 | 317 | /** |
evedelegue | 9:67d737d8a349 | 318 | * Display status packet in hexadecimal format |
evedelegue | 9:67d737d8a349 | 319 | * |
evedelegue | 9:67d737d8a349 | 320 | * @warning |
evedelegue | 9:67d737d8a349 | 321 | * Use console without any previous declaration. Assume console is |
evedelegue | 9:67d737d8a349 | 322 | * setup by calling program |
evedelegue | 9:67d737d8a349 | 323 | */ |
evedelegue | 9:67d737d8a349 | 324 | void PrintSerial(); |
evedelegue | 9:67d737d8a349 | 325 | |
evedelegue | 9:67d737d8a349 | 326 | /** |
evedelegue | 9:67d737d8a349 | 327 | * Get information from de Error byte of the last status packet |
evedelegue | 9:67d737d8a349 | 328 | * received from a servomotor |
evedelegue | 9:67d737d8a349 | 329 | * |
evedelegue | 9:67d737d8a349 | 330 | * @return |
evedelegue | 9:67d737d8a349 | 331 | * One of enum MX12::Status value to describe errors. 'Ok' is |
evedelegue | 9:67d737d8a349 | 332 | * returns if no error occurred during the last operation of |
evedelegue | 9:67d737d8a349 | 333 | * servomotor. |
evedelegue | 9:67d737d8a349 | 334 | * |
evedelegue | 9:67d737d8a349 | 335 | * @warning |
evedelegue | 9:67d737d8a349 | 336 | * Warning: if a combination of several errors is reported the function |
evedelegue | 9:67d737d8a349 | 337 | * returns "Unknown". |
evedelegue | 9:67d737d8a349 | 338 | * |
evedelegue | 9:67d737d8a349 | 339 | * @bug |
evedelegue | 9:67d737d8a349 | 340 | * Bug: this method has a hazardous behavior because it provides |
evedelegue | 9:67d737d8a349 | 341 | * a result by reading the content of the variable _current_frame |
evedelegue | 9:67d737d8a349 | 342 | * which can be modified at any time by the private ISR _Rx_interrupt() |
evedelegue | 9:67d737d8a349 | 343 | */ |
evedelegue | 9:67d737d8a349 | 344 | MX12::Status GetStatus(void); |
evedelegue | 9:67d737d8a349 | 345 | |
evedelegue | 9:67d737d8a349 | 346 | /* function aivailaible in a previous version of the class |
evedelegue | 9:67d737d8a349 | 347 | */ |
evedelegue | 9:67d737d8a349 | 348 | // MX12::Status GetStatus(void); |
evedelegue | 9:67d737d8a349 | 349 | // void ReadPosition(unsigned char mot_id); |
evedelegue | 9:67d737d8a349 | 350 | // float GetPosition(unsigned char mot_id); |
evedelegue | 9:67d737d8a349 | 351 | |
evedelegue | 9:67d737d8a349 | 352 | void cmd_moteur(float Vavance, float Vlat, float Wz); |
evedelegue | 9:67d737d8a349 | 353 | // envoie la commande moteur de manière à avancer d'une vitesse Vavance en |
evedelegue | 9:67d737d8a349 | 354 | // mètres par seconde, d'une vitesse Vlat en mètre par seconde et d'une |
evedelegue | 9:67d737d8a349 | 355 | // vitesse de rotation Wz en rad/s |
evedelegue | 9:67d737d8a349 | 356 | |
evedelegue | 9:67d737d8a349 | 357 | void eteindre_moteurs(); |
evedelegue | 9:67d737d8a349 | 358 | // permet d'enlever le couple dans les moteurs |
evedelegue | 9:67d737d8a349 | 359 | |
evedelegue | 9:67d737d8a349 | 360 | void cmd_moteur_multiturn(float pos1, float pos2, float pos3); |
evedelegue | 9:67d737d8a349 | 361 | |
evedelegue | 9:67d737d8a349 | 362 | |
evedelegue | 9:67d737d8a349 | 363 | protected: |
evedelegue | 9:67d737d8a349 | 364 | |
evedelegue | 9:67d737d8a349 | 365 | /** Serial port where servomotor bus is connected |
evedelegue | 9:67d737d8a349 | 366 | */ |
evedelegue | 9:67d737d8a349 | 367 | UnbufferedSerial _mx12; |
evedelegue | 9:67d737d8a349 | 368 | |
evedelegue | 9:67d737d8a349 | 369 | |
evedelegue | 9:67d737d8a349 | 370 | /** Servomotor bus state to managed medium acces control (MAC) |
evedelegue | 9:67d737d8a349 | 371 | */ |
evedelegue | 9:67d737d8a349 | 372 | MX12::SerialState _bus_state; |
evedelegue | 9:67d737d8a349 | 373 | |
evedelegue | 9:67d737d8a349 | 374 | /** Structure filled by ISR (Interrupt Service Routine) ReadCallback() |
evedelegue | 9:67d737d8a349 | 375 | * parser to store message received from servomotor byte after byte |
evedelegue | 9:67d737d8a349 | 376 | */ |
evedelegue | 9:67d737d8a349 | 377 | MX12::Status_packet _status_pck; |
evedelegue | 9:67d737d8a349 | 378 | |
evedelegue | 9:67d737d8a349 | 379 | /** Structure update by ISR (Interrupt Service Routine) ReadCallback() |
evedelegue | 9:67d737d8a349 | 380 | * parser to model its current state |
evedelegue | 9:67d737d8a349 | 381 | */ |
evedelegue | 9:67d737d8a349 | 382 | MX12::ParserState _parser_state; |
evedelegue | 9:67d737d8a349 | 383 | |
evedelegue | 9:67d737d8a349 | 384 | |
evedelegue | 9:67d737d8a349 | 385 | unsigned char _answer; |
evedelegue | 9:67d737d8a349 | 386 | |
evedelegue | 9:67d737d8a349 | 387 | /** |
evedelegue | 9:67d737d8a349 | 388 | * @brief |
evedelegue | 9:67d737d8a349 | 389 | * Interupt service routine (ISR) to read and parse received message |
evedelegue | 9:67d737d8a349 | 390 | * |
evedelegue | 9:67d737d8a349 | 391 | * @detail |
evedelegue | 9:67d737d8a349 | 392 | * This interupt routine is attached to reception event on servomoteur |
evedelegue | 9:67d737d8a349 | 393 | * bus and is called for each character received on bus. |
evedelegue | 9:67d737d8a349 | 394 | * |
evedelegue | 9:67d737d8a349 | 395 | * As the characters are received, the progress of the parser |
evedelegue | 9:67d737d8a349 | 396 | * is stored in _parser_state and the result of the analysis |
evedelegue | 9:67d737d8a349 | 397 | * is stored in _status_pck. |
evedelegue | 9:67d737d8a349 | 398 | */ |
evedelegue | 9:67d737d8a349 | 399 | void _Rx_interrupt(); |
evedelegue | 9:67d737d8a349 | 400 | |
evedelegue | 9:67d737d8a349 | 401 | }; |
evedelegue | 9:67d737d8a349 | 402 | |
evedelegue | 9:67d737d8a349 | 403 | #endif /* MBED_MX12_H_ */ |