BE@R lab / MX28

Dependents:   MX_control

Fork of MX28 by Georgios Petrou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MX28.h Source File

MX28.h

00001 /* Dynamixel MX28 servo library
00002  * Copyright (c) 2012-2013 Georgios Petrou, MIT License
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00005  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00006  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00007  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00008  * furnished to do so, subject to the following conditions:
00009  *
00010  * The above copyright notice and this permission notice shall be included in all copies or 
00011  * substantial portions of the Software.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00014  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00015  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00016  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00017  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00018  */
00019 
00020 #ifndef MX28_H
00021 #define MX28_H
00022 
00023 #include "mbed.h"
00024 //#include "SerialHalfDuplex.h"
00025 #include "iSerial.h"
00026 #include "Protocol.h"
00027 #include "Utilities.h"
00028 
00029 //#define MX28_DEBUG
00030 
00031 #define PIN_RS485_DIRC PC_8
00032 
00033 
00034 /** MX28 servo control class
00035 *
00036 * Example:
00037 * @code
00038 * 
00039 * #include "mbed.h"
00040 * #include "MX28.h"
00041 * 
00042 * Serial pc(USBTX, USBRX);
00043 * MX28 mx28(p28, p27, 57600);
00044 *
00045 * int main() 
00046 * {
00047 *    pc.baud(115200);   
00048 *    
00049 *    pc.getc();
00050 *    pc.printf("======================================================\r\n"); 
00051 *    
00052 *   uint8_t servoId = 0x01;
00053 *    
00054 *    uint16_t modelNumber;        
00055 *    mx28.GetModelNumber(servoId, &modelNumber);
00056 *    
00057 *    uint8_t firmwareVersion;        
00058 *    mx28.GetFirmwareVersion(servoId, &firmwareVersion);
00059 *    
00060 *    uint8_t id;        
00061 *    mx28.GetId(servoId, &id);               
00062 *    mx28.SetId(servoId, servoId);
00063 *    
00064 *    int32_t baudRate;
00065 *    mx28.GetBaudRate(servoId, &baudRate);    
00066 *    mx28.SetBaudRate(servoId, 57600); 
00067 *    
00068 *    uint8_t returnDelayTime;
00069 *    mx28.GetReturnDelayTime(servoId, &returnDelayTime);     
00070 *    mx28.SetReturnDelayTime(servoId, 0xFA); 
00071 *    
00072 *    uint16_t cwAngleLimit;
00073 *    mx28.GetCWAngleLimit(servoId, &cwAngleLimit);
00074 *    mx28.SetCWAngleLimit(servoId, 0x0000);
00075 *    
00076 *    uint16_t ccwAngleLimit;
00077 *    mx28.GetCCWAngleLimit(servoId, &ccwAngleLimit);    
00078 *    mx28.SetCCWAngleLimit(servoId, 0x0FFF);
00079 *    
00080 *    uint8_t highestTemperatureLimit;
00081 *    mx28.GetHighestTemperatureLimit(servoId, &highestTemperatureLimit);       
00082 *    mx28.SetHighestTemperatureLimit(servoId, 0x50);
00083 *    
00084 *    uint8_t downLimitVoltage;
00085 *    mx28.GetLowestVoltageLimit(servoId, &downLimitVoltage);       
00086 *    mx28.SetLowestVoltageLimit(servoId, 0x3C);
00087 *   
00088 *    uint8_t upLimitVoltage;
00089 *    mx28.GetHighestVoltageLimit(servoId, &upLimitVoltage);       
00090 *    mx28.SetHighestVoltageLimit(servoId, 0xA0);
00091 *    
00092 *    uint16_t maxTorque;
00093 *    mx28.GetMaxTorque(servoId, &maxTorque);    
00094 *    mx28.SetMaxTorque(servoId, 0x03FF);
00095 *    
00096 *    uint8_t statusReturnLevel;        
00097 *    mx28.GetStatusReturnLevel(servoId, &statusReturnLevel);
00098 *    mx28.SetStatusReturnLevel(servoId, 0x02);
00099 *    
00100 *    uint8_t alarmLED;        
00101 *    mx28.GetAlarmLED(servoId, &alarmLED);           
00102 *    mx28.SetAlarmLED(servoId, 0x24);
00103 *    
00104 *    uint8_t alarmShutdown;        
00105 *    mx28.GetAlarmShutdown(servoId, &alarmShutdown);           
00106 *    mx28.SetAlarmShutdown(servoId, 0x24); 
00107 *            
00108 *    uint8_t enableTorque;   
00109 *    mx28.GetEnableTorque(servoId, &enableTorque);    
00110 *    mx28.SetEnableTorque(servoId, 0x00);
00111 *    
00112 *    uint8_t enableLED;   
00113 *    mx28.GetEnableLED(servoId, &enableLED);    
00114 *    mx28.SetEnableLED(servoId, 0x00);
00115 *    
00116 *    uint8_t pGain;        
00117 *    mx28.GetPGain(servoId, &pGain);           
00118 *    mx28.SetPGain(servoId, 0x20);
00119 *    
00120 *    uint8_t iGain;        
00121 *    mx28.GetIGain(servoId, &iGain);           
00122 *    mx28.SetIGain(servoId, 0x00);
00123 *    
00124 *    uint8_t dGain;        
00125 *    mx28.GetDGain(servoId, &dGain);           
00126 *    mx28.SetDGain(servoId, 0x00);
00127 *    
00128 *    uint16_t goalPosition;
00129 *    mx28.GetGoalPosition(servoId, &goalPosition);     
00130 *    mx28.SetGoalPosition(servoId, 0x0800);
00131 *    
00132 *    uint16_t movingSpeed;
00133 *    mx28.GetMovingSpeed(servoId, &movingSpeed);     
00134 *    mx28.SetMovingSpeed(servoId, 0x00FF);
00135 *    
00136 *    uint16_t torqueLimit;
00137 *    mx28.GetTorqueLimit(servoId, &torqueLimit);     
00138 *    mx28.SetTorqueLimit(servoId, 0x03FF);
00139 *    
00140 *    uint16_t presentPosition;
00141 *    mx28.GetPresentPosition(servoId, &presentPosition);
00142 *    
00143 *    uint16_t presentSpeed;
00144 *    mx28.GetPresentSpeed(servoId, &presentSpeed); 
00145 *
00146 *    uint16_t presentLoad;
00147 *    mx28.GetPresentLoad(servoId, &presentLoad);     
00148 *    
00149 *    uint8_t presentVoltage;        
00150 *    mx28.GetPresentVoltage(servoId, &presentVoltage);
00151 *    
00152 *    uint8_t presentTemperature;        
00153 *    mx28.GetPresentTemperature(servoId, &presentTemperature);
00154 *    
00155 *    uint8_t isRegistered;   
00156 *
00157 *    mx28.GetIsRegistered(servoId, &isRegistered);
00158 *    
00159 *    uint8_t isMoving;   
00160 *    mx28.GetIsMoving(servoId, &isMoving);
00161 *    
00162 *    uint8_t lock;        
00163 *    mx28.GetIsLocked(servoId, &lock);           
00164 *    mx28.SetIsLocked(servoId, 0x00); 
00165 *    
00166 *    uint16_t punch;
00167 *    mx28.GetPunch(servoId, &punch);     
00168 *    mx28.SetPunch(servoId, 0x0020);
00169 *    
00170 *    mx28.Ping(servoId);
00171 *    
00172 *    mx28.Reset(servoId);
00173 *    
00174 *    uint8_t servo1Id = 0x01;
00175 *    uint8_t servo2Id = 0x02;
00176 *    uint8_t servo3Id = 0x03;
00177 *    
00178 *    uint16_t servo1GoalPosition = 0x0800;
00179 *    uint16_t servo2GoalPosition = 0x0800;
00180 *    uint16_t servo3GoalPosition = 0x0800;
00181 *    
00182 *    MX28_PROTOCOL_PACKET packet;
00183 *    packet.servoId = MX28_PROTOCOL_BROADCAST_ID;
00184 *    // (Data length + 1) * Number of servos + 4
00185 *    packet.length = (2+ 1) * 3 + 4;             
00186 *    packet.instructionErrorId = MX28_SYNC_WRITE;
00187 *    packet.parameter[0] = MX28_GOAL_POSITION_L;
00188 *    packet.parameter[1] = 0x06;
00189 *    packet.parameter[2] = servo1Id;
00190 *    Utilities::ConvertUInt16ToUInt8Array(servo1GoalPosition, (uint8_t*)&(packet.parameter[3]));    
00191 *    packet.parameter[9] = servo2Id;
00192 *    Utilities::ConvertUInt16ToUInt8Array(servo2GoalPosition, (uint8_t*)&(packet.parameter[10]));
00193 *    packet.parameter[16] = servo3Id;
00194 *    Utilities::ConvertUInt16ToUInt8Array(servo3GoalPosition, (uint8_t*)&(packet.parameter[17]));
00195 *   
00196 *    pc.printf("Set servos goal positions: %hu %hu %hu\r\n", servo1GoalPosition, servo2GoalPosition, servo3GoalPosition);
00197 *    
00198 *    mx28.CommunicatePacket(&packet);
00199 *          
00200 *    packet.servoId = servoId;
00201 *    packet.length = 4;
00202 *    packet.instructionErrorId = MX28_READ_DATA;
00203 *    packet.parameter[0] = MX28_PRESENT_POSITION_L;
00204 *    packet.parameter[1] = 0x08;
00205 * 
00206 *    mx28.CommunicatePacket(&packet);
00207 *    
00208 *    presentPosition = Utilities::ConvertUInt8ArrayToUInt16(packet.parameter);
00209 *    presentSpeed = Utilities::ConvertUInt8ArrayToUInt16((uint8_t*)&(packet.parameter[2]));   
00210 *    presentLoad = Utilities::ConvertUInt8ArrayToUInt16((uint8_t*)&(packet.parameter[4]));    
00211 *    presentVoltage = packet.parameter[6];
00212 *    presentTemperature = packet.parameter[7];
00213 *        
00214 *    pc.printf("Present position: %hu\r\n", presentPosition);
00215 *    pc.printf("Present speed: %hu\r\n", presentSpeed);
00216 *    pc.printf("Present load: %hu\r\n", presentLoad);
00217 *    pc.printf("Present voltage: 0x%02X\r\n", presentVoltage);
00218 *    pc.printf("Present temperature: 0x%02X\r\n", presentTemperature);             
00219 *        
00220 *    uint8_t status = mx28.GetModelNumber(servoId, &modelNumber);
00221 *   
00222 *    if(status == MX28_ERRBIT_WRITE_TIMEOUT)
00223 *        pc.printf("Error: Write timeout\r\n");
00224 *    else if(status == MX28_ERRBIT_READ_TIMEOUT) 
00225 *        pc.printf("Error: Read timeout\r\n");
00226 *    else if(status == MX28_ERRBIT_MASTER_CHECKSUM) 
00227 *        pc.printf("Error: Master checksum error\r\n");
00228 *    else
00229 *    {
00230 *        if(status & MX28_ERRBIT_VOLTAGE)
00231 *            pc.printf("Error: Input voltage error\r\n");
00232 *        if(status & MX28_ERRBIT_ANGLE)
00233 *            pc.printf("Error: Angle limit error\r\n");
00234 *        if(status & MX28_ERRBIT_OVERHEAT)
00235 *            pc.printf("Error: Overheat error\r\n");
00236 *        if(status & MX28_ERRBIT_RANGE)
00237 *            pc.printf("Error: Out of range error\r\n");
00238 *        if(status & MX28_ERRBIT_CHECKSUM)
00239 *            pc.printf("Error: Checksum error\r\n");
00240 *        if(status & MX28_ERRBIT_OVERLOAD)
00241 *            pc.printf("Error: Overload error\r\n");
00242 *        if(status & MX28_ERRBIT_INSTRUCTION)
00243 *            pc.printf("Error: Instruction code error\r\n");
00244 *    }
00245 *    
00246 *    pc.printf("======================================================\r\n"); 
00247 * 
00248 *    return 0;           
00249 * }
00250 * @endcode
00251 */
00252 class MX28
00253 {
00254     private:  
00255         /** PC serial connection used in debug mode.
00256         */
00257         Serial *pc;    
00258                           
00259         /** Servo serial half duplex connection.
00260         */
00261         //SerialHalfDuplex *servoSerialHalfDuplex;  
00262         iSerial *servoSerialHalfDuplex;  
00263         
00264     public: 
00265         /** Send the MX28 packet over the serial half duplex connection.
00266         *        
00267         * @param packet The MX28 packet.
00268         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00269         */
00270         uint8_t CommunicatePacket(MX28_PROTOCOL_PACKET *packet);
00271         
00272         /** Get the servo model number.
00273         *        
00274         * @param servoId The servo id.
00275         * @param modelNumber The variable to store the model number.
00276         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00277         */
00278         uint8_t GetModelNumber(uint8_t servoId, uint16_t *modelNumber);
00279         
00280         /** Get the servo firmware version.
00281         *        
00282         * @param servoId The servo id.
00283         * @param firmwareVersion The variable to store the model number.
00284         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00285         */        
00286         uint8_t GetFirmwareVersion(uint8_t servoId, uint8_t *firmwareVersion);
00287         
00288         /** Get the servo id.
00289         *        
00290         * @param servoId The servo id.
00291         * @param id The variable to store the id.
00292         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00293         */    
00294         uint8_t GetId(uint8_t servoId, uint8_t *id);
00295         
00296         /** Set the servo id.       
00297         *      
00298         * @param servoId The servo id.
00299         * @param newId The new servo id.
00300         * @param isRegWrite If the command will be registered.
00301         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00302         */
00303         uint8_t SetId(uint8_t servoId, uint8_t newId, bool isRegWrite = false); 
00304         
00305         /** Get the servo baudrate.
00306         *        
00307         * @param servoId The servo id.
00308         * @param baudRate The variable to store the baudrate.
00309         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00310         */  
00311         uint8_t GetBaudRate(uint8_t servoId, int32_t *baudRate);
00312         
00313         /** Set the servo baudrate.       
00314         *      
00315         * @param servoId The servo id.
00316         * @param baudRate The servo baudrate.
00317         * @param isRegWrite If the command will be registered.
00318         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00319         */      
00320         uint8_t SetBaudRate(uint8_t servoId, int baudRate, bool isRegWrite = false);
00321         
00322         /** Get the servo return delay time.
00323         *        
00324         * @param servoId The servo id.
00325         * @param returnDelayTime The variable to store the return delay time.
00326         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00327         */  
00328         uint8_t GetReturnDelayTime(uint8_t servoId, uint8_t *returnDelayTime);
00329         
00330         /** Set the servo delay time.       
00331         *      
00332         * @param servoId The servo id.
00333         * @param returnDelayTime The servo return delay time.
00334         * @param isRegWrite If the command will be registered.
00335         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00336         */   
00337         uint8_t SetReturnDelayTime(uint8_t servoId, uint8_t returnDelayTime, bool isRegWrite = false); 
00338         
00339         /** Get the servo clockwise angle limit.
00340         *        
00341         * @param servoId The servo id.
00342         * @param cwAngleLimit The variable to store the clockwise angle limit.
00343         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00344         */  
00345         uint8_t GetCWAngleLimit(uint8_t servoId, uint16_t *cwAngleLimit); 
00346         
00347         /** Set the servo clockwise angle limit.     
00348         *      
00349         * @param servoId The servo id.
00350         * @param cwAngleLimit The servo clockwise angle limit.
00351         * @param isRegWrite If the command will be registered.
00352         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00353         */     
00354         uint8_t SetCWAngleLimit(uint8_t servoId, uint16_t cwAngleLimit, bool isRegWrite = false); 
00355         
00356         /** Get the servo counterclockwise angle limit.
00357         *        
00358         * @param servoId The servo id.
00359         * @param ccwAngleLimit The variable to store the counterclockwise angle limit.
00360         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00361         */  
00362         uint8_t GetCCWAngleLimit(uint8_t servoId, uint16_t *ccwAngleLimit); 
00363         
00364         /** Set the servo counterclockwise angle limit.     
00365         *      
00366         * @param servoId The servo id.
00367         * @param ccwAngleLimit The servo counterclockwise angle limit.
00368         * @param isRegWrite If the command will be registered.
00369         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00370         */         
00371         uint8_t SetCCWAngleLimit(uint8_t servoId, uint16_t ccwAngleLimit, bool isRegWrite = false); 
00372         
00373         /** Get the servo up temperature limit.
00374         *        
00375         * @param servoId The servo id.
00376         * @param highestTemperatureLimit The variable to store the highest temperature limit.
00377         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00378         */
00379         uint8_t GetHighestTemperatureLimit(uint8_t servoId, uint8_t *highestTemperatureLimit); 
00380         
00381         /** Set the servo highest temperature limit.     
00382         *      
00383         * @param servoId The servo id.
00384         * @param highestTemperatureLimit The servo highest temperature limit.
00385         * @param isRegWrite If the command will be registered.
00386         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00387         */  
00388         uint8_t SetHighestTemperatureLimit(uint8_t servoId, uint8_t highestTemperatureLimit, bool isRegWrite = false);   
00389         
00390         /** Get the servo lowest voltage limit.
00391         *        
00392         * @param servoId The servo id.
00393         * @param lowestVoltageLimit The variable to store the lowest voltage limit.
00394         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00395         */
00396         uint8_t GetLowestVoltageLimit(uint8_t servoId, uint8_t *lowestVoltageLimit);
00397         
00398         /** Set the servo lowest voltage limit.     
00399         *      
00400         * @param servoId The servo id.
00401         * @param lowestVoltageLimit The servo lowest voltage limit.
00402         * @param isRegWrite If the command will be registered.
00403         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00404         */  
00405         uint8_t SetLowestVoltageLimit(uint8_t servoId, uint8_t lowestVoltageLimit, bool isRegWrite = false);      
00406         
00407         /** Get the servo highest voltage limit.
00408         *        
00409         * @param servoId The servo id.
00410         * @param highestVoltageLimit The variable to store the highest voltage limit.
00411         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00412         */
00413         uint8_t GetHighestVoltageLimit(uint8_t servoId, uint8_t *highestVoltageLimit);
00414         
00415         /** Set the servo highest voltage limit.   
00416         *      
00417         * @param servoId The servo id.
00418         * @param highestVoltageLimit The servo highest voltage limit.
00419         * @param isRegWrite If the command will be registered.
00420         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00421         */  
00422         uint8_t SetHighestVoltageLimit(uint8_t servoId, uint8_t highestVoltageLimit, bool isRegWrite = false);      
00423         
00424         /** Get the servo max torque.
00425         *        
00426         * @param servoId The servo id.
00427         * @param maxTorque The variable to store the max torque.
00428         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00429         */        
00430         uint8_t GetMaxTorque(uint8_t servoId, uint16_t *maxTorque);
00431         
00432         /** Set the servo max torque.   
00433         *      
00434         * @param servoId The servo id.
00435         * @param maxTorque The servo max torque.
00436         * @param isRegWrite If the command will be registered.
00437         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00438         */  
00439         uint8_t SetMaxTorque(uint8_t servoId, uint16_t maxTorque, bool isRegWrite = false);     
00440         
00441         /** Get the servo status return level.
00442         *        
00443         * @param servoId The servo id.
00444         * @param statusReturnLevel The variable to store the status return level.
00445         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00446         */
00447         uint8_t GetStatusReturnLevel(uint8_t servoId, uint8_t *statusReturnLevel);
00448            
00449         /** Set the servo status return level.   
00450         *      
00451         * @param servoId The servo id.
00452         * @param statusReturnLevel The servo status return level.
00453         * @param isRegWrite If the command will be registered.
00454         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00455         */       
00456         uint8_t SetStatusReturnLevel(uint8_t servoId, uint8_t statusReturnLevel, bool isRegWrite = false);     
00457         
00458         /** Get the servo alarm LED.
00459         *        
00460         * @param servoId The servo id.
00461         * @param alarmLED The variable to store the alarm LED.
00462         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00463         */
00464         uint8_t GetAlarmLED(uint8_t servoId, uint8_t *alarmLED);
00465         
00466         /** Set the servo alarm LED.   
00467         *      
00468         * @param servoId The servo id.
00469         * @param alarmLED The servo alarm LED.
00470         * @param isRegWrite If the command will be registered.
00471         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00472         */
00473         uint8_t SetAlarmLED(uint8_t servoId, uint8_t alarmLED, bool isRegWrite = false); 
00474         
00475         /** Get the servo alarm shutdown.
00476         *        
00477         * @param servoId The servo id.
00478         * @param alarmShutdown The variable to store the alarm shutdown.
00479         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00480         */
00481         uint8_t GetAlarmShutdown(uint8_t servoId, uint8_t *alarmShutdown);
00482         
00483         /** Set the servo alarm shutdown.   
00484         *      
00485         * @param servoId The servo id.
00486         * @param alarmShutdown The servo alarm shutdown.
00487         * @param isRegWrite If the command will be registered.
00488         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00489         */
00490         uint8_t SetAlarmShutdown(uint8_t servoId, uint8_t alarmShutdown, bool isRegWrite = false);  
00491         
00492         /** Get the servo enable torque.
00493         *        
00494         * @param servoId The servo id.
00495         * @param enableTorque The variable to store the enable torque.
00496         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00497         */
00498         uint8_t GetEnableTorque(uint8_t servoId, uint8_t *enableTorque);
00499         
00500         /** Set the servo enable torque.   
00501         *      
00502         * @param servoId The servo id.
00503         * @param enableTorque The servo enable torque.
00504         * @param isRegWrite If the command will be registered.
00505         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00506         */
00507         uint8_t SetEnableTorque(uint8_t servoId, uint8_t enableTorque, bool isRegWrite = false); 
00508         
00509         /** Get the servo enable LED.
00510         *        
00511         * @param servoId The servo id.
00512         * @param enableLED The variable to store the enable LED.
00513         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00514         */
00515         uint8_t GetEnableLED(uint8_t servoId, uint8_t *enableLED);
00516         
00517         /** Set the servo enable LED.  
00518         *      
00519         * @param servoId The servo id.
00520         * @param enableLED The servo enable LED.
00521         * @param isRegWrite If the command will be registered.
00522         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00523         */
00524         uint8_t SetEnableLED(uint8_t servoId, uint8_t enableLED, bool isRegWrite = false);    
00525         
00526         /** Get the servo P gain.
00527         *        
00528         * @param servoId The servo id.
00529         * @param pGain The variable to store the P gain.
00530         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00531         */
00532         uint8_t GetPGain(uint8_t servoId, uint8_t *pGain);
00533         
00534         /** Set the servo P gain.  
00535         *      
00536         * @param servoId The servo id.
00537         * @param pGain The servo P gain.
00538         * @param isRegWrite If the command will be registered.
00539         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00540         */
00541         uint8_t SetPGain(uint8_t servoId, uint8_t pGain, bool isRegWrite = false);
00542         
00543         /** Get the servo I gain.
00544         *        
00545         * @param servoId The servo id.
00546         * @param iGain The variable to store the I gain.
00547         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00548         */
00549         uint8_t GetIGain(uint8_t servoId, uint8_t *iGain);
00550          
00551         /** Set the servo I gain.  
00552         *      
00553         * @param servoId The servo id.
00554         * @param iGain The servo I gain.
00555         * @param isRegWrite If the command will be registered.
00556         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00557         */
00558         uint8_t SetIGain(uint8_t servoId, uint8_t iGain, bool isRegWrite = false); 
00559          
00560         /** Get the servo D gain.
00561         *        
00562         * @param servoId The servo id.
00563         * @param dGain The variable to store the D gain.
00564         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00565         */
00566         uint8_t GetDGain(uint8_t servoId, uint8_t *dGain);
00567          
00568         /** Set the servo D gain.  
00569         *      
00570         * @param servoId The servo id.
00571         * @param dGain The servo D gain.
00572         * @param isRegWrite If the command will be registered.
00573         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00574         */
00575         uint8_t SetDGain(uint8_t servoId, uint8_t dGain, bool isRegWrite = false);        
00576         
00577         /** Get the servo goal position.
00578         *        
00579         * @param servoId The servo id.
00580         * @param goalPosition The variable to store the goal position.
00581         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00582         */
00583         uint8_t GetGoalPosition(uint8_t servoId, uint16_t *goalPosition); 
00584         
00585         /** Set the servo goal position.
00586         *      
00587         * @param servoId The servo id.
00588         * @param goalPosition The servo goal position.
00589         * @param isRegWrite If the command will be registered.
00590         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00591         */
00592         uint8_t SetGoalPosition(uint8_t servoId, uint16_t goalPosition, bool isRegWrite = false);       
00593         
00594         /** Get the servo moving speed.
00595         *        
00596         * @param servoId The servo id.
00597         * @param movingSpeed The variable to store the moving speed.
00598         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00599         */
00600         uint8_t GetMovingSpeed(uint8_t servoId, uint16_t *movingSpeed); 
00601         
00602         /** Set the servo moving speed.
00603         *      
00604         * @param servoId The servo id.
00605         * @param movingSpeed The servo moving speed.
00606         * @param isRegWrite If the command will be registered.
00607         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00608         */
00609         uint8_t SetMovingSpeed(uint8_t servoId, uint16_t movingSpeed, bool isRegWrite = false);        
00610         
00611         /** Get the servo torque limit.
00612         * 0 to 1023 (0x3FF) is available, and the unit is about 0.1%.  
00613         * For example, if the value is 512, it is about 50%; that means only 50% of the maximum torque will be used.
00614         * If the power is turned on, the value of Max Torque (Address 14, 15) is used as the initial value.       
00615         *
00616         * @param servoId The servo id.
00617         * @param torqueLimit The variable to store the torque limit.
00618         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00619         */
00620         uint8_t GetTorqueLimit(uint8_t servoId, uint16_t *torqueLimit); 
00621         
00622         /** Set the servo torque limit.
00623         *      
00624         * @param servoId The servo id.
00625         * @param torqueLimit The servo torque limit.
00626         * @param isRegWrite If the command will be registered.
00627         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00628         */
00629         uint8_t SetTorqueLimit(uint8_t servoId, uint16_t torqueLimit, bool isRegWrite = false);       
00630         
00631         /** Get the servo present position.
00632         * The range of the value is 0~4095 (0xFFF), and the unit is 0.088 degree.        
00633         *
00634         * @param servoId The servo id.
00635         * @param presentPosition The variable to store the present position.
00636         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00637         */
00638         uint8_t GetPresentPosition(uint8_t servoId, uint16_t *presentPosition); 
00639         
00640         /** Get the servo present speed.
00641         * 0~2047 (0x000~0X7FF) can be used.
00642         * If a value is in the rage of 0~1023 then the motor rotates to the CCW direction.
00643         * If a value is in the rage of 1024~2047 then the motor rotates to the CW direction.
00644         * The 10th bit becomes the direction bit to control the direction; 0 and 1024 are equal.
00645         * The value unit is about 0.11rpm.
00646         * For example, if it is set to 300 then the motor is moving to the CCW direction at a rate of about 34.33rpm.        
00647         *
00648         * @param servoId The servo id.
00649         * @param presentSpeed The variable to store the present speed.
00650         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00651         */
00652         uint8_t GetPresentSpeed(uint8_t servoId, uint16_t *presentSpeed);
00653         
00654         /** Get the servo present load.
00655         * The range of the value is 0~2047, and the unit is about 0.1%.
00656         * If the value is 0~1023, it means the load works to the CCW direction.
00657         * If the value is 1024~2047, it means the load works to the CW direction.
00658         * That is, the 10th bit becomes the direction bit to control the direction, and 1024 is equal to 0.
00659         * For example, the value is 512, it means the load is detected in the direction of CCW about 50% of the maximum torque.        
00660         *
00661         * @param servoId The servo id.
00662         * @param presentLoad The variable to store the present load.
00663         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00664         */
00665         uint8_t GetPresentLoad(uint8_t servoId, uint16_t *presentLoad);
00666         
00667         /** Get the servo present voltage.
00668         * This value is 10 times larger than the actual voltage. 
00669         * For example, when 10V is supplied, the data value is 100 (0x64)
00670         *        
00671         * @param servoId The servo id.
00672         * @param presentVoltage The variable to store the present voltage.
00673         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00674         */
00675         uint8_t GetPresentVoltage(uint8_t servoId, uint8_t *presentVoltage);
00676         
00677         /** Get the servo present temperature.
00678         * It is the internal temperature of Dynamixel in Celsius.
00679         * Data value is identical to the actual temperature in Celsius. 
00680         * For example, if the data value is 85 (0x55), the current internal temperature is 85℃.
00681         *        
00682         * @param servoId The servo id.
00683         * @param presentTemperature The variable to store the present temperature.
00684         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00685         */
00686         uint8_t GetPresentTemperature(uint8_t servoId, uint8_t *presentTemperature);
00687         
00688         /** Get if there are commands transmitted by MX28_REG_WRITE.
00689         * 0 There are no commands transmitted by REG_WRITE.
00690         * 1 There are commands transmitted by REG_WRITE. 
00691         *
00692         * @param servoId The servo id.
00693         * @param isRegistered The variable to store if it is registered.
00694         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00695         */
00696         uint8_t GetIsRegistered(uint8_t servoId, uint8_t *isRegistered);
00697         
00698         /** Get if the servo is moving.
00699         * 0 Goal position command execution is completed.
00700         * 1 Goal position command execution is in progress.
00701         *
00702         * @param servoId The servo id.
00703         * @param isMoving The variable to store if the servo is moving.
00704         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00705         */
00706         uint8_t GetIsMoving(uint8_t servoId, uint8_t *isMoving);
00707         
00708         /** Get if the servo EEPROM is locked.
00709         * 0 EEPROM area can be modified.
00710         * 1 EEPROM area cannot be modified.
00711         *        
00712         * @param servoId The servo id.
00713         * @param isLock The variable to store if the servo EEPROM is locked.
00714         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00715         */
00716         uint8_t GetIsLocked(uint8_t servoId, uint8_t *isLocked);
00717         
00718         /** Set if the servo EEPROM is locked.
00719         *      
00720         * @param servoId The servo id.
00721         * @param isLocked The variable to store if the servo EEPROM is locked.
00722         * @param isRegWrite If the command will be registered.
00723         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00724         */
00725         uint8_t SetIsLocked(uint8_t servoId, uint8_t isLocked, bool isRegWrite = false);    
00726         
00727         /** Get the servo punch.
00728         * Can choose vales from 0x00 to 0x3FF.
00729         *      
00730         * @param servoId The servo id.
00731         * @param punch The variable to store the servo punch. 
00732         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00733         */
00734         uint8_t GetPunch(uint8_t servoId, uint16_t *punch);
00735         
00736         /** Set the servo punch.     
00737         *      
00738         * @param servoId The servo id.
00739         * @param punch The servo punch value.
00740         * @param isRegWrite If the command will be registered.
00741         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00742         */    
00743         uint8_t SetPunch(uint8_t servoId, uint16_t punch, bool isRegWrite = false);
00744         
00745         /** Ping the servo.
00746         * No action. Used for obtaining a Status Packet.
00747         *      
00748         * @param servoId The servo id.
00749         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00750         */
00751         uint8_t Ping(uint8_t servoId);
00752         
00753         /** Reset the servo.
00754         * Changes the control table values of the Dynamixel actuator
00755         * to the Factory Default Value settings     
00756         *
00757         * @param servoId The servo id.
00758         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00759         */
00760         uint8_t Reset(uint8_t servoId);
00761        
00762         /** Trigger the servo.
00763         * Triggers the action registered by the REG_WRITE instruction
00764         *
00765         * @param servoId The servo id.
00766         * @return MX28_ERRBIT_NONE if succeeded, error code otherwise.
00767         */
00768         uint8_t Action(uint8_t servoId);
00769               
00770         /** Create an MX28 servo object connected to the specified serial half duplex pins,
00771         *   with the specified baudrate.
00772         *
00773         * @param tx Send pin.
00774         * @param rx Receive pin. 
00775         * @param baudrate The bus speed. 
00776         */
00777         MX28(PinName tx, PinName rx, int baudRate);
00778                
00779         /** Destroy an MX28 servo object
00780         */
00781         ~MX28(); 
00782 };
00783 
00784 #endif // MX28_H