ROBOTIS-GIT / DynamixelSDK

ROBOTIS Dynamixel SDK (Protocol1.0/2.0)
http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/overview/
Apache License 2.0
441 stars 393 forks source link

[3.6.2][MATLAB][MEGA/MAX485][MX-64R] Issue : Communicating with servo #267

Closed DanielJMonash closed 5 years ago

DanielJMonash commented 5 years ago

ISSUE TEMPLATE ver. 1.1.1

BE CAREFUL!! FOLLOW THE RULES AS FOLLOWS, OR YOUR ISSUE WILL BE WON'T FIX ANYWAY

STEP 1. Check what you are suffering from :

I get an error in the MATLAB code stating "[TxRxResult] There is no status packet!", have tried everything I can think of and it still remains. I am using the ping.m script and the error occurs when the ping is attempted. I also cannot connect to the MX-64R using R+Manager, I search through all the baud rates and I recieve "Device not found" as the error.

STEP 2. Write Title as [3.6.2][MATLAB][MEGA/MAX485][MX-64R] Issue : Communicating with servo

STEP 3. Delete all written here, and describe what your problem is

The big issue is that all the coding for the MX-64 servos are for the TTL version, I had to get a RS-485 version due to back orders and now am suffering.

So as mentioned above, I can't communicate with the MX-64R. I am using Matlab 2018a, an arduino mega 2560 and a max485 module. I am using MATLAB because I would like to use the GUI, however I can use arduino IDE and then link it with MATLAB (If that is possible). To do the UART<-->RS-485 conversion, I am following the schematic:

image

Further, I don't understand how the CPU_RXD and CPU_TXD pins are known to the arduino board or even the computer, as they aren't defined anywhere from what I can tell.

Another thing I am uncertain about is the DIRECTION485 pin. I am under the impression that this needs to be toggleable between low and high for transmitting/receiving, however if I put 'a = arduino();' in the code, I get the following error:

image

So I am not sure how I am meant to make this pin work as a switch if I can't use arduino.

The code below is what I am using for the ping.m, as far as I understand, it is for the TTL version.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Copyright 2017 ROBOTIS CO., LTD. % % Licensed under the Apache License, Version 2.0 (the "License"); % you may not use this file except in compliance with the License. % You may obtain a copy of the License at % % http://www.apache.org/licenses/LICENSE-2.0 % % Unless required by applicable law or agreed to in writing, software % distributed under the License is distributed on an "AS IS" BASIS, % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % See the License for the specific language governing permissions and % limitations under the License. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Author: Ryu Woon Jung (Leon)

% % ping Example % % % Available Dynamixel model on this example : All models using Protocol 2.0 % This example is designed for using a Dynamixel PRO 54-200, and an USB2DYNAMIXEL. % To use another Dynamixel model, such as X series, see their details in E-Manual(emanual.robotis.com) and edit below variables yourself. % Be sure that Dynamixel PRO properties are already set as %% ID : 1 / Baudnum : 1 (Baudrate : 57600) %

clc; clear all;

lib_name = '';

if strcmp(computer, 'PCWIN') lib_name = 'dxl_x86_c'; elseif strcmp(computer, 'PCWIN64') lib_name = 'dxl_x64_c'; elseif strcmp(computer, 'GLNX86') lib_name = 'libdxl_x86_c'; elseif strcmp(computer, 'GLNXA64') lib_name = 'libdxl_x64_c'; elseif strcmp(computer, 'MACI64') lib_name = 'libdxl_mac_c'; end

% Load Libraries if ~libisloaded(lib_name) [notfound, warnings] = loadlibrary(lib_name, 'dynamixel_sdk.h', 'addheader', 'port_handler.h', 'addheader', 'packet_handler.h'); end

% Protocol version PROTOCOL_VERSION = 2.0; % See which protocol version is used in the Dynamixel

% Default setting DXL_ID = 1; % Dynamixel ID: 1 BAUDRATE = 57600; DEVICENAME = 'COM3'; % Check which port is being used on your controller % ex) Windows: 'COM1' Linux: '/dev/ttyUSB0' Mac: '/dev/tty.usbserial-*'

