#include "Arduino.h" #include "servo.h" using namespace DYNAMIXEL; const uint8_t DXL_ID = 1; const float DXL_PROTOCOL_VERSION = 2.0; dxl_servo servos[SERVO_COUNT]; Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN); void initServos() { //Main Arm first Servo. Model 1020 servos[0].id=11; servos[0].velocity=50; servos[0].mode=OP_CURRENT_BASED_POSITION; servos[0].current=10.0; servos[0].offset_angle=180; servos[0].min_angle=180-90; servos[0].max_angle=180+90; servos[0].orientation=1; servos[0].modelnumber=1020; //Main Arm second Servo. Model 1080 servos[1].id=12; servos[1].velocity=75; servos[1].mode=OP_POSITION; servos[1].offset_angle=180; servos[1].min_angle=180-90; servos[1].max_angle=180+90; servos[1].orientation=1; servos[1].modelnumber=1080; //Main Arm third Servo. Model 1080 servos[2].id=13; servos[2].velocity=100; servos[2].mode=OP_POSITION; servos[2].offset_angle=180; servos[2].min_angle=180-90; servos[2].max_angle=180+90; servos[2].orientation=1; servos[2].modelnumber=1080; for(uint8_t j=0;j<10;j++) { //Startup Wait Serial.print(j+1);Serial.println("/10"); delay(200); } /*changeID(1,21); scanDynamixel(57600,DXL_PROTOCOL_VERSION,64); while(1){ delay(100); }*/ dxl.begin(57600); // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version. dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION); uint8_t servoErrors=0; for (uint8_t i=0;i0 && servos[i].mode==OP_CURRENT_BASED_POSITION) { dxl.setGoalCurrent(servos[i].id, servos[i].current, UNIT_PERCENT); } dxl.writeControlTableItem(ControlTableItem::PROFILE_VELOCITY, servos[i].id, servos[i].velocity); //was 30 dxl.writeControlTableItem(ControlTableItem::PROFILE_ACCELERATION, servos[i].id, 10); dxl.torqueOn(servos[i].id); } } if (servoErrors>0) { scanDynamixel(57600,DXL_PROTOCOL_VERSION,DXL_BROADCAST_ID); while(1){ delay(100); } } } void loopServos(unsigned long millis) { static uint8_t servoReadI=0; //only one servo per function call static unsigned long last_readservo_update=0; static uint8_t servoUpdateI=0; //only one servo per function call static unsigned long last_servo_update=0; //Sequentially set servo angles if (millis-last_servo_update>SERVO_UPDATE_INTERVAL/SERVO_COUNT && millis-last_readservo_update>SERVO_MIN_COMMAND_TIME){ last_servo_update=millis; dxl.setGoalPosition(servos[servoUpdateI].id, constrain((servos[servoUpdateI].offset_angle+servos[servoUpdateI].angle*servos[servoUpdateI].orientation) , servos[servoUpdateI].min_angle,servos[servoUpdateI].max_angle), UNIT_DEGREE); servoUpdateI++; servoUpdateI%=SERVO_COUNT; } //Sequentially read servo status if (millis-last_readservo_update>SERVO_READUPDATE_INTERVAL/SERVO_COUNT && millis-last_servo_update>SERVO_MIN_COMMAND_TIME){ last_readservo_update=millis; servos[servoReadI].actual_angle = dxl.getPresentPosition(servos[servoReadI].id, UNIT_DEGREE); servoReadI++; servoReadI%=SERVO_COUNT; } } float getAverageServoPositionerror() { float angleerror=0; for (uint8_t i=0;i "); Serial.print(servos[i].offset_angle+servos[i].angle); Serial.print("Servo"); Serial.print(i);Serial.print(" : "); Serial.print(servos[i].actual_angle); Serial.print(" -> "); Serial.print(servos[i].offset_angle+servos[i].angle); Serial.println(); } Serial.print("erroravg:"); Serial.print(getAverageServoPositionerror()); Serial.println(); } void scanDynamixel(int32_t baud, uint8_t protocol,uint8_t maxid) { int8_t found_dynamixel = 0; dxl.setPortProtocolVersion((float)protocol); dxl.begin(baud); for(int id = 0; id < maxid; id++) { //highest ID is DXL_BROADCAST_ID //iterate until all ID in each buadrate is scanned. if(dxl.ping(id)) { DEBUG_SERIAL.print("ID : "); DEBUG_SERIAL.print(id); DEBUG_SERIAL.print(", Model Number: "); DEBUG_SERIAL.println(dxl.getModelNumber(id)); found_dynamixel++; } } } void scanDynamixel() { #define MAX_BAUD 5 const int32_t buad[MAX_BAUD] = {57600, 115200, 1000000, 2000000, 3000000}; int8_t index = 0; int8_t found_dynamixel = 0; for(int8_t protocol = 1; protocol < 3; protocol++) { // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version. dxl.setPortProtocolVersion((float)protocol); DEBUG_SERIAL.print("SCAN PROTOCOL "); DEBUG_SERIAL.println(protocol); for(index = 0; index < MAX_BAUD; index++) { // Set Port baudrate. DEBUG_SERIAL.print("SCAN BAUDRATE "); DEBUG_SERIAL.println(buad[index]); dxl.begin(buad[index]); for(int id = 0; id < DXL_BROADCAST_ID; id++) { //iterate until all ID in each buadrate is scanned. if(dxl.ping(id)) { DEBUG_SERIAL.print("ID : "); DEBUG_SERIAL.print(id); DEBUG_SERIAL.print(", Model Number: "); DEBUG_SERIAL.println(dxl.getModelNumber(id)); found_dynamixel++; } } } } DEBUG_SERIAL.print("Total "); DEBUG_SERIAL.print(found_dynamixel); DEBUG_SERIAL.println(" DYNAMIXEL(s) found!"); } void changeID(uint8_t present_id, uint8_t new_id) { // put your setup code here, to run once: // For Uno, Nano, Mini, and Mega, use UART port of DYNAMIXEL Shield to debug. DEBUG_SERIAL.begin(115200); while(!DEBUG_SERIAL); // Set Port baudrate to 57600bps. This has to match with DYNAMIXEL baudrate. dxl.begin(57600); // Set Port Protocol Version. This has to match with DYNAMIXEL protocol version. dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION); DEBUG_SERIAL.print("PROTOCOL "); DEBUG_SERIAL.print(DXL_PROTOCOL_VERSION, 1); DEBUG_SERIAL.print(", ID "); DEBUG_SERIAL.print(present_id); DEBUG_SERIAL.print(": "); if(dxl.ping(present_id) == true) { DEBUG_SERIAL.print("ping succeeded!"); DEBUG_SERIAL.print(", Model Number: "); DEBUG_SERIAL.println(dxl.getModelNumber(present_id)); // Turn off torque when configuring items in EEPROM area dxl.torqueOff(present_id); // set a new ID for DYNAMIXEL. Do not use ID 200 if(dxl.setID(present_id, new_id) == true){ present_id = new_id; DEBUG_SERIAL.print("ID has been successfully changed to "); DEBUG_SERIAL.println(new_id); }else{ DEBUG_SERIAL.print("Failed to change ID to "); DEBUG_SERIAL.println(new_id); } } else{ DEBUG_SERIAL.println("ping failed!"); } }