Skip to content

Commit afc8935

Browse files
committed
Add fast_bulk_read example
1 parent ee49c3c commit afc8935

File tree

1 file changed

+250
-0
lines changed

1 file changed

+250
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
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+
*******************************************************************************/
16+
17+
// Author: Honghyun Kim
18+
19+
#include <Dynamixel2Arduino.h>
20+
21+
// Please modify it to suit your hardware.
22+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560) // When using DynamixelShield
23+
#include <SoftwareSerial.h>
24+
SoftwareSerial soft_serial(7, 8); // DYNAMIXELShield UART RX/TX
25+
#define DXL_SERIAL Serial
26+
#define DEBUG_SERIAL soft_serial
27+
const int DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
28+
#elif defined(ARDUINO_SAM_DUE) // When using DynamixelShield
29+
#define DXL_SERIAL Serial
30+
#define DEBUG_SERIAL SerialUSB
31+
const int DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
32+
#elif defined(ARDUINO_SAM_ZERO) // When using DynamixelShield
33+
#define DXL_SERIAL Serial1
34+
#define DEBUG_SERIAL SerialUSB
35+
const int DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
36+
#elif defined(ARDUINO_OpenCM904) // When using official ROBOTIS board with DXL circuit.
37+
#define DXL_SERIAL Serial3 //OpenCM9.04 EXP Board's DXL port Serial. (Serial1 for the DXL port on the OpenCM 9.04 board)
38+
#define DEBUG_SERIAL Serial
39+
const int DXL_DIR_PIN = 22; //OpenCM9.04 EXP Board's DIR PIN. (28 for the DXL port on the OpenCM 9.04 board)
40+
#elif defined(ARDUINO_OpenCR) // When using official ROBOTIS board with DXL circuit.
41+
// For OpenCR, there is a DXL Power Enable pin, so you must initialize and control it.
42+
// Reference link : https://github.com/ROBOTIS-GIT/OpenCR/blob/master/arduino/opencr_arduino/opencr/libraries/DynamixelSDK/src/dynamixel_sdk/port_handler_arduino.cpp#L78
43+
#define DXL_SERIAL Serial3
44+
#define DEBUG_SERIAL Serial
45+
const int DXL_DIR_PIN = 84; // OpenCR Board's DIR PIN.
46+
#elif defined(ARDUINO_OpenRB) // When using OpenRB-150
47+
//OpenRB does not require the DIR control pin.
48+
#define DXL_SERIAL Serial1
49+
#define DEBUG_SERIAL Serial
50+
const int DXL_DIR_PIN = -1;
51+
#else // Other boards when using DynamixelShield
52+
#define DXL_SERIAL Serial1
53+
#define DEBUG_SERIAL Serial
54+
const int DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
55+
#endif
56+
57+
58+
/* fastBulkRead
59+
DYNAMIXEL PROTOCOL 1.0 does NOT support Fast Bulk Read feature.
60+
Structures containing the necessary information to process the 'fastBulkRead' packet.
61+
62+
struct XELInfoBulkRead_t {
63+
uint16_t addr;
64+
uint16_t addr_length;
65+
uint8_t *p_recv_buf;
66+
uint8_t id;
67+
uint8_t error;
68+
} __attribute__((packed));
69+
70+
struct InfoBulkReadInst_t {
71+
XELInfoBulkRead_t* p_xels;
72+
uint8_t xel_count;
73+
bool is_info_changed;
74+
InfoSyncBulkBuffer_t packet;
75+
} __attribute__((packed));
76+
*/
77+
78+
/* bulkWrite
79+
DYNAMIXEL PROTOCOL 1.0 does NOT support Bulk Write feature.
80+
Structures containing the necessary information to process the 'bulkWrite' packet.
81+
82+
struct XELInfoBulkWrite_t {
83+
uint16_t addr;
84+
uint16_t addr_length;
85+
uint8_t* p_data;
86+
uint8_t id;
87+
} __attribute__((packed));
88+
89+
struct InfoBulkWriteInst_t {
90+
XELInfoBulkWrite_t* p_xels;
91+
uint8_t xel_count;
92+
bool is_info_changed;
93+
InfoSyncBulkBuffer_t packet;
94+
} __attribute__((packed));
95+
*/
96+
97+
98+
const uint8_t DXL_1_ID = 1;
99+
const uint8_t DXL_2_ID = 2;
100+
const uint8_t DXL_ID_CNT = 2;
101+
const uint16_t BUF_SIZE = 128;
102+
uint8_t user_pkt_buf[BUF_SIZE];
103+
104+
struct BrDataXel1 {
105+
int16_t present_current;
106+
int32_t present_velocity;
107+
} __attribute__((packed));
108+
109+
struct BrDataXel2 {
110+
int32_t present_position;
111+
} __attribute__((packed));
112+
113+
struct BwDataXel1 {
114+
int32_t goal_velocity;
115+
} __attribute__((packed));
116+
117+
struct BwDataXel2 {
118+
int32_t goal_position;
119+
} __attribute__((packed));
120+
121+
122+
BrDataXel1 br_data_xel_1;
123+
BrDataXel2 br_data_xel_2;
124+
DYNAMIXEL::InfoBulkReadInst_t br_infos;
125+
DYNAMIXEL::XELInfoBulkRead_t info_xels_br[DXL_ID_CNT];
126+
127+
BwDataXel1 bw_data_xel_1;
128+
BwDataXel2 bw_data_xel_2;
129+
DYNAMIXEL::InfoBulkWriteInst_t bw_infos;
130+
DYNAMIXEL::XELInfoBulkWrite_t info_xels_bw[DXL_ID_CNT];
131+
132+
Dynamixel2Arduino dxl(DXL_SERIAL, DXL_DIR_PIN);
133+
134+
//This namespace is required to use Control table item names
135+
using namespace ControlTableItem;
136+
137+
void setup() {
138+
pinMode(LED_BUILTIN, OUTPUT);
139+
DEBUG_SERIAL.begin(115200);
140+
dxl.begin(57600);
141+
142+
dxl.torqueOff(DXL_1_ID);
143+
dxl.torqueOff(DXL_2_ID);
144+
dxl.setOperatingMode(DXL_1_ID, OP_VELOCITY);
145+
dxl.setOperatingMode(DXL_2_ID, OP_POSITION);
146+
dxl.torqueOn(DXL_1_ID);
147+
dxl.torqueOn(DXL_2_ID);
148+
149+
// Fill the members of structure to fastSyncRead using external user packet buffer
150+
br_infos.packet.p_buf = user_pkt_buf;
151+
br_infos.packet.buf_capacity = BUF_SIZE;
152+
br_infos.packet.is_completed = false;
153+
br_infos.p_xels = info_xels_br;
154+
155+
info_xels_br[0].id = DXL_1_ID;
156+
info_xels_br[0].addr = 126; // Present Current of X serise.
157+
info_xels_br[0].addr_length = 2 + 4; // Present Current + Present Velocity
158+
info_xels_br[0].p_recv_buf = (uint8_t*)&br_data_xel_1;
159+
160+
info_xels_br[1].id = DXL_2_ID;
161+
info_xels_br[1].addr = 132; // Present Position of X serise.
162+
info_xels_br[1].addr_length = 4; // Present Position + Present Velocity
163+
info_xels_br[1].p_recv_buf = (uint8_t*)&br_data_xel_2;
164+
165+
br_infos.xel_count = DXL_ID_CNT;
166+
br_infos.is_info_changed = true;
167+
168+
// Fill the members of structure to syncWrite using internal packet buffer
169+
bw_infos.packet.p_buf = nullptr;
170+
bw_infos.packet.is_completed = false;
171+
bw_infos.p_xels = info_xels_bw;
172+
173+
bw_data_xel_1.goal_velocity = 0;
174+
info_xels_bw[0].id = DXL_1_ID;
175+
info_xels_bw[0].addr = 104; // Goal Velocity of X serise.
176+
info_xels_bw[0].addr_length = 4; // Goal Velocity
177+
info_xels_bw[0].p_data = (uint8_t*)&bw_data_xel_1;
178+
179+
bw_data_xel_2.goal_position = 0;
180+
info_xels_bw[1].id = DXL_2_ID;
181+
info_xels_bw[1].addr = 116; // Goal Position of X serise.
182+
info_xels_bw[1].addr_length = 4; // Goal Position
183+
info_xels_bw[1].p_data = (uint8_t*)&bw_data_xel_2;
184+
185+
bw_infos.xel_count = DXL_ID_CNT;
186+
bw_infos.is_info_changed = true;
187+
}
188+
189+
void loop() {
190+
static uint32_t try_count = 0;
191+
192+
bw_data_xel_1.goal_velocity += 5;
193+
if (bw_data_xel_1.goal_velocity >= 200)
194+
bw_data_xel_1.goal_velocity = 0;
195+
bw_data_xel_2.goal_position += 255;
196+
if (bw_data_xel_2.goal_position >= 1023)
197+
bw_data_xel_2.goal_position = 0;
198+
bw_infos.is_info_changed = true;
199+
200+
DEBUG_SERIAL.print("\n>>>>>> Bulk Instruction Test : ");
201+
DEBUG_SERIAL.println(try_count++);
202+
if (true == dxl.bulkWrite(&bw_infos)) {
203+
DEBUG_SERIAL.println("[BulkWrite] Success");
204+
DEBUG_SERIAL.print(" ID: ");
205+
DEBUG_SERIAL.println(bw_infos.p_xels[0].id);
206+
DEBUG_SERIAL.print("\t Goal Velocity: ");
207+
DEBUG_SERIAL.println(bw_data_xel_1.goal_velocity);
208+
DEBUG_SERIAL.print(" ID: ");
209+
DEBUG_SERIAL.println(bw_infos.p_xels[1].id);
210+
DEBUG_SERIAL.print("\t Goal Position: ");
211+
DEBUG_SERIAL.println(bw_data_xel_2.goal_position);
212+
} else {
213+
DEBUG_SERIAL.print("[BulkWrite] Fail, Lib error code: ");
214+
DEBUG_SERIAL.print(dxl.getLastLibErrCode());
215+
}
216+
DEBUG_SERIAL.println();
217+
218+
delay(250);
219+
220+
// Transmit predefined fastBulkRead instruction packet
221+
// and receive a status packet from each DYNAMIXEL
222+
uint8_t recv_cnt = dxl.fastBulkRead(&br_infos);
223+
if (recv_cnt > 0) {
224+
DEBUG_SERIAL.print("[fastBulkRead] Success, Received ID Count: ");
225+
DEBUG_SERIAL.println(recv_cnt);
226+
227+
DEBUG_SERIAL.print(" ID: ");
228+
DEBUG_SERIAL.print(br_infos.p_xels[0].id);
229+
DEBUG_SERIAL.print(", Error: ");
230+
DEBUG_SERIAL.println(br_infos.p_xels[0].error);
231+
DEBUG_SERIAL.print("\t Present Current: ");
232+
DEBUG_SERIAL.println(br_data_xel_1.present_current);
233+
DEBUG_SERIAL.print("\t Present Velocity: ");
234+
DEBUG_SERIAL.println(br_data_xel_1.present_velocity);
235+
236+
DEBUG_SERIAL.print(" ID: ");
237+
DEBUG_SERIAL.print(br_infos.p_xels[1].id);
238+
DEBUG_SERIAL.print(", Error: ");
239+
DEBUG_SERIAL.println(br_infos.p_xels[1].error);
240+
DEBUG_SERIAL.print("\t Present Position: ");
241+
DEBUG_SERIAL.println(br_data_xel_2.present_position);
242+
} else {
243+
DEBUG_SERIAL.print("[fastBulkRead] Fail, Lib error code: ");
244+
DEBUG_SERIAL.println(dxl.getLastLibErrCode());
245+
}
246+
DEBUG_SERIAL.println("=======================================================");
247+
248+
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
249+
delay(750);
250+
}

0 commit comments

Comments
 (0)