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: servomotor_MX12_Lorenzo
MX12.h@11:9bc7f5e2ccee, 2021-11-06 (annotated)
- Committer:
- denis2nis
- Date:
- Sat Nov 06 17:24:30 2021 +0000
- Revision:
- 11:9bc7f5e2ccee
- Parent:
- 10:ca9afe156ee1
- Child:
- 12:acfd6c46954b
Arrange and comment (cont.)
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| denis2nis | 1:a9ba9cf928fe | 1 | /** | 
| denis2nis | 9:b4a5187fdec6 | 2 | * @file MX12.h | 
| denis2nis | 8:e74ef93ae660 | 3 | * @brief this header file will contain all required definitions and | 
| denis2nis | 8:e74ef93ae660 | 4 | * basic utilities functions to manage au bus of servomotor | 
| denis2nis | 8:e74ef93ae660 | 5 | * Dynaminel MX12 | 
| denis2nis | 8:e74ef93ae660 | 6 | * | 
| denis2nis | 8:e74ef93ae660 | 7 | */ | 
| denis2nis | 8:e74ef93ae660 | 8 | #ifndef MBED_MX12_H_ | 
| denis2nis | 8:e74ef93ae660 | 9 | #define MBED_MX12_H_ | 
| denis2nis | 0:7556356a8bcd | 10 | |
| denis2nis | 0:7556356a8bcd | 11 | #include "mbed.h" | 
| denis2nis | 0:7556356a8bcd | 12 | |
| denis2nis | 5:0cf54586a4be | 13 | #define MX12_DATA_MAX_SIZE 256 | 
| denis2nis | 5:0cf54586a4be | 14 | #define MX12_MAX_MOTOR_COUNT 16 | 
| denis2nis | 5:0cf54586a4be | 15 | |
| denis2nis | 2:02f3323a107d | 16 | /* Dynamixel protocol v1.0 : Instructions | 
| denis2nis | 2:02f3323a107d | 17 | ******************************************/ | 
| denis2nis | 2:02f3323a107d | 18 | #define PROTOCOL_INSTRUCTION_PING 0x01 | 
| denis2nis | 2:02f3323a107d | 19 | #define PROTOCOL_INSTRUCTION_READ 0x02 | 
| denis2nis | 2:02f3323a107d | 20 | #define PROTOCOL_INSTRUCTION_WRITE 0x03 | 
| denis2nis | 2:02f3323a107d | 21 | #define PROTOCOL_INSTRUCTION_REG_WRITE 0x04 | 
| denis2nis | 2:02f3323a107d | 22 | #define PROTOCOL_INSTRUCTION_ACTION 0x05 | 
| denis2nis | 2:02f3323a107d | 23 | #define PROTOCOL_INSTRUCTION_FACTORY_RESET 0x06 | 
| denis2nis | 2:02f3323a107d | 24 | #define PROTOCOL_INSTRUCTION_REBOOT 0x08 | 
| denis2nis | 2:02f3323a107d | 25 | #define PROTOCOL_INSTRUCTION_SYNC_WRITE 0x83 | 
| denis2nis | 2:02f3323a107d | 26 | #define PROTOCOL_INSTRUCTION_BULK_READ 0x92 | 
| denis2nis | 2:02f3323a107d | 27 | |
| denis2nis | 5:0cf54586a4be | 28 | /* Dynamixel protocol v1.0 : Contro table content | 
| denis2nis | 5:0cf54586a4be | 29 | ************************************************/ | 
| denis2nis | 5:0cf54586a4be | 30 | #define CONTROL_TABLE_MODEL_NUMBER 0 | 
| denis2nis | 5:0cf54586a4be | 31 | #define CONTROL_TABLE_FIRMWARE_VERSION 2 | 
| denis2nis | 5:0cf54586a4be | 32 | #define CONTROL_TABLE_ID 3 | 
| denis2nis | 5:0cf54586a4be | 33 | #define CONTROL_TABLE_BAUD_RATE 4 | 
| denis2nis | 5:0cf54586a4be | 34 | #define CONTROL_TABLE_RETURN_DELAY_TIME 5 | 
| denis2nis | 5:0cf54586a4be | 35 | #define CONTROL_TABLE_CW_ANGLE_LIMIT 6 | 
| denis2nis | 5:0cf54586a4be | 36 | #define CONTROL_TABLE_CCW_ANGLE_LIMIT 8 | 
| denis2nis | 5:0cf54586a4be | 37 | #define CONTROL_TABLE_TEMPERATURE_LIMIT 11 | 
| denis2nis | 5:0cf54586a4be | 38 | #define CONTROL_TABLE_MIN_VOLTAGE_LIMIT 12 | 
| denis2nis | 5:0cf54586a4be | 39 | #define CONTROL_TABLE_MAX_VOLTAGE_LIMIT 13 | 
| denis2nis | 5:0cf54586a4be | 40 | #define CONTROL_TABLE_MAX_TORQUE 14 | 
| denis2nis | 5:0cf54586a4be | 41 | #define CONTROL_TABLE_STATUS_RETURN_LEVEL 16 | 
| denis2nis | 5:0cf54586a4be | 42 | #define CONTROL_TABLE_ALARM_LED 17 | 
| denis2nis | 5:0cf54586a4be | 43 | #define CONTROL_TABLE_SHUTDOWN 18 | 
| denis2nis | 5:0cf54586a4be | 44 | #define CONTROL_TABLE_MULTITURN_OFFSET 20 | 
| denis2nis | 5:0cf54586a4be | 45 | #define CONTROL_TABLE_RESOLUTION_DIVIDER 22 | 
| denis2nis | 5:0cf54586a4be | 46 | #define CONTROL_TABLE_TORQUE_ENABLE 24 | 
| denis2nis | 5:0cf54586a4be | 47 | #define CONTROL_TABLE_LED 25 | 
| denis2nis | 5:0cf54586a4be | 48 | #define CONTROL_TABLE_P_GAIN 26 | 
| denis2nis | 5:0cf54586a4be | 49 | #define CONTROL_TABLE_I_GAIN 27 | 
| denis2nis | 5:0cf54586a4be | 50 | #define CONTROL_TABLE_D_GAIN 28 | 
| denis2nis | 5:0cf54586a4be | 51 | #define CONTROL_TABLE_GOAL_POSITION 30 | 
| denis2nis | 5:0cf54586a4be | 52 | #define CONTROL_TABLE_MOVING_SPEED 32 | 
| denis2nis | 5:0cf54586a4be | 53 | #define CONTROL_TABLE_TORQUE_LIMIT 34 | 
| denis2nis | 5:0cf54586a4be | 54 | #define CONTROL_TABLE_PRESENT_POSITION 36 | 
| denis2nis | 5:0cf54586a4be | 55 | #define CONTROL_TABLE_PRESENT_SPEED 38 | 
| denis2nis | 5:0cf54586a4be | 56 | #define CONTROL_TABLE_PRESENT_LOAD 40 | 
| denis2nis | 5:0cf54586a4be | 57 | #define CONTROL_TABLE_PRESENT_VOLTAGE 42 | 
| denis2nis | 5:0cf54586a4be | 58 | #define CONTROL_TABLE_PRESENT_TEMPERATURE 43 | 
| denis2nis | 5:0cf54586a4be | 59 | #define CONTROL_TABLE_REGISTRED_INSTRUCTION 44 | 
| denis2nis | 5:0cf54586a4be | 60 | #define CONTROL_TABLE_MOVING 46 | 
| denis2nis | 5:0cf54586a4be | 61 | #define CONTROL_TABLE_LOCK 47 | 
| denis2nis | 5:0cf54586a4be | 62 | #define CONTROL_TABLE_PUNCH 48 | 
| denis2nis | 5:0cf54586a4be | 63 | #define CONTROL_TABLE_GOAL_ACCELERATION 73 | 
| denis2nis | 2:02f3323a107d | 64 | |
| denis2nis | 2:02f3323a107d | 65 | /** | 
| denis2nis | 8:e74ef93ae660 | 66 | * @brief Class to communicate with Dynamixel MX12 servomotors | 
| denis2nis | 1:a9ba9cf928fe | 67 | * | 
| denis2nis | 2:02f3323a107d | 68 | * @details | 
| denis2nis | 8:e74ef93ae660 | 69 | * | 
| denis2nis | 2:02f3323a107d | 70 | * The servomotors are daisy chained to a serial link of the target | 
| denis2nis | 2:02f3323a107d | 71 | * microcontroller. The class ensures the initialization of serial link | 
| denis2nis | 8:e74ef93ae660 | 72 | * and the management of communications mainly to control rotational | 
| denis2nis | 8:e74ef93ae660 | 73 | * speed of servomotors. | 
| denis2nis | 8:e74ef93ae660 | 74 | * | 
| denis2nis | 2:02f3323a107d | 75 | * Transmission of messages to the servomotors is blocking while | 
| denis2nis | 2:02f3323a107d | 76 | * reception is non-blocking thanks to the use of an interrupt routine. | 
| denis2nis | 5:0cf54586a4be | 77 | * | 
| denis2nis | 5:0cf54586a4be | 78 | * @author Titouan Soulard (creator and maintainer until April 2021) | 
| denis2nis | 5:0cf54586a4be | 79 | * @author Bruno Denis (Doxygen documentation and code rearrangement) | 
| denis2nis | 1:a9ba9cf928fe | 80 | * | 
| denis2nis | 5:0cf54586a4be | 81 | * @see Control table of Dynamixel MX12 servomotor | 
| denis2nis | 5:0cf54586a4be | 82 | * @see https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/ | 
| denis2nis | 5:0cf54586a4be | 83 | * @see Dynamixel protocol v1.0 manual | 
| denis2nis | 5:0cf54586a4be | 84 | * @see https://emanual.robotis.com/docs/en/dxl/protocol1/ | 
| denis2nis | 11:9bc7f5e2ccee | 85 | |
| denis2nis | 11:9bc7f5e2ccee | 86 | @code | 
| denis2nis | 11:9bc7f5e2ccee | 87 | |
| denis2nis | 11:9bc7f5e2ccee | 88 | #include "mbed.h" | 
| denis2nis | 11:9bc7f5e2ccee | 89 | #include "MX12.h" | 
| denis2nis | 11:9bc7f5e2ccee | 90 | |
| denis2nis | 11:9bc7f5e2ccee | 91 | #define SERVO_TX_PIN PC_4 | 
| denis2nis | 11:9bc7f5e2ccee | 92 | #define SERVO_RX_PIN PC_5 | 
| denis2nis | 11:9bc7f5e2ccee | 93 | #define SERVO_BAUD 115200 | 
| denis2nis | 11:9bc7f5e2ccee | 94 | #define SERVO_ID 1 | 
| denis2nis | 11:9bc7f5e2ccee | 95 | |
| denis2nis | 11:9bc7f5e2ccee | 96 | #define DELAY_1000ms 1000 | 
| denis2nis | 11:9bc7f5e2ccee | 97 | #define DELAY_1ms 1 | 
| denis2nis | 11:9bc7f5e2ccee | 98 | |
| denis2nis | 11:9bc7f5e2ccee | 99 | MX12 servo_bus(SERVO_TX_PIN, SERVO_RX_PIN, SERVO_BAUD); | 
| denis2nis | 11:9bc7f5e2ccee | 100 | float relative_speed; | 
| denis2nis | 11:9bc7f5e2ccee | 101 | |
| denis2nis | 11:9bc7f5e2ccee | 102 | int main() | 
| denis2nis | 11:9bc7f5e2ccee | 103 | { | 
| denis2nis | 11:9bc7f5e2ccee | 104 | // Set speed of SERVO_ID servomotor to 10% | 
| denis2nis | 11:9bc7f5e2ccee | 105 | // Send on servo_bus to SERVO_ID motor the instruction "moving speed" | 
| denis2nis | 11:9bc7f5e2ccee | 106 | // with parameter 0.1 (10% of maximum speed) | 
| denis2nis | 11:9bc7f5e2ccee | 107 | relative_speed = 0.1; | 
| denis2nis | 11:9bc7f5e2ccee | 108 | servo_bus.SetSpeed(SERVO_ID, relative_speed); | 
| denis2nis | 11:9bc7f5e2ccee | 109 | |
| denis2nis | 11:9bc7f5e2ccee | 110 | // wait for one second | 
| denis2nis | 11:9bc7f5e2ccee | 111 | thread_sleep_for(DELAY_1000ms); | 
| denis2nis | 11:9bc7f5e2ccee | 112 | |
| denis2nis | 11:9bc7f5e2ccee | 113 | // set speed of SERVO_ID servomotor to 0% | 
| denis2nis | 11:9bc7f5e2ccee | 114 | relative_speed = 0.0; | 
| denis2nis | 11:9bc7f5e2ccee | 115 | servo_bus.SetSpeed(SERVO_ID, relative_speed); | 
| denis2nis | 11:9bc7f5e2ccee | 116 | |
| denis2nis | 11:9bc7f5e2ccee | 117 | // infinite loop | 
| denis2nis | 11:9bc7f5e2ccee | 118 | while (true) thread_sleep_for(DELAY_1000ms); | 
| denis2nis | 11:9bc7f5e2ccee | 119 | } | 
| denis2nis | 11:9bc7f5e2ccee | 120 | |
| denis2nis | 11:9bc7f5e2ccee | 121 | @endcode | 
| denis2nis | 11:9bc7f5e2ccee | 122 | |
| denis2nis | 5:0cf54586a4be | 123 | * | 
| denis2nis | 8:e74ef93ae660 | 124 | * @warning | 
| denis2nis | 8:e74ef93ae660 | 125 | * | 
| denis2nis | 11:9bc7f5e2ccee | 126 | * Error field of status packet if decoded by GetStatus() | 
| denis2nis | 10:ca9afe156ee1 | 127 | * Doxygen Release 1.7.2 returns an enumation type "Status". As several | 
| denis2nis | 10:ca9afe156ee1 | 128 | * errors can be reported simultaneously the type enum is not suitable | 
| denis2nis | 10:ca9afe156ee1 | 129 | * (B. Denis 11/2021). | 
| denis2nis | 10:ca9afe156ee1 | 130 | * | 
| denis2nis | 11:9bc7f5e2ccee | 131 | * @bug | 
| denis2nis | 8:e74ef93ae660 | 132 | * | 
| denis2nis | 11:9bc7f5e2ccee | 133 | * Bug: _frame_pointer variable is used by private _ReadCallback() ISR | 
| denis2nis | 10:ca9afe156ee1 | 134 | * to store the current size for message (status packet) received from | 
| denis2nis | 10:ca9afe156ee1 | 135 | * servomotor. This variable is NOT initialised and NEVER reset to zero | 
| denis2nis | 10:ca9afe156ee1 | 136 | * at each new message. | 
| denis2nis | 9:b4a5187fdec6 | 137 | * | 
| denis2nis | 10:ca9afe156ee1 | 138 | * Bug: GetStatus() method has a hazardous behavior because it provides | 
| denis2nis | 10:ca9afe156ee1 | 139 | * a result by reading the content of the variable _current_frame | 
| denis2nis | 11:9bc7f5e2ccee | 140 | * which can be modified at any time by the private ISR _ReadCallback(). | 
| denis2nis | 8:e74ef93ae660 | 141 | * | 
| denis2nis | 1:a9ba9cf928fe | 142 | */ | 
| denis2nis | 0:7556356a8bcd | 143 | class MX12 | 
| denis2nis | 0:7556356a8bcd | 144 | { | 
| denis2nis | 0:7556356a8bcd | 145 | public: | 
| denis2nis | 0:7556356a8bcd | 146 | |
| denis2nis | 8:e74ef93ae660 | 147 | /** Error status occurred during the operation of servomotor. | 
| denis2nis | 8:e74ef93ae660 | 148 | * | 
| denis2nis | 8:e74ef93ae660 | 149 | * @warning | 
| denis2nis | 8:e74ef93ae660 | 150 | * Enumaration type is not suitable for all error status because | 
| denis2nis | 8:e74ef93ae660 | 151 | * it can denote only one error at a time (B. Denis 11/2021) | 
| denis2nis | 8:e74ef93ae660 | 152 | */ | 
| denis2nis | 8:e74ef93ae660 | 153 | enum Status { | 
| denis2nis | 8:e74ef93ae660 | 154 | InstructionError, /**< In case of sending an undefined instruction | 
| denis2nis | 8:e74ef93ae660 | 155 | or delivering the action instruction | 
| denis2nis | 8:e74ef93ae660 | 156 | without the Reg Write instruction */ | 
| denis2nis | 8:e74ef93ae660 | 157 | OverloadError, /**< When the current load cannot be controlled | 
| denis2nis | 8:e74ef93ae660 | 158 | by the set Torque */ | 
| denis2nis | 8:e74ef93ae660 | 159 | ChecksumError, /**< When the Checksum of the transmitted | 
| denis2nis | 8:e74ef93ae660 | 160 | Instruction Packet is incorrect */ | 
| denis2nis | 8:e74ef93ae660 | 161 | RangeError, /**< When an instruction is out of the range | 
| denis2nis | 8:e74ef93ae660 | 162 | for use */ | 
| denis2nis | 8:e74ef93ae660 | 163 | OverheatingError, /**< When internal temperature of servomotor | 
| denis2nis | 8:e74ef93ae660 | 164 | is out of the range of operating | 
| denis2nis | 8:e74ef93ae660 | 165 | temperature set in the Control table */ | 
| denis2nis | 8:e74ef93ae660 | 166 | AngleLimitError, /**< When Goal Position is written out of the | 
| denis2nis | 8:e74ef93ae660 | 167 | range from CW Angle Limit to CCW Angle | 
| denis2nis | 8:e74ef93ae660 | 168 | Limit */ | 
| denis2nis | 8:e74ef93ae660 | 169 | InputVoltageError, /**< When the applied voltage is out of the | 
| denis2nis | 8:e74ef93ae660 | 170 | range of operating voltage set in the | 
| denis2nis | 8:e74ef93ae660 | 171 | Control table */ | 
| denis2nis | 8:e74ef93ae660 | 172 | Unknown, /**< Combination of several errors (Caution: | 
| denis2nis | 8:e74ef93ae660 | 173 | limit of enum approach to code errors) */ | 
| denis2nis | 8:e74ef93ae660 | 174 | Ok ///< no error | 
| denis2nis | 8:e74ef93ae660 | 175 | }; | 
| denis2nis | 8:e74ef93ae660 | 176 | |
| denis2nis | 8:e74ef93ae660 | 177 | /** Enumeration of states of the acces methode of the master-slave | 
| denis2nis | 8:e74ef93ae660 | 178 | * protocol of the communication between the robot controller (master) | 
| denis2nis | 8:e74ef93ae660 | 179 | * and the servomotors (slaves). | 
| denis2nis | 8:e74ef93ae660 | 180 | */ | 
| denis2nis | 8:e74ef93ae660 | 181 | enum SerialState { | 
| denis2nis | 8:e74ef93ae660 | 182 | Writing, /**< Robot controller send an "instruction packet" | 
| denis2nis | 8:e74ef93ae660 | 183 | (request) to a servomotor */ | 
| denis2nis | 8:e74ef93ae660 | 184 | Reading, /**< Robot controller receive a "status packet" from a | 
| denis2nis | 8:e74ef93ae660 | 185 | requested servomotor */ | 
| denis2nis | 8:e74ef93ae660 | 186 | Idle ///< Robot controller ready for a new cycle request-answer | 
| denis2nis | 8:e74ef93ae660 | 187 | }; | 
| denis2nis | 8:e74ef93ae660 | 188 | |
| denis2nis | 8:e74ef93ae660 | 189 | /** Structure of store status packet (also known as return packet) | 
| denis2nis | 8:e74ef93ae660 | 190 | * according tne Dynamixel protocol v1.0, which are messages sent | 
| denis2nis | 8:e74ef93ae660 | 191 | * by servomotors to contriller in response of an instruction packet | 
| denis2nis | 8:e74ef93ae660 | 192 | */ | 
| denis2nis | 8:e74ef93ae660 | 193 | struct Frame { | 
| denis2nis | 8:e74ef93ae660 | 194 | unsigned char motorId; /**< Identifier of the servomotor involved | 
| denis2nis | 8:e74ef93ae660 | 195 | in this exchange */ | 
| denis2nis | 8:e74ef93ae660 | 196 | unsigned char length; /**< */ | 
| denis2nis | 8:e74ef93ae660 | 197 | unsigned char data[MX12_DATA_MAX_SIZE]; /**< */ | 
| denis2nis | 11:9bc7f5e2ccee | 198 | unsigned char valid; /**< */ | 
| denis2nis | 8:e74ef93ae660 | 199 | }; | 
| denis2nis | 8:e74ef93ae660 | 200 | |
| denis2nis | 9:b4a5187fdec6 | 201 | /** State of packet parser store which section of a status packet | 
| denis2nis | 9:b4a5187fdec6 | 202 | * (according the Dynamixel according the Dynamixel) is currently reading | 
| denis2nis | 9:b4a5187fdec6 | 203 | * from a servomotor return message. | 
| denis2nis | 9:b4a5187fdec6 | 204 | */ | 
| denis2nis | 9:b4a5187fdec6 | 205 | enum ParsingState { | 
| denis2nis | 9:b4a5187fdec6 | 206 | Header, ///< reading the two heading bytes | 
| denis2nis | 9:b4a5187fdec6 | 207 | Id, ///< reading the servomotor ID byte | 
| denis2nis | 9:b4a5187fdec6 | 208 | Length, ///< reading byte length of the instruction | 
| denis2nis | 9:b4a5187fdec6 | 209 | Data, ///< reading parameters | 
| denis2nis | 9:b4a5187fdec6 | 210 | Checksum ///< reading one bytes checksum | 
| denis2nis | 9:b4a5187fdec6 | 211 | }; | 
| denis2nis | 9:b4a5187fdec6 | 212 | |
| denis2nis | 9:b4a5187fdec6 | 213 | /** Complement to the ParsingState enumeration to store the reading | 
| denis2nis | 9:b4a5187fdec6 | 214 | * progress of each section of the status packet. | 
| denis2nis | 8:e74ef93ae660 | 215 | */ | 
| denis2nis | 8:e74ef93ae660 | 216 | struct StateContext { | 
| denis2nis | 8:e74ef93ae660 | 217 | unsigned char headingCount; | 
| denis2nis | 8:e74ef93ae660 | 218 | unsigned char dataCount; | 
| denis2nis | 8:e74ef93ae660 | 219 | unsigned char checksum; | 
| denis2nis | 8:e74ef93ae660 | 220 | }; | 
| denis2nis | 5:0cf54586a4be | 221 | |
| denis2nis | 8:e74ef93ae660 | 222 | /** Create MX12 instance | 
| denis2nis | 8:e74ef93ae660 | 223 | * | 
| denis2nis | 8:e74ef93ae660 | 224 | * @param tx board pin used for transmission in UART daisy chain link | 
| denis2nis | 8:e74ef93ae660 | 225 | * to servomotors | 
| denis2nis | 8:e74ef93ae660 | 226 | * @param rx board pin used for reception in UART daisy chain link | 
| denis2nis | 8:e74ef93ae660 | 227 | * to servomotors | 
| denis2nis | 8:e74ef93ae660 | 228 | * @param baud modulation rate of UART signal, unit: Baud | 
| denis2nis | 8:e74ef93ae660 | 229 | * to servomotors | 
| denis2nis | 8:e74ef93ae660 | 230 | */ | 
| denis2nis | 8:e74ef93ae660 | 231 | MX12(PinName tx, PinName rx, int baud=115200); | 
| denis2nis | 8:e74ef93ae660 | 232 | |
| denis2nis | 8:e74ef93ae660 | 233 | /** Send desired speed to a specific servomotor | 
| denis2nis | 8:e74ef93ae660 | 234 | * | 
| denis2nis | 8:e74ef93ae660 | 235 | * @param mot_id a unique value in the daisy chain network to identify | 
| denis2nis | 8:e74ef93ae660 | 236 | * each servomotor | 
| denis2nis | 8:e74ef93ae660 | 237 | * @param speed a float between -1 and 1 that represents the percentage | 
| denis2nis | 8:e74ef93ae660 | 238 | * of maximum requested speed | 
| denis2nis | 8:e74ef93ae660 | 239 | */ | 
| denis2nis | 8:e74ef93ae660 | 240 | void SetSpeed(unsigned char mot_id, float speed); | 
| denis2nis | 8:e74ef93ae660 | 241 | |
| denis2nis | 10:ca9afe156ee1 | 242 | /** Informs about the availability of the bus for a new transmission | 
| denis2nis | 10:ca9afe156ee1 | 243 | * of instruction packet (Method Access Control) | 
| denis2nis | 10:ca9afe156ee1 | 244 | * | 
| denis2nis | 10:ca9afe156ee1 | 245 | * @returns true if bus ready for a new transmission, otherwise false | 
| denis2nis | 9:b4a5187fdec6 | 246 | */ | 
| denis2nis | 8:e74ef93ae660 | 247 | char IsAvailable(void); | 
| denis2nis | 8:e74ef93ae660 | 248 | |
| denis2nis | 8:e74ef93ae660 | 249 | /** | 
| denis2nis | 8:e74ef93ae660 | 250 | * Build and send an instruction packet to a servomotor according | 
| denis2nis | 8:e74ef93ae660 | 251 | * DYNAMIXEL Protocol 1.0 (online protocol documentation | 
| denis2nis | 8:e74ef93ae660 | 252 | * https://emanual.robotis.com/docs/en/dxl/protocol1/) | 
| denis2nis | 8:e74ef93ae660 | 253 | * | 
| denis2nis | 8:e74ef93ae660 | 254 | * @param[in] mot_id indicates the ID of the device (servomotor) that | 
| denis2nis | 8:e74ef93ae660 | 255 | * should receive the Instruction Packet and process it | 
| denis2nis | 8:e74ef93ae660 | 256 | * @param[in] address data address in the "Control Table of RAM Area" | 
| denis2nis | 8:e74ef93ae660 | 257 | * of a servomotor MX12 | 
| denis2nis | 8:e74ef93ae660 | 258 | * (https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/#control-table-of-ram-area). | 
| denis2nis | 8:e74ef93ae660 | 259 | * @param[in] len if it is a write instruction, size in bytes | 
| denis2nis | 8:e74ef93ae660 | 260 | * of the data to write in the "Control Table of RAM Area" | 
| denis2nis | 8:e74ef93ae660 | 261 | * @param[in] data array of char containing parameter of Danamixel | 
| denis2nis | 8:e74ef93ae660 | 262 | * protocol that are the instruction’s auxiliary data field | 
| denis2nis | 8:e74ef93ae660 | 263 | * | 
| denis2nis | 8:e74ef93ae660 | 264 | * @see https://emanual.robotis.com/docs/en/dxl/protocol1/ | 
| denis2nis | 8:e74ef93ae660 | 265 | * | 
| denis2nis | 8:e74ef93ae660 | 266 | * Packet sent | 
| denis2nis | 8:e74ef93ae660 | 267 | * <PRE> | 
| denis2nis | 8:e74ef93ae660 | 268 | * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum| | 
| denis2nis | 8:e74ef93ae660 | 269 | * |-------|-------|---------|------|-----------|---------------|--------| | 
| denis2nis | 8:e74ef93ae660 | 270 | * | 0xFF | 0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM | | 
| denis2nis | 8:e74ef93ae660 | 271 | * | cmd[0]| cmd[1]| cmd[2] |cmd[3]| cmd[4] |cmd[5]... | | | 
| denis2nis | 8:e74ef93ae660 | 272 | * \\__ ___/ \\_ _/ \\__ __/ | 
| denis2nis | 8:e74ef93ae660 | 273 | * \/ \/ \/ | 
| denis2nis | 8:e74ef93ae660 | 274 | * mot_id address data | 
| denis2nis | 8:e74ef93ae660 | 275 | * (len = N-1) | 
| denis2nis | 8:e74ef93ae660 | 276 | * </PRE> | 
| denis2nis | 11:9bc7f5e2ccee | 277 | * | 
| denis2nis | 11:9bc7f5e2ccee | 278 | * Code simple | 
| denis2nis | 11:9bc7f5e2ccee | 279 | * | 
| denis2nis | 11:9bc7f5e2ccee | 280 | @code | 
| denis2nis | 11:9bc7f5e2ccee | 281 | * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum| | 
| denis2nis | 11:9bc7f5e2ccee | 282 | * |-------|-------|---------|------|-----------|---------------|--------| | 
| denis2nis | 11:9bc7f5e2ccee | 283 | * | 0xFF | 0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM | | 
| denis2nis | 11:9bc7f5e2ccee | 284 | * | cmd[0]| cmd[1]| cmd[2] |cmd[3]| cmd[4] |cmd[5]... | | | 
| denis2nis | 11:9bc7f5e2ccee | 285 | * \__ ___/ \_ _/ \__ __/ | 
| denis2nis | 11:9bc7f5e2ccee | 286 | * \/ \/ \/ | 
| denis2nis | 11:9bc7f5e2ccee | 287 | * mot_id address data | 
| denis2nis | 11:9bc7f5e2ccee | 288 | * (len = N-1) | 
| denis2nis | 11:9bc7f5e2ccee | 289 | @endcode | 
| denis2nis | 11:9bc7f5e2ccee | 290 | * | 
| denis2nis | 11:9bc7f5e2ccee | 291 | * Code simple {.unparsed} | 
| denis2nis | 11:9bc7f5e2ccee | 292 | * | 
| denis2nis | 11:9bc7f5e2ccee | 293 | @code{.unparsed} | 
| denis2nis | 11:9bc7f5e2ccee | 294 | * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum| | 
| denis2nis | 11:9bc7f5e2ccee | 295 | * |-------|-------|---------|------|-----------|---------------|--------| | 
| denis2nis | 11:9bc7f5e2ccee | 296 | * | 0xFF | 0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM | | 
| denis2nis | 11:9bc7f5e2ccee | 297 | * | cmd[0]| cmd[1]| cmd[2] |cmd[3]| cmd[4] |cmd[5]... | | | 
| denis2nis | 11:9bc7f5e2ccee | 298 | * \__ ___/ \_ _/ \__ __/ | 
| denis2nis | 11:9bc7f5e2ccee | 299 | * \/ \/ \/ | 
| denis2nis | 11:9bc7f5e2ccee | 300 | * mot_id address data | 
| denis2nis | 11:9bc7f5e2ccee | 301 | * (len = N-1) | 
| denis2nis | 11:9bc7f5e2ccee | 302 | @endcode | 
| denis2nis | 8:e74ef93ae660 | 303 | */ | 
| denis2nis | 8:e74ef93ae660 | 304 | void rw(unsigned char mot_id, char address, char len, char *data); | 
| denis2nis | 8:e74ef93ae660 | 305 | |
| denis2nis | 8:e74ef93ae660 | 306 | /** | 
| denis2nis | 8:e74ef93ae660 | 307 | * | 
| denis2nis | 8:e74ef93ae660 | 308 | * @warning | 
| denis2nis | 8:e74ef93ae660 | 309 | * | 
| denis2nis | 8:e74ef93ae660 | 310 | */ | 
| denis2nis | 8:e74ef93ae660 | 311 | void PrintSerial(); | 
| denis2nis | 8:e74ef93ae660 | 312 | |
| denis2nis | 8:e74ef93ae660 | 313 | /** | 
| denis2nis | 8:e74ef93ae660 | 314 | * Get information from de Error byte of the last status packet | 
| denis2nis | 8:e74ef93ae660 | 315 | * received from a servomotor | 
| denis2nis | 8:e74ef93ae660 | 316 | * | 
| denis2nis | 8:e74ef93ae660 | 317 | * @return | 
| denis2nis | 8:e74ef93ae660 | 318 | * One of enum MX12::Status value to describe errors. 'Ok' is | 
| denis2nis | 8:e74ef93ae660 | 319 | * returns if no error occurred during the last operation of | 
| denis2nis | 8:e74ef93ae660 | 320 | * servomotor. | 
| denis2nis | 8:e74ef93ae660 | 321 | * | 
| denis2nis | 8:e74ef93ae660 | 322 | * @warning | 
| denis2nis | 10:ca9afe156ee1 | 323 | * | 
| denis2nis | 10:ca9afe156ee1 | 324 | * Warning: if a combination of several errors is reported the function | 
| denis2nis | 10:ca9afe156ee1 | 325 | * returns 'Unknown' (B. Denis 11/2021). | 
| denis2nis | 9:b4a5187fdec6 | 326 | * | 
| denis2nis | 9:b4a5187fdec6 | 327 | * @bug | 
| denis2nis | 10:ca9afe156ee1 | 328 | * | 
| denis2nis | 10:ca9afe156ee1 | 329 | * Bug: this method has a hazardous behavior because it provides | 
| denis2nis | 10:ca9afe156ee1 | 330 | * a result by reading the content of the variable _current_frame | 
| denis2nis | 10:ca9afe156ee1 | 331 | * which can be modified at any time by the private ISR _ReadCallback() | 
| denis2nis | 8:e74ef93ae660 | 332 | */ | 
| denis2nis | 8:e74ef93ae660 | 333 | MX12::Status GetStatus(void); | 
| denis2nis | 5:0cf54586a4be | 334 | |
| denis2nis | 8:e74ef93ae660 | 335 | /* function aivailaible in a previous version of the class | 
| denis2nis | 8:e74ef93ae660 | 336 | */ | 
| denis2nis | 8:e74ef93ae660 | 337 | // MX12::Status GetStatus(void); | 
| denis2nis | 8:e74ef93ae660 | 338 | // void ReadPosition(unsigned char mot_id); | 
| denis2nis | 8:e74ef93ae660 | 339 | // float GetPosition(unsigned char mot_id); | 
| denis2nis | 8:e74ef93ae660 | 340 | |
| denis2nis | 10:ca9afe156ee1 | 341 | protected: | 
| denis2nis | 5:0cf54586a4be | 342 | |
| denis2nis | 9:b4a5187fdec6 | 343 | /* | 
| denis2nis | 9:b4a5187fdec6 | 344 | */ | 
| denis2nis | 8:e74ef93ae660 | 345 | UnbufferedSerial _mx12; | 
| denis2nis | 8:e74ef93ae660 | 346 | MX12::ParsingState _pstate; | 
| denis2nis | 8:e74ef93ae660 | 347 | MX12::SerialState _sstate; | 
| denis2nis | 8:e74ef93ae660 | 348 | |
| denis2nis | 8:e74ef93ae660 | 349 | /** Structure used only by ISR (Interrupt Service Routine) ReadCallback() | 
| denis2nis | 8:e74ef93ae660 | 350 | */ | 
| denis2nis | 8:e74ef93ae660 | 351 | MX12::StateContext _scontext; | 
| denis2nis | 8:e74ef93ae660 | 352 | MX12::Frame _current_frame; | 
| denis2nis | 8:e74ef93ae660 | 353 | |
| denis2nis | 8:e74ef93ae660 | 354 | unsigned char _answer; | 
| denis2nis | 8:e74ef93ae660 | 355 | |
| denis2nis | 8:e74ef93ae660 | 356 | /** Character array to store status message received from servomotors. | 
| denis2nis | 8:e74ef93ae660 | 357 | * _ReadCallback() ISR fill this array character by character and | 
| denis2nis | 8:e74ef93ae660 | 358 | * update the size of the message currently received in the variable | 
| denis2nis | 8:e74ef93ae660 | 359 | * _frame_pointer. | 
| denis2nis | 8:e74ef93ae660 | 360 | */ | 
| denis2nis | 8:e74ef93ae660 | 361 | unsigned char _stored_frame[MX12_DATA_MAX_SIZE]; | 
| denis2nis | 8:e74ef93ae660 | 362 | |
| denis2nis | 8:e74ef93ae660 | 363 | /** Size of the message currently received from servomotor. This variable | 
| denis2nis | 8:e74ef93ae660 | 364 | * is update at each call of _ReadCallback() ISR. The content of the | 
| denis2nis | 8:e74ef93ae660 | 365 | * message is store into _stored_frame array. | 
| denis2nis | 8:e74ef93ae660 | 366 | * | 
| denis2nis | 8:e74ef93ae660 | 367 | * @warning | 
| denis2nis | 8:e74ef93ae660 | 368 | */ | 
| denis2nis | 8:e74ef93ae660 | 369 | unsigned char _frame_pointer; | 
| denis2nis | 9:b4a5187fdec6 | 370 | |
| denis2nis | 8:e74ef93ae660 | 371 | /** Interupt service routine (ISR) to read and parse the response message | 
| denis2nis | 8:e74ef93ae660 | 372 | * comming from servomotor on UART (serial port). This routine is called | 
| denis2nis | 8:e74ef93ae660 | 373 | * when each character is received on the servomotor bus. | 
| denis2nis | 8:e74ef93ae660 | 374 | * | 
| denis2nis | 8:e74ef93ae660 | 375 | * As the characters are received, the progress of the parser | 
| denis2nis | 8:e74ef93ae660 | 376 | * is stored in the two state variables _pstate and _scontext, | 
| denis2nis | 8:e74ef93ae660 | 377 | * and the result of the analysis is stored in _current_frame. | 
| denis2nis | 8:e74ef93ae660 | 378 | */ | 
| denis2nis | 8:e74ef93ae660 | 379 | void _ReadCallback(); | 
| denis2nis | 8:e74ef93ae660 | 380 | |
| denis2nis | 0:7556356a8bcd | 381 | }; | 
| denis2nis | 0:7556356a8bcd | 382 | |
| denis2nis | 8:e74ef93ae660 | 383 | #endif /* MBED_MX12_H_ */ |