COMM_SUCCESS = 0; % Communication Success result value COMM_TX_FAIL = -1001; % Communication Tx Failed

% Initialize PortHandler Structs % Set the port path % Get methods and members of PortHandlerLinux or PortHandlerWindows port_num = portHandler(DEVICENAME);

% Initialize PacketHandler Structs packetHandler();

dxl_comm_result = COMM_TX_FAIL; % Communication result

% Open port if (openPort(port_num)) fprintf('Succeeded to open the port!\n'); else unloadlibrary(lib_name); fprintf('Failed to open the port!\n'); input('Press any key to terminate...\n'); return; end

% Set port baudrate if (setBaudRate(port_num, BAUDRATE)) fprintf('Succeeded to change the baudrate!\n'); else unloadlibrary(lib_name); fprintf('Failed to change the baudrate!\n'); input('Press any key to terminate...\n'); return; end

% Try to ping the Dynamixel % Get Dynamixel model number % a=arduino(); % writeDigitalPin(a,'D8',0); dxl_model_number = pingGetModelNum(port_num, PROTOCOL_VERSION, DXL_ID); dxl_comm_result = getLastTxRxResult(port_num, PROTOCOL_VERSION); dxl_error = getLastRxPacketError(port_num, PROTOCOL_VERSION); if dxl_comm_result ~= COMM_SUCCESS fprintf('%s\n', getTxRxResult(PROTOCOL_VERSION, dxl_comm_result)); elseif dxl_error ~= 0 fprintf('%s\n', getRxPacketError(PROTOCOL_VERSION, dxl_error)); else fprintf('[ID:%03d] ping Succeeded. Dynamixel model number : %d\n', DXL_ID, dxl_model_number); end

% Close port closePort(port_num);

% Unload Library unloadlibrary(lib_name);

close all; clear all;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Any and all help is appreciated, thank you

kijongGil commented 5 years ago

Hi @DanielJMonash :) DynamixelSDK has been made regardless of TTL and RS485. DynamixelSDK only distinguish protocol version. This error '[TxRxResult] There is no status packet!]' is that Dynamixel is not connect. How did you connect power?

tician commented 5 years ago

http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/device_setup/

The PC-based SDK is usable only with the USB2Dynamixel, U2D2, USB2AX, or some other USB2UART converter with the correct flow control pin hooked up to the direction pin of the MAX485 transceiver IC.

Have not dealt with any older arduinos or the SDK is quite some time, so not remembering all the details about which flow control pin of the FT232 USB2UART in the USB2Dynamixel is used as the direction control pin and whether that is the same pin used in the Mega to perform a board reset over USB. The FTDI FT232R USB2UART IC on the Arduino Mega is what the SDK is talking to and that is not connected to the MAX485. You have to write the code to run on the Mega to take the packet that the SDK dumps onto the Mega's primary serial port and push that onto another serial port connected to the MAX485 and toggle the direction pin on your own when passing along packets.

DanielJMonash commented 5 years ago

Hi @DanielJMonash :) DynamixelSDK has been made regardless of TTL and RS485. DynamixelSDK only distinguish protocol version. This error '[TxRxResult] There is no status packet!]' is that Dynamixel is not connect. How did you connect power?

I am using a 3S 11.1V battery, I have it fully charged at ~12.6V and make sure that it is always above 12V. When I plug it in, I have the LED blink once, and from what I've read, that means the power is correctly connected.

DanielJMonash commented 5 years ago

http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_sdk/device_setup/

The PC-based SDK is usable only with the USB2Dynamixel, U2D2, USB2AX, or some other USB2UART converter with the correct flow control pin hooked up to the direction pin of the MAX485 transceiver IC.

