PSL_2021 / servomotor_MX12_Lorenzo

Dependents:   PSL_ROBOT_lorenzo robot_lorenzo recepteur_mbed_os_6

MX12.h

Committer:
denis2nis
Date:
2021-11-04
Revision:
4:277e5a4cba2e
Parent:
3:add8b050eb86
Child:
5:0cf54586a4be

File content as of revision 4:277e5a4cba2e:

#ifndef MBED_MX12_H
#define MBED_MX12_H

/**  
* @file MX12.h  
* @brief this header file will contain all required  
*        definitions and basic utilities functions. 
* @details comming soon
*  
* @author Titouan Soulard 
* @author Bruno Denis (for comments)
* 
*/ 

#include "mbed.h"

#define MX12_ANSWER_MAX_SIZE 32
#define MX12_MOTOR_COUNT 16

/* Dynamixel protocol v1.0 : Instructions
 ******************************************/
#define PROTOCOL_INSTRUCTION_PING          0x01
#define PROTOCOL_INSTRUCTION_READ          0x02
#define PROTOCOL_INSTRUCTION_WRITE         0x03
#define PROTOCOL_INSTRUCTION_REG_WRITE     0x04
#define PROTOCOL_INSTRUCTION_ACTION        0x05
#define PROTOCOL_INSTRUCTION_FACTORY_RESET 0x06
#define PROTOCOL_INSTRUCTION_REBOOT        0x08
#define PROTOCOL_INSTRUCTION_SYNC_WRITE    0x83
#define PROTOCOL_INSTRUCTION_BULK_READ     0x92



/** 
 * @brief Class to communicate with Dynamixel MX12 servomotors. 
 *
 * @details
 *  The servomotors are daisy chained to a serial link of the target 
 *  microcontroller. The class ensures the initialization of serial link 
 *  and the management of communications. 
 *  Transmission of messages to the servomotors is blocking while 
 *  reception is non-blocking thanks to the use of an interrupt routine. 
 *  
 */
class MX12 
{
    public:
    
        /** Error status occurred during the operation of servomotor.
         *
         * BDenis remarj: enum type is not suitable for the errors status 
         *                because several errors can be repported simultaneously 
         */
        enum Status {
            InstructionError,  ///<  In case of sending an undefined instruction or delivering the action instruction without the Reg Write instruction
            OverloadError,     ///<  When the current load cannot be controlled by the set Torque
            ChecksumError,     ///<  When the Checksum of the transmitted Instruction Packet is incorrect
            RangeError,        ///<  When an instruction is out of the range for use 
            OverheatingError,  ///<  When internal temperature of servomotor is out of the range of operating temperature set in the Control table
            AngleLimitError,   ///<  When Goal Position is written out of the range from CW Angle Limit to CCW Angle Limit
            InputVoltageError, ///<  When the applied voltage is out of the range of operating voltage set in the Control table
            Unknown,           ///<  ???
            Ok                 ///<  no error
        };
        
        /** State enum, possible state of communication automaton
         *
         */
         enum State {
            ReadingPosition,   ///<  ReadingPosition
            Writing,           ///<  Writing
            Available,         ///<  Available
        };
    
        /** Create MX12 instance
         *
         * @param tx board pin used for transmission in UART daisy chain link 
         *           to servomotors 
         * @param rx board pin used for reception in UART daisy chain link 
         *           to servomotors 
         * @param baud modulation rate of UART signal, unit: Baud
         *           to servomotors 
         */
        MX12(PinName tx, PinName rx, int baud=115200);
        
        /** Send desired speed to a specifc servomotor
         *
         * @param mot_id a unique value in the daisy chain network to identify
         *               each servomotor
         * @param speed a float between -1 and 1 that represents the percentage
         *              of maximum requested speed
         */
        void SetSpeed(unsigned char mot_id, float speed);
        
        char IsAvailable(void);
        
        MX12::Status GetStatus(void);
        
        
        void ReadPosition(unsigned char mot_id);
        
        float GetPosition(unsigned char mot_id);
        
        void PrintAnswer();
        
        /**
         * Build and send an instruction packet to a servomotor according
         * DYNAMIXEL Protocol 1.0 (online protocol documentation 
         * https://emanual.robotis.com/docs/en/dxl/protocol1/)
         *
         * @param[in] mot_id indicates the ID of the device (servomotor) that
         *            should receive the Instruction Packet and process it
         * @param[in] address data address in the "Control Table of RAM Area"
         *            of a servomotor MX12 (https://emanual.robotis.com/docs/en/dxl/mx/mx-12w/#control-table-of-ram-area).
         * @param[in] len if it is a write instruction, size in bytes 
         *            of the data to write in the "Control Table of RAM Area"
         * @param[in, out] data array of char containing parameter of Danamixel  
         *            protocol that are the instruction’s auxiliary data field
         *  
         * @see https://emanual.robotis.com/docs/en/dxl/protocol1/
         *
         * Packet sent
         * <PRE>
         * |Header1|Header2|Packet ID|Length|Instruction|Param1...ParamN|Checksum |
         * |-------|-------|---------|------|-----------|---------------|---------|
         * |  0xFF |  0xFF |Packet ID|Length|Instruction|Param1...ParamN| CHKSUM  |
         * | cmd[0]| cmd[1]|  cmd[2] |cmd[3]|  cmd[4]   |cmd[5]...      |(2 bytes)|
         *                                               \_  _/ \__  __/
         *                                                 \/      \/
         *                                              address   data
         *                                                        (len = N-1)
         * </PRE>
         */
        void rw(unsigned char mot_id, char address, char len, char *data);
        
        /** Interupt Routine to read in data from UART daisy chain link
         *  (serial port)
         *
         */
        void _ReadCallback();
        
        char _chksm;
    
    private:
    
        UnbufferedSerial _mx12;
        MX12::Status _status;
        char _res[MX12_ANSWER_MAX_SIZE];
        char _res_count;
        char _len;
        MX12::State _state;
        float _angle[MX12_MOTOR_COUNT];
        int _baud;
};

#endif /* MBED_MX12_H */