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.
Fork of AX12 by
AX12.cpp
00001 /* mbed AX-12+ Servo Library 00002 * 00003 * Copyright (c) 2010, cstyles (http://mbed.org) 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy 00006 * of this software and associated documentation files (the "Software"), to deal 00007 * in the Software without restriction, including without limitation the rights 00008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 * copies of the Software, and to permit persons to whom the Software is 00010 * furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included in 00013 * all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 * THE SOFTWARE. 00022 */ 00023 00024 #include "AX12.h" 00025 #include "mbed.h" 00026 #define AX12_DEBUG 1 00027 00028 AX12::AX12(PinName tx, PinName rx, int ID) 00029 : _ax12(tx,rx) { 00030 00031 _ax12.baud(9600); 00032 _ID = ID; 00033 } 00034 00035 // Set the mode of the servo 00036 // 0 = Positional (0-300 degrees) 00037 // 1 = Rotational -1 to 1 speed 00038 int AX12::SetMode(int mode) { 00039 00040 if (mode == 1) { // set CR 00041 SetCWLimit(0); 00042 SetCCWLimit(0); 00043 SetCRSpeed(0.0); 00044 } else { 00045 SetCWLimit(0); 00046 SetCCWLimit(300); 00047 SetCRSpeed(0.0); 00048 } 00049 return(0); 00050 } 00051 00052 00053 // if flag[0] is set, were blocking 00054 // if flag[1] is set, we're registering 00055 // they are mutually exclusive operations 00056 int AX12::SetGoal(int degrees, int flags) { 00057 00058 char reg_flag = 0; 00059 char data[2]; 00060 00061 // set the flag is only the register bit is set in the flag 00062 if (flags == 0x2) { 00063 reg_flag = 1; 00064 } 00065 00066 // 1023 / 300 * degrees 00067 short goal = (1023 * degrees) / 300; 00068 if (AX12_DEBUG) { 00069 printf("SetGoal to 0x%x\n",goal); 00070 } 00071 00072 data[0] = goal & 0xff; // bottom 8 bits 00073 data[1] = goal >> 8; // top 8 bits 00074 00075 // write the packet, return the error code 00076 int rVal = write(_ID, AX12_REG_GOAL_POSITION, 2, data, reg_flag); 00077 00078 if (flags == 1) { 00079 // block until it comes to a halt 00080 while (isMoving()) {} 00081 } 00082 return(rVal); 00083 } 00084 00085 00086 // Set continuous rotation speed from -1 to 1 00087 int AX12::SetCRSpeed(float speed) { 00088 00089 // bit 10 = direction, 0 = CCW, 1=CW 00090 // bits 9-0 = Speed 00091 char data[2]; 00092 00093 int goal = (0x3ff * abs(speed)); 00094 00095 // Set direction CW if we have a negative speed 00096 if (speed < 0) { 00097 goal |= (0x1 << 10); 00098 } 00099 00100 data[0] = goal & 0xff; // bottom 8 bits 00101 data[1] = goal >> 8; // top 8 bits 00102 00103 // write the packet, return the error code 00104 int rVal = write(_ID, 0x20, 2, data); 00105 00106 return(rVal); 00107 } 00108 00109 00110 int AX12::SetCWLimit (int degrees) { 00111 00112 char data[2]; 00113 00114 // 1023 / 300 * degrees 00115 short limit = (1023 * degrees) / 300; 00116 00117 if (AX12_DEBUG) { 00118 printf("SetCWLimit to 0x%x\n",limit); 00119 } 00120 00121 data[0] = limit & 0xff; // bottom 8 bits 00122 data[1] = limit >> 8; // top 8 bits 00123 00124 // write the packet, return the error code 00125 return (write(_ID, AX12_REG_CW_LIMIT, 2, data)); 00126 00127 } 00128 00129 int AX12::SetCCWLimit (int degrees) { 00130 00131 char data[2]; 00132 00133 // 1023 / 300 * degrees 00134 short limit = (1023 * degrees) / 300; 00135 00136 if (AX12_DEBUG) { 00137 printf("SetCCWLimit to 0x%x\n",limit); 00138 } 00139 00140 data[0] = limit & 0xff; // bottom 8 bits 00141 data[1] = limit >> 8; // top 8 bits 00142 00143 // write the packet, return the error code 00144 return (write(_ID, AX12_REG_CCW_LIMIT, 2, data)); 00145 } 00146 00147 00148 int AX12::SetID (int CurrentID, int NewID) { 00149 00150 char data[1]; 00151 data[0] = NewID; 00152 if (AX12_DEBUG) { 00153 printf("Setting ID from 0x%x to 0x%x\n",CurrentID,NewID); 00154 } 00155 return (write(CurrentID, AX12_REG_ID, 1, data)); 00156 00157 } 00158 00159 00160 // return 1 is the servo is still in flight 00161 int AX12::isMoving(void) { 00162 00163 char data[1]; 00164 read(_ID,AX12_REG_MOVING,1,data); 00165 return(data[0]); 00166 } 00167 00168 00169 void AX12::trigger(void) { 00170 00171 char TxBuf[16]; 00172 char sum = 0; 00173 00174 if (AX12_TRIGGER_DEBUG) { 00175 printf("\nTriggered\n"); 00176 } 00177 00178 // Build the TxPacket first in RAM, then we'll send in one go 00179 if (AX12_TRIGGER_DEBUG) { 00180 printf("\nTrigger Packet\n Header : 0xFF, 0xFF\n"); 00181 } 00182 00183 TxBuf[0] = 0xFF; 00184 TxBuf[1] = 0xFF; 00185 00186 // ID - Broadcast 00187 TxBuf[2] = 0xFE; 00188 sum += TxBuf[2]; 00189 00190 if (AX12_TRIGGER_DEBUG) { 00191 printf(" ID : %d\n",TxBuf[2]); 00192 } 00193 00194 // Length 00195 TxBuf[3] = 0x02; 00196 sum += TxBuf[3]; 00197 if (AX12_TRIGGER_DEBUG) { 00198 printf(" Length %d\n",TxBuf[3]); 00199 } 00200 00201 // Instruction - ACTION 00202 TxBuf[4] = 0x04; 00203 sum += TxBuf[4]; 00204 if (AX12_TRIGGER_DEBUG) { 00205 printf(" Instruction 0x%X\n",TxBuf[5]); 00206 } 00207 00208 // Checksum 00209 TxBuf[5] = 0xFF - sum; 00210 if (AX12_TRIGGER_DEBUG) { 00211 printf(" Checksum 0x%X\n",TxBuf[5]); 00212 } 00213 00214 // Transmit the packet in one burst with no pausing 00215 for (int i = 0; i < 6 ; i++) { 00216 _ax12.putc(TxBuf[i]); 00217 } 00218 00219 // This is a broadcast packet, so there will be no reply 00220 00221 return; 00222 } 00223 00224 00225 float AX12::GetPosition(void) { 00226 00227 if (AX12_DEBUG) { 00228 printf("\nGetPosition(%d)",_ID); 00229 } 00230 00231 char data[2]; 00232 00233 int ErrorCode = read(_ID, AX12_REG_POSITION, 2, data); 00234 short position = data[0] + (data[1] << 8); 00235 float angle = (position * 300)/1024; 00236 00237 return (angle); 00238 } 00239 00240 00241 float AX12::GetTemp (void) { 00242 00243 if (AX12_DEBUG) { 00244 printf("\nGetTemp(%d)",_ID); 00245 } 00246 char data[1]; 00247 int ErrorCode = read(_ID, AX12_REG_TEMP, 1, data); 00248 float temp = data[0]; 00249 return(temp); 00250 } 00251 00252 00253 float AX12::GetVolts (void) { 00254 if (AX12_DEBUG) { 00255 printf("\nGetVolts(%d)",_ID); 00256 } 00257 char data[1]; 00258 int ErrorCode = read(_ID, AX12_REG_VOLTS, 1, data); 00259 float volts = data[0]/10.0; 00260 return(volts); 00261 } 00262 00263 00264 int AX12::read(int ID, int start, int bytes, char* data) { 00265 00266 char PacketLength = 0x4; 00267 char TxBuf[16]; 00268 char sum = 0; 00269 char Status[16]; 00270 00271 Status[4] = 0xFE; // return code 00272 00273 if (AX12_READ_DEBUG) { 00274 printf("\nread(%d,0x%x,%d,data)\n",ID,start,bytes); 00275 } 00276 00277 // Build the TxPacket first in RAM, then we'll send in one go 00278 if (AX12_READ_DEBUG) { 00279 printf("\nInstruction Packet\n Header : 0xFF, 0xFF\n"); 00280 } 00281 00282 TxBuf[0] = 0xff; 00283 TxBuf[1] = 0xff; 00284 00285 // ID 00286 TxBuf[2] = ID; 00287 sum += TxBuf[2]; 00288 if (AX12_READ_DEBUG) { 00289 printf(" ID : %d\n",TxBuf[2]); 00290 } 00291 00292 // Packet Length 00293 TxBuf[3] = PacketLength; // Length = 4 ; 2 + 1 (start) = 1 (bytes) 00294 sum += TxBuf[3]; // Accululate the packet sum 00295 if (AX12_READ_DEBUG) { 00296 printf(" Length : 0x%x\n",TxBuf[3]); 00297 } 00298 00299 // Instruction - Read 00300 TxBuf[4] = 0x2; 00301 sum += TxBuf[4]; 00302 if (AX12_READ_DEBUG) { 00303 printf(" Instruction : 0x%x\n",TxBuf[4]); 00304 } 00305 00306 // Start Address 00307 TxBuf[5] = start; 00308 sum += TxBuf[5]; 00309 if (AX12_READ_DEBUG) { 00310 printf(" Start Address : 0x%x\n",TxBuf[5]); 00311 } 00312 00313 // Bytes to read 00314 TxBuf[6] = bytes; 00315 sum += TxBuf[6]; 00316 if (AX12_READ_DEBUG) { 00317 printf(" No bytes : 0x%x\n",TxBuf[6]); 00318 } 00319 00320 // Checksum 00321 TxBuf[7] = 0xFF - sum; 00322 if (AX12_READ_DEBUG) { 00323 printf(" Checksum : 0x%x\n",TxBuf[7]); 00324 } 00325 00326 // Transmit the packet in one burst with no pausing 00327 for (int i = 0; i<8 ; i++) { 00328 printf("Inizio scrittura numero %d\n",i); 00329 _ax12.putc(TxBuf[i]); 00330 printf("Fine scrittura numero %d\n",i); 00331 } 00332 00333 // Wait for the bytes to be transmitted 00334 wait (0.00002); 00335 00336 // Skip if the read was to the broadcast address 00337 if (_ID != 0xFE) { 00338 00339 // Receive the Status packet 6+ number of bytes read 00340 for (int i=0; i<(6+bytes) ; i++) { 00341 printf("Inizio lettura numero %d\n",i); 00342 Status[i] = _ax12.getc(); 00343 printf("Fine lettura numero %d dato: %d\n",i, Status[i]); 00344 } 00345 00346 // Copy the data from Status into data for return 00347 for (int i=0; i < Status[3]-2 ; i++) { 00348 data[i] = Status[5+i]; 00349 } 00350 00351 if (AX12_READ_DEBUG) { 00352 printf("\nStatus Packet\n"); 00353 printf(" Header : 0x%x\n",Status[0]); 00354 printf(" Header : 0x%x\n",Status[1]); 00355 printf(" ID : 0x%x\n",Status[2]); 00356 printf(" Length : 0x%x\n",Status[3]); 00357 printf(" Error Code : 0x%x\n",Status[4]); 00358 00359 for (int i=0; i < Status[3]-2 ; i++) { 00360 printf(" Data : 0x%x\n",Status[5+i]); 00361 } 00362 00363 printf(" Checksum : 0x%x\n",Status[5+(Status[3]-2)]); 00364 } 00365 00366 } // if (ID!=0xFE) 00367 00368 return(Status[4]); 00369 } 00370 00371 00372 int AX12:: write(int ID, int start, int bytes, char* data, int flag) { 00373 // 0xff, 0xff, ID, Length, Intruction(write), Address, Param(s), Checksum 00374 00375 char TxBuf[16]; 00376 char sum = 0; 00377 char Status[6]; 00378 00379 if (AX12_WRITE_DEBUG) { 00380 printf("\nwrite(%d,0x%x,%d,data,%d)\n",ID,start,bytes,flag); 00381 } 00382 00383 // Build the TxPacket first in RAM, then we'll send in one go 00384 if (AX12_WRITE_DEBUG) { 00385 printf("\nInstruction Packet\n Header : 0xFF, 0xFF\n"); 00386 } 00387 00388 TxBuf[0] = 0xff; 00389 TxBuf[1] = 0xff; 00390 00391 // ID 00392 TxBuf[2] = ID; 00393 sum += TxBuf[2]; 00394 00395 if (AX12_WRITE_DEBUG) { 00396 printf(" ID : %d\n",TxBuf[2]); 00397 } 00398 00399 // packet Length 00400 TxBuf[3] = 3+bytes; 00401 sum += TxBuf[3]; 00402 00403 if (AX12_WRITE_DEBUG) { 00404 printf(" Length : %d\n",TxBuf[3]); 00405 } 00406 00407 // Instruction 00408 if (flag == 1) { 00409 TxBuf[4]=0x04; 00410 sum += TxBuf[4]; 00411 } else { 00412 TxBuf[4]=0x03; 00413 sum += TxBuf[4]; 00414 } 00415 00416 if (AX12_WRITE_DEBUG) { 00417 printf(" Instruction : 0x%x\n",TxBuf[4]); 00418 } 00419 00420 // Start Address 00421 TxBuf[5] = start; 00422 sum += TxBuf[5]; 00423 if (AX12_WRITE_DEBUG) { 00424 printf(" Start : 0x%x\n",TxBuf[5]); 00425 } 00426 00427 // data 00428 for (char i=0; i<bytes ; i++) { 00429 TxBuf[6+i] = data[i]; 00430 sum += TxBuf[6+i]; 00431 if (AX12_WRITE_DEBUG) { 00432 printf(" Data : 0x%x\n",TxBuf[6+i]); 00433 } 00434 } 00435 00436 // checksum 00437 TxBuf[6+bytes] = 0xFF - sum; 00438 if (AX12_WRITE_DEBUG) { 00439 printf(" Checksum : 0x%x\n",TxBuf[6+bytes]); 00440 } 00441 00442 // Transmit the packet in one burst with no pausing 00443 for (int i = 0; i < (7 + bytes) ; i++) { 00444 _ax12.putc(TxBuf[i]); 00445 } 00446 00447 // Wait for data to transmit 00448 wait (0.00002); 00449 00450 // make sure we have a valid return 00451 Status[4]=0x00; 00452 00453 // we'll only get a reply if it was not broadcast 00454 if (_ID!=0xFE) { 00455 00456 // response is always 6 bytes 00457 // 0xFF, 0xFF, ID, Length Error, Param(s) Checksum 00458 for (int i=0; i < 6 ; i++) { 00459 Status[i] = _ax12.getc(); 00460 } 00461 00462 // Build the TxPacket first in RAM, then we'll send in one go 00463 if (AX12_WRITE_DEBUG) { 00464 printf("\nStatus Packet\n Header : 0x%X, 0x%X\n",Status[0],Status[1]); 00465 printf(" ID : %d\n",Status[2]); 00466 printf(" Length : %d\n",Status[3]); 00467 printf(" Error : 0x%x\n",Status[4]); 00468 printf(" Checksum : 0x%x\n",Status[5]); 00469 } 00470 00471 00472 } 00473 00474 return(Status[4]); // return error code 00475 }
Generated on Wed Jul 20 2022 23:01:05 by
1.7.2