Have not dealt with any older arduinos or the SDK is quite some time, so not remembering all the details about which flow control pin of the FT232 USB2UART in the USB2Dynamixel is used as the direction control pin and whether that is the same pin used in the Mega to perform a board reset over USB. The FTDI FT232R USB2UART IC on the Arduino Mega is what the SDK is talking to and that is not connected to the MAX485. You have to write the code to run on the Mega to take the packet that the SDK dumps onto the Mega's primary serial port and push that onto another serial port connected to the MAX485 and toggle the direction pin on your own when passing along packets.

I was afraid something like this is the case, do you know if there are any documents that would help me do this? I feel like I have searched everywhere and noone has had my exact setup.

gaiajoypop commented 5 years ago

I was afraid something like this is the case, do you know if there are any documents that would help me do this? I feel like I have searched everywhere and noone has had my exact setup.

In my opinion, this issue is due to the hardware configuration. The pins in diagram(CPU_RXD, CPU_TXD, DIRECTION485) should be connected to the CPU. In your case, Atmega8 in Arduino Mega. If you show the hardware configuration(Mega, UART/RS485 converter), it will be useful to each others.

kijongGil commented 5 years ago

This issue will be closed since there were no actions for a while. You can reopen this issue to show this issue to the users whenever. Thanks.

jwatte commented 5 years ago

You need to buy a USB2Dynamixel and use that as your communications device (make sure to set it to RS-485 mode) to remove the variable of the Arduino, which you apparently don't yet have a lot of experience with. You should also hook an oscilloscope to the D+/D- pins to verify that there is data going out on the serial bus. (My guess right now is that you're not successfully forwarding the command or return packets.)

DanielJMonash commented 5 years ago

The issue is that I needed to control 4 other pwm servos along with the MX-64R from a single GUI in Matlab. Is that even possible if I have the USB2DYNAMIXEL controlling the MX-64R? Won't that be using different software?

In amazed at how this 300$ servo needs the extra adapter to control it. From a first glance, the servos look amazing, but it's only once you get it that you realise what a mess they are, and how little information there is if you don't want to do exactly what they're made for.

jwatte commented 5 years ago

In amazed at how this 300$ servo needs the extra adapter to control it.

Don't worry, everyone has the sticker shock when they move away from cheap consumer goods made by the millions, into actual motion control and mechanical engineering. Compared to most industrial servos, the Robotis servos have pretty great software and documentation support, and are high value price/performance. You can pay a lot more for the same approximate performance, in a heavier/more rugged enclosure.

It's totally possible to control these servos from an Arduino or other microcontroller. It's also totally possible to control cheap hobby PWM servos from an Arduino. It's also possible to talk to more than one piece of separate hardware from Matlab at the same time. Nothing is impossible! Many people, including me, do this and more with these servos and these kinds of microcontrollers. (I, however, do not use Matlab; my preferred development environment is C++.)

It seems to me that you are having an integration challenge that you're not used to, and you're additionally having trouble solving it because you don't have the necessary practical engineering background yet.

For example: In UART communications, anything "TX" means an "outgoing" signal, and anything "RX" means an "incoming" signal. Thus, it seems to me that the "CPU_TXD" pin is the "TX" pin from the CPU (microcontroller) that you're connecting to. However, if you believe that the rule "TX on one end always connects to RX on the other end" still holds in this case, you could verify which of the two pins are actually transmit, by looking at the output signal with an oscilloscope. An idle transmit signal is high. Another example: You haven't yet told us whether your oscilloscope tells you that you're getting a signal out from the Mega, or out through the RS485 conversion chip. In order to debug the problem, you need to be able to see each part of the problem, and in order to see the problem, you need the appropriate tools.

So far, it seems very likely that the problem is somewhere in the chain you've built from Matlab -> Arduino -> RS485 -> Servo. It's unlikely the problem is with the servo itself (which a lot of people have used successfully,) nor with the Matlab SDK (which a lot of people have used successfully.) If you want to verify that the servo is OK, and that your computer can talk to it, reducing possible points of failure by using a ready-made adapter is one possible step -- you'd remove the unknown of "arduino plus RS485 adapter." If you can make that work, then you know the problem is in the component you removed, and you can work your way backwards from there.