Skip to content

Commit e6096c1

Browse files
author
Kei
committed
Add some overloading function & example for creating custom
SerialPortHandler (#23)
1 parent a688da3 commit e6096c1

File tree

7 files changed

+242
-25
lines changed

7 files changed

+242
-25
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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+
#include <Dynamixel2Arduino.h>
18+
19+
20+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560)
21+
#include <SoftwareSerial.h>
22+
SoftwareSerial soft_serial(7, 8); // DYNAMIXELShield UART RX/TX
23+
#define DXL_SERIAL Serial
24+
#define DEBUG_SERIAL soft_serial
25+
const uint8_t DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
26+
#else
27+
#define DXL_SERIAL Serial1
28+
#define DEBUG_SERIAL Serial
29+
const uint8_t DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
30+
#endif
31+
32+
class NewSerialPortHandler : public DYNAMIXEL::SerialPortHandler
33+
{
34+
public:
35+
NewSerialPortHandler(HardwareSerial& port, const int dir_pin = -1)
36+
: SerialPortHandler(port, dir_pin), port_(port), dir_pin_(dir_pin)
37+
{}
38+
39+
virtual size_t write(uint8_t c) override
40+
{
41+
size_t ret = 0;
42+
digitalWrite(DXL_DIR_PIN, HIGH);
43+
while(digitalRead(DXL_DIR_PIN) != HIGH);
44+
45+
ret = port_.write(c);
46+
47+
port_.flush();
48+
digitalWrite(DXL_DIR_PIN, LOW);
49+
while(digitalRead(DXL_DIR_PIN) != LOW);
50+
51+
return ret;
52+
}
53+
54+
virtual size_t write(uint8_t *buf, size_t len) override
55+
{
56+
size_t ret;
57+
digitalWrite(DXL_DIR_PIN, HIGH);
58+
while(digitalRead(DXL_DIR_PIN) != HIGH);
59+
60+
ret = port_.write(buf, len);
61+
62+
port_.flush();
63+
digitalWrite(DXL_DIR_PIN, LOW);
64+
while(digitalRead(DXL_DIR_PIN) != LOW);
65+
66+
return ret;
67+
}
68+
69+
private:
70+
HardwareSerial& port_;
71+
const int dir_pin_;
72+
};
73+
74+
const uint8_t DXL_ID = 1;
75+
const float DXL_PROTOCOL_VERSION = 2.0;
76+
77+
Dynamixel2Arduino dxl;
78+
NewSerialPortHandler dxl_port(DXL_SERIAL, DXL_DIR_PIN);
79+
80+
81+
void setup() {
82+
// put your setup code here, to run once:
83+
84+
// Use Serial to debug.
85+
DEBUG_SERIAL.begin(115200);
86+
87+
// Set Port instance
88+
dxl.setPort(dxl_port);
89+
// Set Port baudrate to 57600bps. This has to match with DYNAMIXEL baudrate.
90+
dxl.begin(57600);
91+
// Set Port Protocol Version. This has to match with DYNAMIXEL protocol version.
92+
dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
93+
}
94+
95+
void loop() {
96+
// put your main code here, to run repeatedly:
97+
98+
DEBUG_SERIAL.print("PROTOCOL ");
99+
DEBUG_SERIAL.print(DXL_PROTOCOL_VERSION, 1);
100+
DEBUG_SERIAL.print(", ID ");
101+
DEBUG_SERIAL.print(DXL_ID);
102+
DEBUG_SERIAL.print(": ");
103+
if(dxl.ping(DXL_ID) == true){
104+
DEBUG_SERIAL.print("ping succeeded!");
105+
DEBUG_SERIAL.print(", Model Number: ");
106+
DEBUG_SERIAL.println(dxl.getModelNumber(DXL_ID));
107+
}else{
108+
DEBUG_SERIAL.println("ping failed!");
109+
}
110+
delay(500);
111+
}
112+
113+
114+

examples/advanced/read_write_ControlTableItem/read_write_ControlTableItem.ino

+4-12
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,16 @@
116116
*/
117117

118118

