1- /* ******************************************************************************
2- * Copyright 2016 ROBOTIS CO., LTD.
3- *
4- * Licensed under the Apache License, Version 2.0 (the "License");
5- * you may not use this file except in compliance with the License.
6- * You may obtain a copy of the License at
7- *
8- * http://www.apache.org/licenses/LICENSE-2.0
9- *
10- * Unless required by applicable law or agreed to in writing, software
11- * distributed under the License is distributed on an "AS IS" BASIS,
12- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13- * See the License for the specific language governing permissions and
14- * limitations under the License.
15- *******************************************************************************/
1+ // Copyright 2021 ROBOTIS CO., LTD.
2+ //
3+ // Licensed under the Apache License, Version 2.0 (the "License");
4+ // you may not use this file except in compliance with the License.
5+ // You may obtain a copy of the License at
6+ //
7+ // http://www.apache.org/licenses/LICENSE-2.0
8+ //
9+ // Unless required by applicable law or agreed to in writing, software
10+ // distributed under the License is distributed on an "AS IS" BASIS,
11+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ // See the License for the specific language governing permissions and
13+ // limitations under the License.
14+
15+ // Example Environment
16+ //
17+ // - DYNAMIXEL: X series
18+ // ID = 1 & 2, Baudrate = 57600bps, DYNAMIXEL Protocol 2.0
19+ // - Controller: Arduino MKR ZERO
20+ // DYNAMIXEL Shield for Arduino MKR
21+ // - https://emanual.robotis.com/docs/en/parts/interface/mkr_shield/
22+ //
23+ // Author: David Park
1624
1725#include < Dynamixel2Arduino.h>
1826
5159/* syncRead
5260 Structures containing the necessary information to process the 'syncRead' packet.
5361
54- typedef struct XELInfoBulkRead{
55- uint16_t addr;
56- uint16_t addr_length;
62+ typedef struct XELInfoSyncRead{
5763 uint8_t *p_recv_buf;
5864 uint8_t id;
5965 uint8_t error;
60- } __attribute__((packed)) XELInfoBulkRead_t ;
66+ } __attribute__((packed)) XELInfoSyncRead_t ;
6167
62- typedef struct InfoBulkReadInst{
63- XELInfoBulkRead_t* p_xels;
68+ typedef struct InfoSyncReadInst{
69+ uint16_t addr;
70+ uint16_t addr_length;
71+ XELInfoSyncRead_t* p_xels;
6472 uint8_t xel_count;
6573 bool is_info_changed;
6674 InfoSyncBulkBuffer_t packet;
67- } __attribute__((packed)) InfoBulkReadInst_t ;
75+ } __attribute__((packed)) InfoSyncReadInst_t ;
6876*/
6977
7078/* syncWrite
7179 Structures containing the necessary information to process the 'syncWrite' packet.
7280
73- typedef struct XELInfoBulkWrite{
74- uint16_t addr;
75- uint16_t addr_length;
81+ typedef struct XELInfoSyncWrite{
7682 uint8_t* p_data;
7783 uint8_t id;
78- } __attribute__((packed)) XELInfoBulkWrite_t ;
84+ } __attribute__((packed)) XELInfoSyncWrite_t ;
7985
80- typedef struct InfoBulkWriteInst{
81- XELInfoBulkWrite_t* p_xels;
86+ typedef struct InfoSyncWriteInst{
87+ uint16_t addr;
88+ uint16_t addr_length;
89+ XELInfoSyncWrite_t* p_xels;
8290 uint8_t xel_count;
8391 bool is_info_changed;
8492 InfoSyncBulkBuffer_t packet;
85- } __attribute__((packed)) InfoBulkWriteInst_t ;
93+ } __attribute__((packed)) InfoSyncWriteInst_t ;
8694*/
8795
8896const uint8_t BROADCAST_ID = 254 ;
@@ -92,9 +100,13 @@ const uint8_t DXL_ID_LIST[DXL_ID_CNT] = {1, 2};
92100const uint16_t user_pkt_buf_cap = 128 ;
93101uint8_t user_pkt_buf[user_pkt_buf_cap];
94102
95- const uint16_t SR_START_ADDR = 132 ; // Starting Data Addr, Can differ Depending on what address to access
96- const uint16_t SR_ADDR_LEN = 4 ; // Data Length, Can differ depending on how many address to access.
97- const uint16_t SW_START_ADDR = 116 ;
103+ // Starting address of the Data to read; Present Position = 132
104+ const uint16_t SR_START_ADDR = 132 ;
105+ // Length of the Data to read; Length of Position data of X series is 4 byte
106+ const uint16_t SR_ADDR_LEN = 4 ;
107+ // Starting address of the Data to write; Goal Position = 116
108+ const uint16_t SW_START_ADDR = 116 ;
109+ // Length of the Data to write; Length of Position data of X series is 4 byte
98110const uint16_t SW_ADDR_LEN = 4 ;
99111typedef struct sr_data {
100112 int32_t present_position;
@@ -114,11 +126,11 @@ DYNAMIXEL::XELInfoSyncWrite_t info_xels_sw[DXL_ID_CNT];
114126
115127Dynamixel2Arduino dxl (DXL_SERIAL, DXL_DIR_PIN);
116128
117- // This namespace is required to use Control table item names
129+ // This namespace is required to use DYNAMIXEL Control table item name definitions
118130using namespace ControlTableItem ;
119131
120132int32_t goal_position[2 ] = {1024 , 2048 };
121- uint8_t direction = 0 ;
133+ uint8_t goal_position_index = 0 ;
122134
123135void setup () {
124136 // put your setup code here, to run once:
@@ -128,7 +140,8 @@ void setup() {
128140 dxl.begin (57600 );
129141 dxl.setPortProtocolVersion (DYNAMIXEL_PROTOCOL_VERSION);
130142
131- for (i=0 ; i<DXL_ID_CNT; i++){
143+ // Prepare the SyncRead structure
144+ for (i = 0 ; i < DXL_ID_CNT; i++){
132145 dxl.torqueOff (DXL_ID_LIST[i]);
133146 dxl.setOperatingMode (DXL_ID_LIST[i], OP_POSITION);
134147 }
@@ -143,7 +156,7 @@ void setup() {
143156 sr_infos.p_xels = info_xels_sr;
144157 sr_infos.xel_count = 0 ;
145158
146- for (i= 0 ; i< DXL_ID_CNT; i++){
159+ for (i = 0 ; i < DXL_ID_CNT; i++){
147160 info_xels_sr[i].id = DXL_ID_LIST[i];
148161 info_xels_sr[i].p_recv_buf = (uint8_t *)&sr_data[i];
149162 sr_infos.xel_count ++;
@@ -158,7 +171,7 @@ void setup() {
158171 sw_infos.p_xels = info_xels_sw;
159172 sw_infos.xel_count = 0 ;
160173
161- for (i= 0 ; i< DXL_ID_CNT; i++){
174+ for (i = 0 ; i < DXL_ID_CNT; i++){
162175 info_xels_sw[i].id = DXL_ID_LIST[i];
163176 info_xels_sw[i].p_data = (uint8_t *)&sw_data[i].goal_position ;
164177 sw_infos.xel_count ++;
@@ -171,39 +184,50 @@ void loop() {
171184 static uint32_t try_count = 0 ;
172185 uint8_t i, recv_cnt;
173186
174- for (i=0 ; i<DXL_ID_CNT; i++){
175- sw_data[i].goal_position = goal_position[direction];
187+ // Insert a new Goal Position to the SyncWrite Packet
188+ for (i = 0 ; i < DXL_ID_CNT; i++){
189+ sw_data[i].goal_position = goal_position[goal_position_index];
176190 }
191+
192+ // Update the SyncWrite packet status
177193 sw_infos.is_info_changed = true ;
178194
179195 DEBUG_SERIAL.print (" \n >>>>>> Sync Instruction Test : " );
180196 DEBUG_SERIAL.println (try_count++);
197+
198+ // Build a SyncWrite Packet and transmit to DYNAMIXEL
181199 if (dxl.syncWrite (&sw_infos) == true ){
182200 DEBUG_SERIAL.println (" [SyncWrite] Success" );
183- for (i= 0 ; i<sw_infos.xel_count ; i++){
201+ for (i = 0 ; i<sw_infos.xel_count ; i++){
184202 DEBUG_SERIAL.print (" ID: " );DEBUG_SERIAL.println (sw_infos.p_xels [i].id );
185203 DEBUG_SERIAL.print (" \t Goal Position: " );DEBUG_SERIAL.println (sw_data[i].goal_position );
186204 }
187- if (direction == 0 )
188- direction = 1 ;
205+ if (goal_position_index == 0 )
206+ goal_position_index = 1 ;
189207 else
190- direction = 0 ;
191- }else {
208+ goal_position_index = 0 ;
209+ } else {
192210 DEBUG_SERIAL.print (" [SyncWrite] Fail, Lib error code: " );
193211 DEBUG_SERIAL.print (dxl.getLastLibErrCode ());
194212 }
195213 DEBUG_SERIAL.println ();
196214
197215 delay (250 );
198216
217+
218+ // Transmit predefined SyncRead instruction packet
219+ // and receive a status packet from each DYNAMIXEL
199220 recv_cnt = dxl.syncRead (&sr_infos);
200- if (recv_cnt > 0 ){
221+ if (recv_cnt > 0 ) {
201222 DEBUG_SERIAL.print (" [SyncRead] Success, Received ID Count: " );
202223 DEBUG_SERIAL.println (recv_cnt);
203- for (i=0 ; i<recv_cnt; i++){
204- DEBUG_SERIAL.print (" ID: " );DEBUG_SERIAL.print (sr_infos.p_xels [i].id );
205- DEBUG_SERIAL.print (" , Error: " );DEBUG_SERIAL.println (sr_infos.p_xels [i].error );
206- DEBUG_SERIAL.print (" \t Present Position: " );DEBUG_SERIAL.println (sr_data[i].present_position );
224+ for (i = 0 ; i<recv_cnt; i++){
225+ DEBUG_SERIAL.print (" ID: " );
226+ DEBUG_SERIAL.print (sr_infos.p_xels [i].id );
227+ DEBUG_SERIAL.print (" , Error: " );
228+ DEBUG_SERIAL.println (sr_infos.p_xels [i].error );
229+ DEBUG_SERIAL.print (" \t Present Position: " );
230+ DEBUG_SERIAL.println (sr_data[i].present_position );
207231 }
208232 }else {
209233 DEBUG_SERIAL.print (" [SyncRead] Fail, Lib error code: " );
0 commit comments