119-
#ifdef ARDUINO_AVR_UNO
119+
#if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_MEGA2560)
120120
#include <SoftwareSerial.h>
121-
SoftwareSerial soft_serial(7, 8); //RX,TX
121+
SoftwareSerial soft_serial(7, 8); // DYNAMIXELShield UART RX/TX
122122
#define DXL_SERIAL Serial
123123
#define DEBUG_SERIAL soft_serial
124-
const uint8_t DXL_DIR_PIN = 2; //DYNAMIXEL Shield
125-
#elif ARDUINO_AVR_MEGA2560
126-
#define DXL_SERIAL Serial
127-
#define DEBUG_SERIAL Serial1
128-
const uint8_t DXL_DIR_PIN = 2; //DYNAMIXEL Shield
129-
#elif BOARD_OpenCM904
130-
#define DXL_SERIAL Serial3 //OpenCM9.04 EXP Board's DXL port Serial. (To use the DXL port on the OpenCM 9.04 board, you must use Serial1 for Serial. And because of the OpenCM 9.04 driver code, you must call Serial1.setDxlMode(true); before dxl.begin();.)
131-
#define DEBUG_SERIAL Serial
132-
const uint8_t DXL_DIR_PIN = 22; //OpenCM9.04 EXP Board's DIR PIN. (To use the DXL port on the OpenCM 9.04 board, you must use 28 for DIR PIN.)
124+
const uint8_t DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
133125
#else
134126
#define DXL_SERIAL Serial1
135127
#define DEBUG_SERIAL Serial
136-
const uint8_t DXL_DIR_PIN = 2; //DYNAMIXEL Shield
128+
const uint8_t DXL_DIR_PIN = 2; // DYNAMIXEL Shield DIR PIN
137129
#endif
138130

139131
const uint8_t DXL_ID = 1;

keywords.txt

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ writeControlTableItem KEYWORD2
4343

4444
# Master Class
4545
setPortProtocolVersion KEYWORD2
46+
setPortProtocolVersionUsingIndex KEYWORD2
4647
getPortProtocolVersion KEYWORD2
4748
setPort KEYWORD2
4849
ping KEYWORD2

src/Dynamixel2Arduino.cpp

+57-5
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,36 @@ static bool checkAndconvertWriteData(float in_data, int32_t &out_data, uint8_t u
6767
static bool checkAndconvertReadData(int32_t in_data, float &out_data, uint8_t unit, ItemAndRangeInfo_t &item_info);
6868

6969

70+
Dynamixel2Arduino::Dynamixel2Arduino()
71+
: Master()
72+
{}
73+
7074
Dynamixel2Arduino::Dynamixel2Arduino(HardwareSerial& port, int dir_pin)
71-
: Master(), dxl_port_(port, dir_pin)
75+
: Master()
7276
{
73-
setPort(dxl_port_);
77+
p_dxl_port_ = new SerialPortHandler(port, dir_pin);
78+
setPort(p_dxl_port_);
7479
}
7580

7681
/* For Master configuration */
7782
void Dynamixel2Arduino::begin(unsigned long baud)
7883
{
79-
dxl_port_.begin(baud);
84+
p_dxl_port_ = (SerialPortHandler*)getPort();
85+
86+
if(p_dxl_port_ == nullptr)
87+
return;
88+
89+
p_dxl_port_->begin(baud);
8090
}
8191

82-
unsigned long Dynamixel2Arduino::getPortBaud() const
92+
unsigned long Dynamixel2Arduino::getPortBaud()
8393
{
84-
return dxl_port_.getBaud();
94+
p_dxl_port_ = (SerialPortHandler*)getPort();
95+
96+
if(p_dxl_port_ == nullptr)
97+
return 0;
98+
99+
return p_dxl_port_->getBaud();
85100
}
86101

87102
bool Dynamixel2Arduino::scan()
@@ -95,6 +110,9 @@ bool Dynamixel2Arduino::scan()
95110

96111
bool Dynamixel2Arduino::ping(uint8_t id)
97112
{
113+
if(getPort() == nullptr)
114+
return false;
115+
98116
bool ret = false;
99117
uint8_t i;
100118

@@ -146,6 +164,9 @@ bool Dynamixel2Arduino::ping(uint8_t id)
146164

147165
uint16_t Dynamixel2Arduino::getModelNumber(uint8_t id)
148166
{
167+
if(getPort() == nullptr)
168+
return false;
169+
149170
uint16_t model_num = 0xFFFF;
150171

151172
(void) read(id, COMMON_MODEL_NUMBER_ADDR, COMMON_MODEL_NUMBER_ADDR_LENGTH,
@@ -177,6 +198,9 @@ bool Dynamixel2Arduino::setProtocol(uint8_t id, float version)
177198
//TODO: Simplify the code by grouping model numbers.
178199
bool Dynamixel2Arduino::setBaudrate(uint8_t id, uint32_t baudrate)
179200
{
201+
if(getPort() == nullptr)
202+
return false;
203+
180204
uint16_t model_num = getModelNumberFromTable(id);
181205
uint8_t baud_idx = 0;
182206

@@ -420,6 +444,9 @@ bool Dynamixel2Arduino::ledOff(uint8_t id)
420444

421445
bool Dynamixel2Arduino::setLedState(uint8_t id, bool state)
422446
{
447+
if(getPort() == nullptr)
448+
return false;
449+
423450
bool ret = false;
424451
uint16_t model_num = getModelNumberFromTable(id);
425452

@@ -463,6 +490,9 @@ bool Dynamixel2Arduino::setLedState(uint8_t id, bool state)
463490
//TODO: Simplify the code by grouping model numbers.
464491
bool Dynamixel2Arduino::setOperatingMode(uint8_t id, uint8_t mode)
465492
{
493+
if(getPort() == nullptr)
494+
return false;
495+
466496
bool ret = false;
467497
uint16_t model_num = getModelNumberFromTable(id);
468498

@@ -707,13 +737,19 @@ float Dynamixel2Arduino::getPresentCurrent(uint8_t id, uint8_t unit)
707737

708738
int32_t Dynamixel2Arduino::readControlTableItem(uint8_t item_idx, uint8_t id, uint32_t timeout)
709739
{
740+
if(getPort() == nullptr)
741+
return 0;
742+
710743
uint16_t model_num = getModelNumberFromTable(id);
711744

712745
return readControlTableItem(model_num, item_idx, id, timeout);
713746
}
714747

715748
bool Dynamixel2Arduino::writeControlTableItem(uint8_t item_idx, uint8_t id, int32_t data, uint32_t timeout)
716749
{
750+
if(getPort() == nullptr)
751+
return false;
752+
717753
uint16_t model_num = getModelNumberFromTable(id);
718754

719755
return writeControlTableItem(model_num, item_idx, id, data, timeout);
@@ -726,6 +762,9 @@ bool Dynamixel2Arduino::writeControlTableItem(uint8_t item_idx, uint8_t id, int3
726762

727763
int32_t Dynamixel2Arduino::readControlTableItem(uint16_t model_num, uint8_t item_idx, uint8_t id, uint32_t timeout)
728764
{
765+
if(getPort() == nullptr)
766+
return 0;
767+
729768
int32_t recv_len, ret = 0;
730769
ControlTableItemInfo_t item_info;
731770

@@ -749,6 +788,9 @@ int32_t Dynamixel2Arduino::readControlTableItem(uint16_t model_num, uint8_t item
749788

750789
bool Dynamixel2Arduino::writeControlTableItem(uint16_t model_num, uint8_t item_idx, uint8_t id, int32_t data, uint32_t timeout)
751790
{
791+
if(getPort() == nullptr)
792+
return false;
793+
752794
ControlTableItemInfo_t item_info;
753795

754796
item_info = getControlTableItemInfo(model_num, item_idx);
@@ -790,6 +832,11 @@ uint16_t Dynamixel2Arduino::getModelNumberFromTable(uint8_t id)
790832

791833
float Dynamixel2Arduino::readForRangeDependencyFunc(uint8_t func_idx, uint8_t id, uint8_t unit)
792834
{
835+
p_dxl_port_ = (SerialPortHandler*)getPort();
836+
837+
if(p_dxl_port_ == nullptr)
838+
return 0.0;
839+
793840
float ret = 0;
794841
int32_t ret_data = 0;
795842
uint16_t model_num = getModelNumberFromTable(id);
@@ -807,6 +854,11 @@ float Dynamixel2Arduino::readForRangeDependencyFunc(uint8_t func_idx, uint8_t id
807854

808855
bool Dynamixel2Arduino::writeForRangeDependencyFunc(uint8_t func_idx, uint8_t id, float value, uint8_t unit)
809856
{
857+
p_dxl_port_ = (SerialPortHandler*)getPort();
858+
859+
if(p_dxl_port_ == nullptr)
860+
return false;
861+
810862
bool ret = false;
811863
int32_t data = 0;
812864
uint16_t model_num = getModelNumberFromTable(id);

src/Dynamixel2Arduino.h

+10-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ enum ParamUnit{
4545
class Dynamixel2Arduino : public DYNAMIXEL::Master
4646
{
4747
public:
48+
/**
49+
* @brief The constructor.
50+
* @code
51+
* Dynamixel2Arduino dxl;
52+
* @endcode
53+
*/
54+
Dynamixel2Arduino();
55+
4856
/**
4957
* @brief The constructor.
5058
* @code
@@ -79,7 +87,7 @@ class Dynamixel2Arduino : public DYNAMIXEL::Master
7987
* @endcode
8088
* @return It returns serial baudrate of board port.
8189
*/
82-
unsigned long getPortBaud() const;
90+
unsigned long getPortBaud();
8391

8492
/**
8593
* @brief It is API for To checking the communication connection status of DYNAMIXEL.
@@ -409,7 +417,7 @@ class Dynamixel2Arduino : public DYNAMIXEL::Master
409417
uint8_t id;
410418
} IdAndModelNum_t;
411419

412-
DYNAMIXEL::SerialPortHandler dxl_port_;
420+
DYNAMIXEL::SerialPortHandler *p_dxl_port_;
413421

414422
IdAndModelNum_t registered_dxl_[DXL_MAX_NODE];
415423
uint8_t registered_dxl_cnt_;

0 commit comments

Comments
 (0)