Giter VIP home page Giter VIP logo

opencm9.04's People

Contributors

chcbaram avatar hancheol-cho avatar jaehyunshim avatar kurte avatar opusk avatar robotis-will avatar robotpilot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opencm9.04's Issues

Problem when using more than 4 motors.

Hello. I am having a problem when I try to use more than 4 motors. The following code writes (async) DXL_CNT motors (based on some of the examples).

#include <DynamixelWorkbench.h>

#define DEVICE_NAME "3"

#define BAUDRATE  1000000
#define DXL_CNT   4

DynamixelWorkbench dxl_wb;

int dxl_id[DXL_CNT] = {1, 2, 33, 34};

int32_t pos = 0;

void setup() {
  Serial.begin(57600);
  digitalWrite(LED_BUILTIN, HIGH);
  while(!Serial);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.println("Starting...");
  delay(200);
  pinMode(LED_BUILTIN, OUTPUT);
  dxl_wb.begin(DEVICE_NAME, BAUDRATE);
  
  for(int i=0; i<DXL_CNT; i++){
    Serial.print("Ping ID=");
    Serial.print(dxl_id[i]);
    Serial.print("... ");
    dxl_wb.ping(dxl_id[i]);
    Serial.print("Done... ");
    dxl_wb.jointMode(dxl_id[i]);
    Serial.println("Connected.");
  }
}

void loop(){
  Serial.print("Pos = ");
  Serial.println(pos);
  for(int i=0; i<DXL_CNT; i++){
    dxl_wb.goalPosition(dxl_id[i], pos);
  }
  pos = pos < 500 ? pos + 100 : 0;
  delay(2000);
}

It works fine, the serial output is:

Starting...
Ping ID=1... Done... Connected.
Ping ID=2... Done... Connected.
Ping ID=33... Done... Connected.
Ping ID=34... Done... Connected.
Pos = 0
Pos = 100
Pos = 200
Pos = 300
Pos = 400
Pos = 500
Pos = 0

But when I change #define DXL_CNT 4 by #define DXL_CNT 5 and int dxl_id[DXL_CNT] = {1, 2, 33, 34}; by int dxl_id[DXL_CNT] = {1, 2, 33, 34, 80};, I get:

Starting...
Ping ID=1... Done... Connected.
Ping ID=2... Done... Connected.
Ping ID=33... Done... Connected.
Ping ID=34... Done... 

And the OpenCM 9.04 processor dies, the USB connection is lost and I have to reset the board to be able to close the arduino serial monitor.

The problem happens when I try to do jointMode the motor 34, but it worked with DXL_CNT=4!!!

The problem persists with any combination of IDs.

MOTORS:

  • ID 1 = MX-106
  • ID 2 = MX-28
  • ID 33 = MX-28
  • ID 34 = RX-64
  • ID 80 = AX-12+

Communication problem with OpenCM9.04 via ArduinoIDE

Hello,

I've installed ArduinoIDE on my Ubuntu laptop and connected OpenCM9.04 board to it via USB. So, I'm able to run BlinkLED sketch and green LED really blinks. However, when I'm trying to run Serial_HelloWorld sketch, I see it is uploaded and says "Go Application", but I find neither counts nor any errors in terminal.

Here is the full terminal output:

Sketch uses 34232 bytes (29%) of program storage space. Maximum is 116736 bytes.
Global variables use 8644 bytes of dynamic memory.
Enter bootloader
stm32ld ver 1.0.1
OpenCM Download Ver 1.0.4 2015.06.16 
Board Name : CM-904
Ready To download 
Flash : 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 
Write Size : 34520
CheckSum : Success..
Go Application

Any ideas why that happens?

I'm using ArduinoIDE 1.8.9 with OpenCM9.04 driver v.1.4.1 if that matters.

[OpenCMIDE]:can not get more than 30RPM from AX12+.

Hi.
We are controlling a furuta pendulum using AX12+, but we can not get any velocity more than 3.14 rad/s or 30 RPM which we really need. I was wondering if something has to be set to reach the maximum velocity.
Any help would be appreciated.
Thanks in advance.

Serial2 Settings

Can you guys please give an option to set the Serial2 settings? I see that they are hard coded, and I need "Serial_8E2" settings to read an SBUS signal. I know there's some workarounds, but why do that when I just need to change those settings in code?

ARDUINO IDE : Not able to build when openCM is selected

Hi there,

I've just followed step by step installation guide for openCM board library on Arduino IDE but I have the following issue even when my sketch is empty

Arduino : 1.8.7 (Mac OS X), Carte : "OpenCM9.04 Board, OpenCM Bootloader"

fork/exec /Users/renauddidier/Library/Arduino15/packages/OpenCM904/tools/opencm_gcc/5.4.0-2016q2/bin/arm-none-eabi-ar: no such file or directory
Erreur de compilation pour la carte OpenCM9.04 Board

Can you help me to get it working ?

Thanks

Problem with installation of library (OpenCM) for Arduino

I added link in preferences, but when I opened boards manager, I couldn't download library for OpenCM9.04 and I got the message (attached screenshot). PC: Windows 10 and Arduino IDE 1.8.7. Could you help me with this problem?
error of opencm library

[keil]: AX12+ does not move, although I can communicate with it.

I am trying to program AX12+ with keil on stm32f407VG.
Now, I can communicate with the motor by changing data in the registers, and I have tested changing the LED status and settings, but the motor does not move at all.
I am giving commands to the motor without any RX pin, that is to say, the data pin is connected to TX pin on my board ( we do not need any feedback from the motor.) with 12v,4.5A power supply.
Any suggestion about where the problem might be?

Thanks in advance.

Incompatibility with Adafruit Graphics Libraries

Hello!

I am currently trying to use an Adafruit LCD display with the OpenCM9.04. It appears the libraries GFX and ST7735 are not compatible currently with the board as digitalPinToPort and portOutputRegister seem to not be declared. I've attempted to modify the #include statements to no avail. Is there a certain library I should include that I'm just overlooking?

OpenCM9.04 & Visual Micro Debugging

Hello,

We are developing our firmware for our robotic arms to run on the CM9.04 and using the dynamixelSDK. We have recently moved over to coding in Visual Studio using the Visual Micro extension. The visual micro extension is for developing Arduino projects inside the Visual Studio C++ IDE. It has many helpful features and allows for far more advanced development.

We are trying to set up debugging to work with the OpenCM9.04 board and I'm posting for help on how to achieve this. Offering the OpenCM9.04 to work with Visual Micro would be a huge advantage for all your 3rd party developers.

Visual Micro says that we have to set up the software serial debugger option and we are not sure of the proper settings to make this work.

I have made a post at VM forums here:
https://www.visualmicro.com/forums/YaBB.pl?num=1538797491/0#4

Here are links explaining how to set up serial for debugging:
https://www.visualmicro.com/post/2012/05/06/Configure-debug-for-other-types-of-serial-transport.aspx

https://www.visualmicro.com/post/2013/04/26/How-to-debug-Arduino-on-a-different-usb-serial-port.aspx

Attached is a screenshot of the output shown when trying to run debugging. And on the left in the box is project settings that we need to set up correctly.

projectpropertiesandoutput

Did you open the OpenCM9.04 bootloader?

I have a pair of OpenCM9.04 board that have the STM32 micro damaged, did you open the bootloader?, in order to change the micro and load the firmware vía SWD.

Source code for R++ Manager CM9.04 sketch?

Sorry, not sure if this is the appropriate place to ask this.

Is the source code for R++ Manager 2 for the Open CM 9.04 firmware recovery available? Hopefully as an Arduino sketch?

Would be nice to try out things like updates to it, to potentially use Serial.flush(), when it detects that it is sending back a response over USB back to the host and it has completed a full packet.

I can and have written my own versions of code similar to these for other boards and can do for this as well, but might be nice to not reinvent the wheel. And if it works well then maybe can create a Pull Request with the updates

[OpenCM9.04]: interrupt pins

Hi,
I was trying to program OpenCM9.04 using OPENCM IDE. I am wondering which pins can be attached to an interrupt. Any information regarding this matter would be appreciated.
I want to read an encoder pulses with this board to avoid serial communication with other boards, and then command a certain speed to AX12+, so I need 2 interrupts at least.

SampleCode

Hi @KurtE @OpusK @ROBOTIS-Will
I am trying to write a basic code for AX-12a : wheel mode writing speed and reading position. I would like to create a base and then add other functionalities(like reading load etc).
The main thing is that I would like to use the standard arduino structure:
Setup() - code to run once
Loop() - main code to run repeatedly

This is not working...any idea?

#include <DynamixelSDK.h>

#define AX_CW_ANGLE_LIMIT_H 7
#define AX_CCW_ANGLE_LIMIT_L 8
#define AX_CCW_ANGLE_LIMIT_H 9
/** RAM AREA **/
#define AX_TORQUE_ENABLE 24
#define AX_GOAL_POSITION_L 30
#define AX_GOAL_POSITION_H 31
#define AX_GOAL_SPEED_L 32
#define AX_GOAL_SPEED_H 33
#define AX_TORQUE_LIMIT_L 34
#define AX_TORQUE_LIMIT_H 35
#define AX_PRESENT_POSITION_L 36
#define AX_PRESENT_POSITION_H 37
#define AX_PRESENT_SPEED_L 38
#define AX_PRESENT_SPEED_H 39
#define AX_PRESENT_LOAD_L 40
#define AX_PRESENT_LOAD_H 41

// Protocol version
#define PROTOCOL_VERSION 1.0

// Default setting
#define DXL_ID 1 // Dynamixel ID: 1
#define BAUDRATE 1000000
#define DEVICENAME "3" // Check which port is being used on your controller

#define TORQUE_ENABLE 1 // Value for enabling the torque
#define TORQUE_DISABLE 0 // Value for disabling the torque

#define ESC_ASCII_VALUE 0x1b

dynamixel::PortHandler *portHandler;
dynamixel::PacketHandler *packetHandler;

// Communication result
int dxl_comm_result = COMM_TX_FAIL;
uint8_t dxl_error = 0;
int16_t ax_present_position = 0;
uint16_t ax_moving_speed = 1024 + 800;

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial);
Serial.println("Start..");

dynamixel::PortHandler *portHandler = dynamixel::PortHandler::getPortHandler(DEVICENAME);
// Initialize PacketHandler instance
// Set the protocol version
// Get methods and members of Protocol1PacketHandler or Protocol2PacketHandler
dynamixel::PacketHandler *packetHandler = dynamixel::PacketHandler::getPacketHandler(PROTOCOL_VERSION);

// Open port
if (portHandler->openPort())
{
Serial.print("Succeeded to open the port!\n");
}
else
{
Serial.print("Failed to open the port!\n");
Serial.print("Press any key to terminate...\n");
return;
}

// Set port baudrate
if (portHandler->setBaudRate(BAUDRATE))
{
Serial.print("Succeeded to change the baudrate!\n");
}
else
{
Serial.print("Failed to change the baudrate!\n");
Serial.print("Press any key to terminate...\n");
return;
}
/*
// Enable Dynamixel Torque
dxl_comm_result = packetHandler->write1ByteTxRx(portHandler, DXL_ID, AX_TORQUE_ENABLE, TORQUE_ENABLE, &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
packetHandler->getTxRxResult(dxl_comm_result);
}
else if (dxl_error != 0)
{
packetHandler->printRxPacketError(dxl_error);
}
else
{
Serial.print("Dynamixel has been successfully connected!\n");
}
*/
// Change Dynamixel CW Angle Limit
dxl_comm_result = packetHandler->write2ByteTxRx(portHandler, DXL_ID, AX_CW_ANGLE_LIMIT_L,0, &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
Serial.printf("%sn", packetHandler->getTxRxResult(dxl_comm_result));
}
else if (dxl_error != 0)
{
Serial.printf("%sn", packetHandler->getRxPacketError(dxl_error));
}
else
{
Serial.printf("Dynamixel CW angle set to 0 successfully!\n");
}

// Change Dynamixel CCW Angle Limit
dxl_comm_result = packetHandler->write2ByteTxRx(portHandler, DXL_ID, AX_CCW_ANGLE_LIMIT_L, 0, &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
Serial.printf("%sn", packetHandler->getTxRxResult(dxl_comm_result));
}
else if (dxl_error != 0)
{
Serial.printf("%sn", packetHandler->getRxPacketError(dxl_error));
}
else
{
Serial.printf("Dynamixel CCW angle set to 0 successfully!\n");
}

}

void loop() {
// Write goal speed
dxl_comm_result = packetHandler->write2ByteTxRx(portHandler, DXL_ID, AX_GOAL_SPEED_H, ax_moving_speed , &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
Serial.printf("%sn", packetHandler->getTxRxResult(dxl_comm_result));
}
else if (dxl_error != 0)
{
Serial.printf("%sn", packetHandler->getRxPacketError(dxl_error));
}

// Read present Position
dxl_comm_result = packetHandler->read2ByteTxRx(portHandler, DXL_ID, AX_PRESENT_POSITION_H, ax_present_position , &dxl_error);
if (dxl_comm_result != COMM_SUCCESS)
{
Serial.printf("%sn", packetHandler->getTxRxResult(dxl_comm_result));
}
else if (dxl_error != 0)
{
Serial.printf("%sn", packetHandler->getRxPacketError(dxl_error));
}

Serial.printf("[ID:%03d] Pres:%dnn", DXL_ID, ax_present_position);
}

BT-410 & OpenCM9.04 via Arduino IDE

Hello,

I'm interesting in setting of wireless communication between Arduino IDE (Windows 10) and OpenCM9.04 via Bluetooth module BT-410. Could you help me how I can carry out this communication?

EEPROM library problem

The EEPROM library is not working. I tried the simple "write" and "read" example, but board is not responding after downloading the example on it.

Can we detect how much stack space and heap memory is used by a sketch?

Not sure if this is the best place to ask? This is not totally specific to OpenCM, this equally will apply to OpenCR, XEL, Ros To Arduino... But the actual code may differ.

Again not sure if this is better to ask here or RobotSource or Robotis Forum?

But wondering if there are any suggestions on how to detect how much memory is being used by a sketch. For example I am pretty sure that when I try to blindly merge in the current Dyanmixel SDK, my test apps were failing to properly run as the stack and heap corrupted each other.

Would be great if we could somehow find out how much non-static memory a program is using, which would would help to measure reductions in usage.

I don't know for example if the new operation as well as malloc(), maybe call _sbrk(). If so might be able to enable test for collision... (Would need to maybe change the commented out write statement...

But again this does not show us how close we are getting...

Was wondering if it would make sense to do something like, maybe have the startup code, do something like write a standard byte or the like to all memory over "end" to some known quantity.

Again assuming that _sbrk is correct and we can hack it slightly, we can hopefully find out how far the heap has grown.

We could then scan from the heap_end back to at worst case back to current stack pointer, but basically keep walking up in memory until we hit something that is NOT our prefill values and assume the stack grew at least to there... Obviously the stack could have grown beyond that if it had used those magic values, but hopefully close enough...

In my test app that failed earlier. I added some init code:

 // Print out some memory information
  Serial.printf("End Memory location: %x\n", (uint32_t)&end);
  Serial.printf("Stack Pointer: %x\n", (uint32_t)stack_ptr);

Which Output:

End Memory location: 20003450
Stack Pointer: 20004fd8

Which if I subtract the two I see they differ by 7048 bytes. Which might explain why increasing the size of buffers from 2K to 4K and a write allocated a 4K buffer and the stuffing function also used 4K on stack where these two collided.

Does this make sense? Has anyone already setup something like this?

[Arduino IDE][AX-12A] Issues reading Present Position from AX-12A

I tried to get the Present Position value of AX-12A by using Dynamixelworkbench, but it does not cause an error and the value is 0.
API of 1 can get the value with , but it could not get with API of 2.
What is the cause?
I will attach the log and code at that time.

1. bool readRegister (uint8_t id, uint16_t address, uint16_t length, uint32_t * data, const char ** log = NULL);
2. bool readRegister (uint8_t id, const char * item_name, int32_t * data, const char ** log = NULL);

Environment
OpenCM9.04, SMPS2Dynamixel, Arduino IDE 1.8.8, DynamixelWorkbench 1.3.0, Windows10

Dynamixel Setting

  • Model Name
    AX-12A

  • ID
    ID1

  • Baud Rate of Dynamixels
    1000000

  • Protocol Version
    Protocol1.0

code

#include <DynamixelWorkbench.h>

#define DEVICE_NAME "1"

#define BAUDRATE  1000000
#define DXL_ID_1  1

DynamixelWorkbench dxl_wb;

uint8_t dxl_id = DXL_ID_1;
uint16_t goal_position[2] = {0, 1023};
const uint8_t handler_index = 0;

void setup()
{
  Serial.begin(57600);
  while (!Serial); // Wait for Opening Serial Monitor

  const char *log;
  bool result = false;

  uint16_t model_number = 0;

  result = dxl_wb.init(DEVICE_NAME, BAUDRATE, &log);
  if (result == false)
  {
    Serial.println(log);
    Serial.println("Failed to init");
  }
  else
  {
    Serial.print("Succeeded to init : ");
    Serial.println(BAUDRATE);
  }
  result = dxl_wb.ping(dxl_id, &model_number, &log);
  if (result == false)
  {
    Serial.println(log);
    Serial.println("Failed to ping");
  }
  else
  {
    dxl_wb.torqueOn(dxl_id);
    Serial.println("Succeeded to ping");
    Serial.print("id : ");
    Serial.print(dxl_id);
    Serial.print(" model_number : ");
    Serial.println(model_number);
  }
}

void loop()
{
  const char *log;
  bool result = false;

  int32_t get_data = 0;

  // id , address , data_length , read_data, log
  result = dxl_wb.writeRegister(dxl_id, 30, 2, (uint8_t*)&goal_position[0], &log);
  if (result == false)
  {
    Serial.println(log);
    Serial.println("Failed to write position");
  }
  else
  {
    Serial.println(log);
  }
  
  do
  {
    //result = dxl_wb.readRegister(dxl_id, 36 , 2, &get_data , &log);
    result = dxl_wb.readRegister(dxl_id, "Present_Position", &get_data , &log);
    if (result == false)
    {
      Serial.println(log);
    }
    else
    {
      Serial.print("[ID ");
      Serial.print(dxl_id);
      Serial.print(" ]");
      Serial.print(" Goal Position : ");
      Serial.print(goal_position[0]);
      Serial.print(" Present Position : ");
      Serial.println(get_data);
    }
  } while (abs(goal_position[0] - get_data) > 15);

  swapUint16(goal_position);
}

void swapUint16(uint16_t *array)
{
  uint16_t tmp = array[0];
  array[0] = array[1];
  array[1] = tmp;
}

log

Succeeded to init : 1000000
Succeeded to ping
id : 1 model_number : 12
[DynamixelDriver] Succeeded to write!
[ID 1 ] Goal Position : 0 Present Position : 0
[DynamixelDriver] Succeeded to write!
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
[ID 1 ] Goal Position : 1023 Present Position : 0
...

Dynamixel Workbench: PRO+ Issues

Users are reporting that the DYNAMIXEL Workbench library, when used with OpenCM9.04 + Arduino IDE, does not properly change the Profile Acceleration when a jointeMode instruction is used for DXL PRO+.

The value '1000' should go to the acceleration registry, but it doesn't take.

The work around is to add a second line:

servo.jointMode(servoID[1], 2920, 1000);
servo.itemWrite(servoID[1], "Profile_Acceleration", 1495, &log);

Unable to upload code on OpenCM 9.04

I am trying to upload one of the examples (Examples -> OpenCM 9.04 -> 01_Basics -> b_Blink_LED) on the OpenCM 9.04 Type B board. Initially when I connect the board using micro-usb cable, only the Power LED (Red color) lights up. When I try to upload the example I get the following error:

Sketch uses 34404 bytes (29%) of program storage space. Maximum is 116736 bytes.
Global variables use 8644 bytes of dynamic memory.
stm32ld ver 1.0.1
Unable to connect to bootloader
OpenCM Download Ver 1.0.4 2015.06.16 
Fail to connect OpenCM

Next I connected the Board when pressing down on User SW button. This time both Power (Red) and Status (Green) LEDs light up. Now if I try to upload the example code I get the following error:

Sketch uses 34404 bytes (29%) of program storage space. Maximum is 116736 bytes.
Global variables use 8644 bytes of dynamic memory.
Enter bootloader

Could you please point out how to solve the issue.

Issues reading data from MX-28AR

I am unable to read out any information from my MX-28AR dynamixel.

Hardware config: OpenCM9.04 - RS485 Expansion Board - MX-28AR

Running Protocol 2.0

I am unable to get any information from the dynamixel to print over the serial channel. I am able to send data to the servo and I see the response (IE, the servo MOVES to the position sent).

Below is a modified version of the "o_Read_Write" example in the Dynamixel Workbench set.
`#include <DynamixelWorkbench.h>

#if defined(OPENCM904)
#define DEVICE_NAME "3" //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
#elif defined(OPENCR)
#define DEVICE_NAME ""
#endif

#define BAUDRATE 57600
#define DXL_ID 1

DynamixelWorkbench dxl_wb;

void setup()
{
Serial.begin(57600);
// while(!Serial); // If this line is activated, you need to open Serial Terminal.

dxl_wb.begin(DEVICE_NAME, BAUDRATE);
dxl_wb.ping(DXL_ID);

dxl_wb.jointMode(DXL_ID);
}

void loop()
{
static int index = 0;
int32_t present_position = 0;

//int32_t goal_position[2] = {1000, 2000};

//dxl_wb.itemWrite(DXL_ID, "Goal_Position", goal_position[index]);

dxl_wb.itemWrite(DXL_ID, "Present_Position", 2000);
present_position = dxl_wb.itemRead(DXL_ID, "Present_Position");
SerialUSB.print(present_position);`

The servo moves to the position, but once I open up a serial monitor through the Arduino IDE, all I get is zeros...

image

I have tried reading values from several different items in the servo as well as any and all of the example programs that use the itemRead() command, and I am always met with a bunch of zeros.

Regards,
Greg

Should digitalWrite - only work with HIGH and LOW?

I thought I would try out one of the forum posts about a program not working on Arduino that worked on other SDK...
http://en.robotis.com/service/forum_view.php?bbs_no=2406903&page=1&save_sca=&sca=&save_stx=&stx=&sfl=

So compiled program and looked at output with Logic Analyzer. The data did not look valid...
The data was output using the line:

 digitalWrite(Max7219_pinDIN,DATA&0x80)

Which was not working. However the line:

digitalWrite(Max7219_pinDIN,(DATA&0x80)? HIGH : LOW);

Took a quick look at the digitalWrite code:

extern void digitalWrite( uint32_t ulPin, uint32_t ulVal )
{

  switch(ulVal) {

    case HIGH:
      HAL_GPIO_WritePin(g_Pin2PortMapArray[ulPin].GPIOx_Port,g_Pin2PortMapArray[ulPin].Pin_abstraction,GPIO_PIN_SET);
			break;

    case LOW:
      HAL_GPIO_WritePin(g_Pin2PortMapArray[ulPin].GPIOx_Port,g_Pin2PortMapArray[ulPin].Pin_abstraction,GPIO_PIN_RESET);
			break;

    default:
			break;
  }
}

It looks like it only works with the two values HIGH and LOW. Most systems I have worked with assumed HIGH for any non 0 value.

Serial USB not displaying negative dynamixel position values

I have an OpenCM9.04 connected to a MX-64AT dynamixel. I have set the dynamixel to Multi-Turn Mode. I command the dynamixel to move to different goal positions and use the "readWord" function to read the present position (addresses 36 and 37) and print to the Serial Monitor via USB. According to the e-manual for MX-64AT, in multi-turn mode, the dynamixel should be able to go to position values in the range -28672 to +28672. When the dynamixel is in positive position values, the position prints fine. But when it goes to negative values, all I get is "65535". Here's the code used to print out position:

//move to new goal within while loop
Dxl.writeWord(1, 30, newGoal);
while ( abs(newGoal - Dxl.readWord(1, 36)) > 10 )
{
      SerialUSB.print("Position: ");
      SerialUSB.print(Dxl.readWord(1, 36));
      SerialUSB.print(", Goal: ");
      SerialUSB.println(newGoal);
}

An excerpt of the output displayed on Serial Monitor as the dynamixel moves from positive position values to negative position values is as follows:

Position: 1837, Goal: -7000
Position: 1716, Goal: -7000
Position: 1599, Goal: -7000
Position: 1482, Goal: -7000
Position: 1364, Goal: -7000
Position: 1247, Goal: -7000
Position: 1125, Goal: -7000
Position: 1007, Goal: -7000
Position: 890, Goal: -7000
Position: 777, Goal: -7000
Position: 664, Goal: -7000
Position: 553, Goal: -7000
Position: 439, Goal: -7000
Position: 327, Goal: -7000
Position: 214, Goal: -7000
Position: 99, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000
Position: 65535, Goal: -7000

What am I doing wrong?

Can not program OpenCM 9.04 using Arduino IDE...

This has been mentioned in a few different threads on Robotis forum, such as: http://en.robotis.com/service/forum_view.php?bbs_no=2406740&slg=&page_type=&mode=&submode=

I have an OpenCM9.04B board I purchased awhile ago probably from Trossen Robotics. I can currently program this board using the Robotis_OpenCM IDE, however I can not program it using your Arduino board install as it fails. It also fails to use the failsafe to load a program or update the firmware using your different apps such as R+ Manager or Roboplus Manager.

However I have some newer 904A and 904C boards which this same set works just fine.

Not sure if some firmware changed at some point? If so can I somehow reflash the 904B? I do have an ST-Link which I have used in the past on the Trossen Arbotix-Pro.

If not easily fixable, not a big deal, as these boards are pretty cheap.

[openCM IDE]: I can not communicate with OPENCM9.04

Hi again,
I used opencm9.04 and it was fine, but from this afternoon I can not cammunicate with it. I can not even upload a blink program on it. on arduino IDE it says :
image
and on openCM IDE it says:
image
My computer finds ROBOTIS virtual com ports.
Can anyone help me please?

I2C OpenCM9.04C board using Arduino IDE

I'm attempting to connect to an IMU (Adafruit BNO055) using an OpenCM9.04 board with I2C. I tried using the Wire.h library and the I2CDev library, but it still doesn't recognize the connection. I have the wires connected to pins 24 and 25 for SDA and SCL connections. At the beginning of my code, I tried using wire.begin(14,15) and wire.begin(24,25) to initialize the I2C but it doesn't seem to work. Any idea how I can connect with the IMU? I know the IMU works because I can get it working for an Arduino Uno, but not for the OpemCM9.04.

description missing for M42P pro plus servos

I am unable to control M42P-010-s260-R Pro Plus servo because I think there is no description in the library. When pinging the servo using the "ping" SDK example with both the OpenCr1.0 and the OpenCM9.04 the model # comes up as "0"

when I try to use the sync_write example with the M42P there is no movement.

I am able to ping and control H42P servo with no issue.

st-link simple example

Hello! I'm new to ARM programming and couldn't find any manuals/examples on C++ programming via ST-Link for your board... Could you give some simple example of code and process of it's building with flashing OpenCM via ST-link?

For example, I have Dynamixel ax-12a servos and want to rotate one of them with C++ bare bones on your board. Will I be able to use Dynamixel SDK for this task?

Wish the OpenCM9.04 had a more complete USB descriptor

As the title mentions, I wish the descriptor was more complete, some of it may simply be cosmetic, like maybe having string objects to give the company name and product name... But part of it is also functional information. For example does each OpenCM9.04 have a Serial number?

My guess is currently not or at least not accessible as part of the USB information. Why is this maybe important. Unlike other Arduino devices, that I plug into my computer, all of the OpenCM boards all try to use the same COM port number on Windows. I Have not checked on a MAC, but guessing probably the same.

Example comparing the information that Linux knows about the device:

  dmesg | tail
  [  187.801982] usb 1-3: new full-speed USB device number 8 using xhci_hcd
  [  187.931238] usb 1-3: New USB device found, idVendor=fff1, idProduct=ff48
  [  187.931246] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
  [  187.931250] usb 1-3: Product: ROBOTIS Virtual COM Port
  [  187.931253] usb 1-3: Manufacturer: CM-900
  [  187.931564] usb 1-3: ep 0x82 - rounding interval to 1024 microframes, ep desc says 2040 microframes
  [  187.972767] cdc_acm 1-3:1.0: ttyACM0: USB ACM device
  [  187.973957] usbcore: registered new interface driver cdc_acm
  [  187.974013] cdc_acm: USB Abstract Control Model driver for USB modems and 

  kurt@kurt-UP-Turtle:~$ lsusb
  Bus 002 Device 002: ID 8086:0a80 Intel Corp.
  Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
  Bus 001 Device 007: ID 0424:2530 Standard Microsystems Corp.
  Bus 001 Device 006: ID 0424:4603 Standard Microsystems Corp.
  Bus 001 Device 008: ID fff1:ff48
  Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

  kurt@kurt-UP-Turtle:~$ lsusb -v -d  fff1:ff48

  Bus 001 Device 008: ID fff1:ff48
  Device Descriptor:
    bLength                18
    bDescriptorType         1
    bcdUSB               2.00
    bDeviceClass            2 Communications
    bDeviceSubClass         0
    bDeviceProtocol         0
    bMaxPacketSize0        64
    idVendor           0xfff1
    idProduct          0xff48
    bcdDevice            2.00
    iManufacturer           1 (error)
    iProduct                2 (error)
    iSerial                 0
    bNumConfigurations      1
    Configuration Descriptor:
      bLength                 9
      bDescriptorType         2
      wTotalLength           67
      bNumInterfaces          2
      bConfigurationValue     1
      iConfiguration          0
      bmAttributes         0x80
        (Bus Powered)
      MaxPower                0mA
      Interface Descriptor:
        bLength                 9
        bDescriptorType         4
        bInterfaceNumber        0
        bAlternateSetting       0
        bNumEndpoints           1
        bInterfaceClass         2 Communications
        bInterfaceSubClass      2 Abstract (modem)
        bInterfaceProtocol      1 AT-commands (v.25ter)
        iInterface              0
        CDC Header:
          bcdCDC               1.10
        CDC Call Management:
          bmCapabilities       0x00
          bDataInterface          1
        CDC ACM:
          bmCapabilities       0x02
            line coding and serial state
        CDC Union:
          bMasterInterface        0
          bSlaveInterface         1
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x82  EP 2 IN
          bmAttributes            3
            Transfer Type            Interrupt
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0008  1x 8 bytes
          bInterval             255
      Interface Descriptor:
        bLength                 9
        bDescriptorType         4
        bInterfaceNumber        1
        bAlternateSetting       0
        bNumEndpoints           2
        bInterfaceClass        10 CDC Data
        bInterfaceSubClass      0 Unused
        bInterfaceProtocol      0
        iInterface              0
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x03  EP 3 OUT
          bmAttributes            2
            Transfer Type            Bulk
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0040  1x 64 bytes
          bInterval               0
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x81  EP 1 IN
          bmAttributes            2
            Transfer Type            Bulk
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0040  1x 64 bytes
          bInterval               0
  Device Status:     0x3100
    (Bus Powered)

Now if you instead compare the information for a PJRC Teensy 3.2 board

  [ 1353.572055] usb 1-3: new full-speed USB device number 9 using xhci_hcd
  [ 1353.701457] usb 1-3: New USB device found, idVendor=16c0, idProduct=0483
  [ 1353.701471] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
  [ 1353.701478] usb 1-3: Product: USB Serial
  [ 1353.701485] usb 1-3: Manufacturer: Teensyduino
  [ 1353.701491] usb 1-3: SerialNumber: 2706960
  [ 1353.703111] cdc_acm 1-3:1.0: ttyACM0: USB ACM device

  kurt@kurt-UP-Turtle:~$ lsusb
  Bus 002 Device 002: ID 8086:0a80 Intel Corp.
  Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
  Bus 001 Device 007: ID 0424:2530 Standard Microsystems Corp.
  Bus 001 Device 006: ID 0424:4603 Standard Microsystems Corp.
  Bus 001 Device 009: ID 16c0:0483 Van Ooijen Technische Informatica Teensyduino Serial
  Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

  kurt@kurt-UP-Turtle:~$ lsusb -v -d 16c0:0483

  Bus 001 Device 009: ID 16c0:0483 Van Ooijen Technische Informatica Teensyduino Serial
  Couldn't open device, some information will be missing
  Device Descriptor:
    bLength                18
    bDescriptorType         1
    bcdUSB               1.01
    bDeviceClass            2 Communications
    bDeviceSubClass         0
    bDeviceProtocol         0
    bMaxPacketSize0        64
    idVendor           0x16c0 Van Ooijen Technische Informatica
    idProduct          0x0483 Teensyduino Serial
    bcdDevice            2.00
    iManufacturer           1
    iProduct                2
    iSerial                 3
    bNumConfigurations      1
    Configuration Descriptor:
      bLength                 9
      bDescriptorType         2
      wTotalLength           67
      bNumInterfaces          2
      bConfigurationValue     1
      iConfiguration          0
      bmAttributes         0xc0
        Self Powered
      MaxPower              100mA
      Interface Descriptor:
        bLength                 9
        bDescriptorType         4
        bInterfaceNumber        0
        bAlternateSetting       0
        bNumEndpoints           1
        bInterfaceClass         2 Communications
        bInterfaceSubClass      2 Abstract (modem)
        bInterfaceProtocol      1 AT-commands (v.25ter)
        iInterface              0
        CDC Header:
          bcdCDC               1.10
        CDC Call Management:
          bmCapabilities       0x01
            call management
          bDataInterface          1
        CDC ACM:
          bmCapabilities       0x06
            sends break
            line coding and serial state
        CDC Union:
          bMasterInterface        0
          bSlaveInterface         1
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x82  EP 2 IN
          bmAttributes            3
            Transfer Type            Interrupt
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0010  1x 16 bytes
          bInterval              64
      Interface Descriptor:
        bLength                 9
        bDescriptorType         4
        bInterfaceNumber        1
        bAlternateSetting       0
        bNumEndpoints           2
        bInterfaceClass        10 CDC Data
        bInterfaceSubClass      0 Unused
        bInterfaceProtocol      0
        iInterface              0
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x03  EP 3 OUT
          bmAttributes            2
            Transfer Type            Bulk
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0040  1x 64 bytes
          bInterval               0
        Endpoint Descriptor:
          bLength                 7
          bDescriptorType         5
          bEndpointAddress     0x84  EP 4 IN
          bmAttributes            2
            Transfer Type            Bulk
            Synch Type               None
            Usage Type               Data
          wMaxPacketSize     0x0040  1x 64 bytes
          bInterval               0

You can see some of the differences, in particular, the difference in:

    iManufacturer           1 (error)
    iProduct                2 (error)
    iSerial                 0

    versus

    iManufacturer           1
    iProduct                2
    iSerial                 3

There are many times when this information may not be important to most people, but could be if they for example wish to use multiple of these devices and be able control different sets of servos.

My guess is that some of this could be updated in the file: ...\OpenCM9.04\arduino\opencm_arduino\opencm9.04\variants\OpenCM904\hw\usb_cdc

Again not sure if the boards have a unique serial number or not.

Hope this makes sense.

Code hang: while (Serial2.read() != -1) ;

I have some arduino code that was working on a few different Arduino platforms (AVR, Teensy 3.x and LC, Edison) that is now hanging.

I was trying to flush out any data in a Uart input buffer, by doing:

while (Serial2.read() != -1) ;

And the code hung. Obviously I could do it a different way like:

while (Serial2.available()) Serial2.read();

But the original code should work as well. I sort of was surprised that the Arduino install only included core header files and not the sources. I am assuming this project is the sources.

The UARTClass.cpp code simply returns stuff from drv...

int UARTClass::read( void )
{
  rx_cnt++;
  return drv_uart_read(_uart_num);
}

and the drv_uart_read code does not check if the queue is empty, like peek does.

int drv_uart_read(uint8_t uart_num)
{
    int ret = -1;
    int index;

    index = drv_uart_rx_buf_tail[uart_num];

    ret = drv_uart_rx_buf[uart_num][index];

    drv_uart_rx_buf_tail[uart_num] = (drv_uart_rx_buf_tail[uart_num] + 1) % DRV_UART_RX_BUF_LENGTH;

    return ret;
}

Uarts - non blocking writes?

Again not sure if best place to ask this. Feel free to close it not appropriate.

I am thinking about experimenting with trying to make the calls like Serial2.write(...) to not necessarily delay the whole processor until the write fully completes (TC bit set).

I believe both the OpenCM9.04 as well as the OpenCR boards, UART classes, write one byte at a time with a blocking function: Note these code excerpts are actually OpenCR code, but a lot of it is identical on OPenCM

size_t UARTClass::write( const uint8_t uc_data )
{
  tx_cnt++;
  return drv_uart_write(_uart_num, uc_data);
}

Which calls:

uint32_t drv_uart_write(uint8_t uart_num, const uint8_t wr_data)
{
  HAL_UART_Transmit(&huart[uart_num], (uint8_t *)&wr_data, 1, 10);
  return 1;
}

And the HAL_UART_Transmit function will wait until there is room in the double buffering, checking for TXE bit set, then writes to TDR register

Then waits for TC (Transfer Complete) before returning...

Things I would like to try:
a) Don't write one byte at a time: Example: PortHandlerArduino::writePort calls the Serialport write function; Example OpenCM: length_written = p_dxl_serial->write(packet, length);

The UARTClass is derived from HardwareSerial class which is derived from Stream class which is derived from PrintClass... Print class has a virtual function: virtual size_t write(const uint8_t *buffer, size_t size);
The default implementation just writes one byte at a time.

size_t Print::write(const uint8_t *buffer, size_t size)
{
  size_t n = 0;
  while (size--) {
    n += write(*buffer++);
  }
  return n;
}

So I would suggest overwrite this method at some level like UART class, which maybe needs a new version of drv_uart_write which takes buffer and count which it passes to passes this down to HAL function...

This would keep the output register full as the internal loop waits on TXE so the the output register should not empty until the whole count is output...

b) Wondering about trying to remove calls like Serial2.println("Code got here");
from locking up the processor until the last character is fully output.

Wondering about trying to use either HAL_UART_Transmit_IT or HAL_UART_Transmit_DMA. It is easier for me to understand the workings of _IT, as some of the documentation on _DMA is not clear to me.
Has anyone experimented with either of these?

Suggestions on how to use either of them.

Note converting to either of these would require some other changes to make work properly. In particular DXL buss code. Would need to do the equivalent to Serial3.flush() (or Serial1....) which waits for the actual output of the DXL data, before we switch the IO pin to convert the buss in read mode.

c) Maybe do something like was done on Teensy. That is have the serial port know that it is setup for Half duplex mode. In their case, there was a method added: transmitterEnable(pin) assume Serial1 here.

When this was enabled, the serial class was setup, that when you called Serial1.write(...), the internal code would switch the port to output mode. Then the ISR functions, would detect when the output queue was empty and the Transfer complete (TC) is set and then automatically switch the buss back to read mode. This way if for example if your code is doing something like txPacket, the code does not have to wait until this completes before continuing.

So again wondering if any of this makes any sense. Also any suggestions on how best to maybe do some of this?

Again I will hopefully play around with some of this. But any suggestions would be appreciated.

Kurt

Can't unlock the stm32f103

@OpusK, Hi! When I'm trying to flash the stm32f103 on the opencm 9.04 board via st-link, openocd gets an error:

Info : device id = 0x20036410
Info : flash size = 128kbytes
Error: stm32x device protected
Error: failed erasing sectors 0 to 2

I've tried stm32f1x unlock 0 but it didn't help...

OpenCM 9.04 problem with linux and ROS

Hello, I am using OpenCM9.04 for my project. I have passed through different difficulties.

  1. PC1 with AMD64 architecture works fine with Robotis when I controlled with Windows 10. The motors aka dynamixels are pinged successfully and work fine.

  2. I have downloaded and follow all the tutorials to build by using ROS and linux but when I ping the dynamixels so it dont find any dynamixels. I have also tried position control, but it gives error TxxRxx: The status packet is missing or some error about status packet

  3. PC2 with aarch64 architecture: (Using Linux)
    2.1) I have downloaded and follow all the tutorials to build by using ROS and linux but when I ping the dynamixels so it dont find any dynamixels. I have also tried position control, but it gives error TxxRxx: The status packet is missing or some error about status packet

2.2) I then used Arduino IDE to code OpenCm9.04 but when I port to arduino and installing OPENCM9.04 library it gives "opencm-gcc is not available for your operating system "

I want to know that is why OPENCM9.04 dont work with ROS and linux??? and also about opencm-gcc is not available?

Also when I am using my PC x86_64, i first use arduino to ping the dynamixel, during uploading it says "Enter Bootloader" then after some seconds it says done uploaing, application success. What do it mean "Enter Bootloader"? Does it entering the bootloader or ask from us. I have never faced this issue in windows.

xl430 not found wth roboplus wizard or dynamixel_workbench_single_monitor

HI,

I can connect and control all my 3 servos using opencm904 + 485 using arduino IDE and the dynamixel_workbench s_monitor example script. But the dxl_tosser example script of the opencm IDE does not work with the xl430 motors. It works with my xl320. Using those, I can also use roboplus wizard. But roboplus wizard does not find the xl430 servos. What is the difference? Both servo types use protocol 2.0. I read that opencm IDE is being discontiued, and arduino IDE should be used. But I cannot find something similar to dxl_tosser in the arduino IDE examples. I want to use the tosser to have the same behaviour as USB2Dynamixel. How can I do that?

Lasse Børresen

Trying to run the I2C in slave mode

Hi, I'm trying to connect the openCM9.04 board to some other control unit and thinking about receiving command through the hardware I2C. Is there any possible way to let the openCM side be in slave mode, receive command and send back data? It will be better if this can be done through DMA or interruptions

vibration

I have 6 xl320 with opencm 904c. when the motors are connected some are vibrating and slightly moving. why is that do you think? thanks.

SerialX - Half duplex support - Support FlySky IBUS

Not sure if this is the best place to ask and or discuss...

Background:
I am playing with a prototype new version of the Trossen Robotics PhantomX hexapod that is now built with XL430-W250 servos instead of AX-12/18 servos. Also they would like to get away from using their on Arbotix-M board (Atmega644p) and use the OpenCM board and maybe get away from their Arbotix Commander remote (XBEE)... More details of current PhantomX is up at:
https://www.trossenrobotics.com/phantomx-ax-hexapod.aspx . So looking at some alternatives. I personally want the remote to have a at least one or two analog joysticks..

With some other processors I would probably go with PS3 or PS4 like remotes but not sure how to use them here...

So I am now experimenting with a Fly Sky Remote (FS-i6S) with an FS-IA6B receiver as they are reasonably cheap and they have the ability to talk to a PC using TTL Serial at 115200. I have now been able to rig up a connection to Serial2 on OpenCM board to receive 10 channels of data from the remote. Another interesting thing about this remote is there is some ability for the receiver to send back data that can be displayed on the remote. They do this using a half duplex Serial connection. Some of this is talked about at: https://github.com/betaflight/betaflight/wiki/Single-wire-FlySky-(IBus)-telemetry

Experimenting
Currently I have a test program that does some of this currently using two Serial ports. The Serial2 to receive the SERVO data and the bidirectional SENS(or) code that I have hooked up to a DXL TTL pin on OpenCM board and hacked up code to use the DXL code to control direction.

But I was thinking of experimenting with trying to do both using Serial2...

Question:
So the question is, has anyone tried using the processors hardware support for half duplex?
Some of this is decribed in section 27.3.10 of the STM32F10x Reference manual.

I know that the HAL layer has some support for this, in the function; HAL_HalfDuplex_Init
But I don't think anyone calls it. Was wondering if it might make sense to try adding a new UARTMode like Mode_8N1_HALFDUPLEX which could be passed in through
Serial2.begin(115200, Mode_8N1_HALFDUPLEX )

The underlying code would then have to pick off this flag and call off to HAL_HalfDuplex_Init instead of HAL_UART_Init. My guess is it would also require additional changes as the initialization of the IO pins would probably be different. RX Pin not used TX pin supposed to be configured either floating input (or output high open-drain)

From description could not tell if that pin configuration for TX would be done at init time and/or when we detect that there is no more data to output.

So again I am wondering if anyone has tried something like this? Make sense? Or better to just punt for now?
Thanks
Kurt

Wire Library Problem

Hi,

I am using the i2c port to connect some sensors, but in some case, it does not work right!

After many investigations on the communication protocol and testing with different sensors, I find it out that it because the Wire library for cm9.04 is not using an actual hardware i2c and it's just a software i2c protocol implementation. So, in case of the i2c modules only support 400kHz frequency, the soft i2c communication is not working.
In this regard, I find the wire library from Maple Mini that it is using the actual i2c hardware. My suggestion is to use that lib for the OpenCm9.04 as well. It supports 400Khz communication also. :)

Git is showing me some strange errors?

Not sure if this is the right place for this and/or is this an issue with my local machine and/or with your git project.

When I tried to Sync up to the develop branch, either just my simple clone of your project or if I try to fetch upstream for my fork/clone to update to recent stuff. I have found that github for windows will appear to hang and when I did the fetch upstream from command prompt it took a long long time and then gave me this message:

D:\GitHub\OpenCM9.04>git fetch upstream
remote: Counting objects: 48, done.
remote: Compressing objects: 100% (32/32), done.
remote: Total 48 (delta 15), reused 43 (delta 11), pack-reused 0
Unpacking objects: 100% (48/48), done.
error: cannot lock ref 'refs/remotes/upstream/develop': is at 3e82af723dbbd4373600e6c3c4b9fe96056a1313 but expected 2d052eb45614d6467a722e13a46fd43bb4c11aaa
From https://github.com/ROBOTIS-GIT/OpenCM9.04
 ! 2d052eb..3e82af7  develop    -> upstream/develop  (unable to update local ref)
error: cannot lock ref 'refs/remotes/upstream/master': is at 4ffa401488ba90f9940e90452375d23f3a5a6828 but expected 13d8087a3cb5693c2a01c63e0f1a3bfeca1b34b5
 ! 13d8087..4ffa401  master     -> upstream/master  (unable to update local ref)
 * [new tag]         1.2.0      -> 1.2.0

D:\GitHub\OpenCM9.04>

And I unfortunately only know GIT well enough to be dangerous ;)

Suggestions?

Pull Requests: develop branch what files need to be updated in ...opencm904_release?

Again sorry in advance. You probably have already answered this.

I am looking to maybe issue a new Pull request for some of the Serial updates and again wondered what files need to be updated in the opencm9.04_release directory. I know that the lib_f103.a file needs to be updated. But I also thought all updated header files? What about Library source files? and the like.

What about if I created a keywords.txt (I have), which include some of the things that are not currently showing up as special things in the arduino ide?

Currently mine looke like:

# OpenCM specific functions
printf	KEYWORD2
flushRx	KEYWORD2
transmitterEnable	KEYWORD2
setDxlMode	KEYWORD2
getBaudRate	KEYWORD2
getRxCnt	KEYWORD2
getTxCnt	KEYWORD2

# Arduino constants

# advanced pin states
OUTPUT_OPEN	LITERAL1
INPUT_PULLDOWN	LITERAL1
INPUT_ANALOG	LITERAL1

(The transmitterEnable is new in my stuff)

I tried running WinMerge to see which files are different. First on my current code and updated all of the header files I had changed, But there are several other files I have not touched, so I looked at the files in my clone of your fork/branch and it too shows several files different.

Things like UARTClass.h, variant.h drv_uart.h , but in addition there are other source files, like:
port_handler_arduino.cpp, variant.cpp, that is also different,

And many of the example sketches where mostly the changes are changing the comment about
changing comments:
http://support.robotis.com/ -> http://emanual.robotis.com/

But also a few with actual changes.

So mainly just wondering which types of these files should be updated with a Pull request.

Thanks
Kurt

Arduino builds on linux arm boards (RPI, ODroid, ...)

Sometimes I find it convenient to be able to do simple Arduino builds for boards like the OpenCM board while it is plugged into an ARM based SBC, like the RPI3 and the Odroid XU4 or...

You can install Arduino to run on these boards, and you can follow the instructions to install the OpenCM board.

Yes I know that these boards are a lot slower to build on, but sometimes it beats having to dig in to where the OpenCM board is, unplug it, move it to your PC (Windows, Linux, MAC...), reprogram it, than move it back to the SBC.

Note: Most of the time I do the builds using the GUI. I start up a VNCServer on the RPI3 in this case, then open a viewer on my PC...

Today I tried this, and the compile worked, but the download fails.

Using library DynamixelSDK at version 0.0.1 in folder: /home/kurt/.arduino15/packages/OpenCM904/hardware/OpenCM904/1.1.0/libraries/DynamixelSDK 
Sketch uses 77004 bytes (65%) of program storage space. Maximum is 116736 bytes.
Global variables use 11204 bytes of dynamic memory.
/home/kurt/.arduino15/packages/OpenCM904/tools/opencm_tools/0.0.2/linux/opencm9.04_ld /dev/ttyACM0 57600 /tmp/arduino_build_790505/OpenCM_Servo_Controller.ino.bin 1 opencm 
An error occurred while uploading the sketch
/home/kurt/.arduino15/packages/OpenCM904/tools/opencm_tools/0.0.2/linux/opencm9.04_ld: 1: /home/kurt/.arduino15/packages/OpenCM904/tools/opencm_tools/0.0.2/linux/opencm9.04_ld: Syntax error: end of file unexpected

It is trying to run the standard intel 32 bit linux image...

Assuming you can get this to work, the next thing that would be great is if it also worked with the command line invocation of Arduino (GUI not required), than can setup to build over a putty command line.

EEPROM Writes - Too many EEPROM.write() can crash board - needs recovery...

While testing, my memory reduction code, with EEPROMs, I thought I should try to verify that EEPROM still worked. So I tried a simple program to write to all memory locations and then try to read them back. When I ran it, it hung and the board become totally unresponsive. If you reset the board, it will not run. You need to do a firmware recovery to reuse the board.

I tested this on the released version of OpenCM9.04 Arduino release and it had the same problem... Note: if I have the test case only output 64 items in the run it appears to work, but if you reboot and try again, reboot... on the 4th run it will die the same way.... Right now I have it configured to try to output 256 items and it does it in the first run.

#define MAX_INDEX 256
#include <EEPROM.h>
void setup() {
  // put your setup code here, to run once:
  while (!Serial) ;
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  Serial.println("EEPROM Test");
  // lets try writing to EEPROM
  uint16_t max_index = EEPROM.length();
  if (max_index > MAX_INDEX) max_index = MAX_INDEX;
  Serial.printf("EEPROM length: %d Max Test: %d\n", EEPROM.length(), max_index);
  uint32_t start_time = micros();
  for (uint16_t i = 0; i < max_index; i++) {
    EEPROM.write(i, i & 0xff);
  }
  Serial.printf("Write time: %d\n", micros() - start_time);
  Serial.println("Start read back");
  start_time = micros();
  for (uint16_t i = 0; i < max_index; i++) {
    uint8_t b = EEPROM.read(i);
    if (b != (i & 0xff)) {
      Serial.printf("Read mismatch: %d %x!=%x\n", i, b, i & 0xff);
    }
  }
  Serial.printf("Read time: %d\n", micros() - start_time);
}

void loop() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  delay(250);
 }

I then instrumented the EEPROM code in drv_eeprom.c

static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
{
  HAL_StatusTypeDef flashstatus = HAL_OK;
  uint16_t validpage = PAGE0;
  uint32_t address = EEPROM_START_ADDRESS, pageendaddress = EEPROM_START_ADDRESS+PAGE_SIZE;
  vcp_printf("EEVPFWV %x %x ", VirtAddress, Data); vcp_flush_tx();;

  /* Get valid Page for write operation */
  validpage = EE_FindValidPage(WRITE_IN_VALID_PAGE);

  /* Check if there is no valid page */
  if (validpage == NO_VALID_PAGE)
  {
    vcp_printf("NO_VALID_PAGE\n"); vcp_flush_tx();
    return  NO_VALID_PAGE;
  }

  /* Get the valid Page start address */
  address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(validpage * PAGE_SIZE));

  /* Get the valid Page end address */
  pageendaddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((validpage + 1) * PAGE_SIZE));

  vcp_printf(" PAGE%d %x %x ", (validpage==PAGE0)? 0 : 1 , address, pageendaddress); vcp_flush_tx();
  /* Check each active page address starting from begining */
  while (address < pageendaddress)
  {
    /* Verify if address and address+2 contents are 0xFFFFFFFF */
    if ((*(__IO uint32_t*)address) == 0xFFFFFFFF)
    {
      /* Set variable data */
      vcp_printf(" HFP %x %x %x  ", FLASH_TYPEPROGRAM_HALFWORD, address, Data); vcp_flush_tx();
      flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, Data);
      /* If program operation was failed, a Flash error code is returned */
      if (flashstatus != HAL_OK)
      {
        vcp_printf(" fail %x\n", flashstatus); vcp_flush_tx();

        return flashstatus;
      }
      /* Set variable virtual address */
      vcp_printf(" HFP %x %x %x  ", FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress); vcp_flush_tx();
      flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address + 2, VirtAddress);
      /* Return program operation status */
      vcp_printf(" status %x\n", flashstatus); vcp_flush_tx();
      return flashstatus;
    }
    else
    {
      /* Next address location */
      address = address + 4;
    }
  }

  /* Return PAGE_FULL in case the valid page is full */
  vcp_printf("PAGE_FULL\n"); vcp_flush_tx();
  return PAGE_FULL;
}

I recovered the firmware and ran the test again, with this stuff and it spewed the data...

EEPROM Test
EEPROM length: 512 Max Test: 256
EEVPFWV 0 0  PAGE0 801f800 801fbff  HFP 1 801f804 0   HFP 1 801f806 0   status 0
EEVPFWV 1 1  PAGE0 801f800 801fbff  HFP 1 801f808 1   HFP 1 801f80a 1   status 0
EEVPFWV 2 2  PAGE0 801f800 801fbff  HFP 1 801f80c 2   HFP 1 801f80e 2   status 0
EEVPFWV 3 3  PAGE0 801f800 801fbff  HFP 1 801f810 3   HFP 1 801f812 3   status 0
EEVPFWV 4 4  PAGE0 801f800 801fbff  HFP 1 801f814 4   HFP 1 801f816 4   status 0
EEVPFWV 5 5  PAGE0 801f800 801fbff  HFP 1 801f818 5   HFP 1 801f81a 5   status 0
EEVPFWV 6 6  PAGE0 801f800 801fbff  HFP 1 801f81c 6   HFP 1 801f81e 6   status 0
EEVPFWV 7 7  PAGE0 801f800 801fbff  HFP 1 801f820 7   HFP 1 801f822 7   status 0
EEVPFWV 8 8  PAGE0 801f800 801fbff  HFP 1 801f824 8   HFP 1 801f826 8   status 0
EEVPFWV 9 9  PAGE0 801f800 801fbff  HFP 1 801f828 9   HFP 1 801f82a 9   status 0
EEVPFWV a a  PAGE0 801f800 801fbff  HFP 1 801f82c a   HFP 1 801f82e a   status 0
EEVPFWV b b  PAGE0 801f800 801fbff  HFP 1 801f830 b   HFP 1 801f832 b   status 0
EEVPFWV c c  PAGE0 801f800 801fbff  HFP 1 801f834 c   HFP 1 801f836 c   status 0
EEVPFWV d d  PAGE0 801f800 801fbff  HFP 1 801f838 d   HFP 1 801f83a d   status 0
EEVPFWV e e  PAGE0 801f800 801fbff  HFP 1 801f83c e   HFP 1 801f83e e   status 0
EEVPFWV f f  PAGE0 801f800 801fbff  HFP 1 801f840 f   HFP 1 801f842 f   status 0
EEVPFWV 10 10  PAGE0 801f800 801fbff  HFP 1 801f844 10   HFP 1 801f846 10   status 0
...
EEVPFWV f7 f7  PAGE0 801f800 801fbff  HFP 1 801fbe0 f7   HFP 1 801fbe2 f7   status 0
EEVPFWV f8 f8  PAGE0 801f800 801fbff  HFP 1 801fbe4 f8   HFP 1 801fbe6 f8   status 0
EEVPFWV f9 f9  PAGE0 801f800 801fbff  HFP 1 801fbe8 f9   HFP 1 801fbea f9   status 0
EEVPFWV fa fa  PAGE0 801f800 801fbff  HFP 1 801fbec fa   HFP 1 801fbee fa   status 0
EEVPFWV fb fb  PAGE0 801f800 801fbff  HFP 1 801fbf0 fb   HFP 1 801fbf2 fb   status 0
EEVPFWV fc fc  PAGE0 801f800 801fbff  HFP 1 801fbf4 fc   HFP 1 801fbf6 fc   status 0
EEVPFWV fd fd  PAGE0 801f800 801fbff  HFP 1 801fbf8 fd   HFP 1 801fbfa fd   status 0
EEVPFWV fe fe  PAGE0 801f800 801fbff  HFP 1 801fbfc fe   HFP 1 801fbfe fe   status 0
EEVPFWV ff ff  PAGE0 801f800 801fbff PAGE_FULL
EEVPFWV ff ff  PAGE1 802f800 802fbff 

So it died/hung when it transitioned from Page 0 to Page 1. Wonder if Page 1 is valid?

Time to debug...

I wish Serial.flush() was implemented...

Like was done for OpenCR in the Issue:
ROBOTIS-GIT/OpenCR#92

While trying to debug another issue, later Serial.prints did not show up to the debug terminal as the system faulted as the user was calling through a NULL pointer.

Side note: Wish list. Wish that when the processor does fault like this, that maybe the fault handler tried to do some similar things to what Teensy tries to do and that is to try to service Serial (both USB and some of the HardwareSerial interrupts, such that maybe any pending messages print out.

barebones USART3 corrupts data at 1mbit

I've got an issue with comunicating with AX-12a trough USART3. When a baud rate is 115200 get the right data, but when I change the baud to 1mbit(for ax-12a) then I get corrupted data...

Serial1.flush() - I believe is doing the old behaviour and output buffers?

Prior to Arduino 1.0, Serial1.flush() would throw away all of the buffered input.

Where as after that Serial1.flush() would wait for all buffered output to fully go out the device as you can see in the Arduino reference: https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/

Looking at the Sources:
UARTClass.cpp:

void UARTClass::flush( void )
{
  drv_uart_flush(_uart_num);
}

Which if you look in drv_uart.c you see:

void drv_uart_flush(uint8_t uart_num)
{
  if(is_uart_mode[uart_num] == DRV_UART_IRQ_MODE)
  {
    drv_uart_rx_buf_head[uart_num] = 0;
    drv_uart_rx_buf_tail[uart_num] = 0;
  }
  else
  {
    drv_uart_rx_buf_head[uart_num] = DRV_UART_RX_BUF_LENGTH - hdma_rx[uart_num].Instance->CNDTR;
    drv_uart_rx_buf_tail[uart_num] = drv_uart_rx_buf_head[uart_num];
  }
}

Note: reading through sources, I am unsure if you need a new Arduino flush behavior?
That is typically on Arduino if you do something like:

Serail1.write(0);
or
Serial1.write(Buffer, cnt);

The call would the majority of time simply put the data into an output buffer and return immediately. The exception, is if you tried to write more data into the queue than what would fit, in which case the call would not return until enough data was sent that the last parts of your write would fit into buffer.

That is why some platforms have also added call: Serial1.availableForWrite(), which would give you the current free space on the output buffer, such that you could than write less than that and know you were not going to block.

The reason I noticed this was looking at DynamixelSDK port_handler_arduino.cpp at:

int PortHandlerArduino::writePort(uint8_t *packet, int length)
{
  int length_written;

  setTxEnable();

#if defined(__OPENCR__)
  length_written = DYNAMIXEL_SERIAL.write(packet, length);
#elif defined(__OPENCM904__)
  length_written = p_dxl_serial->write(packet, length);
#endif

  setTxDisable();

  return length_written;
}

The setTxEnable() and setTxDisable(), just set the appropriate IO port for the correct direction. So was unclear how the underlying call p_dxl_Serial->write on who waited for the underlying call:
Serial1.write(packet, length) to complete...

Not sure how much should change here... But for example I do have code that does use things like:

Serial1.print(....)
Seriall1.flush(); // wait for data output to complete..

EDIT: noticed you do have Serial1.availableForWrite, but not sure it is correct?

int UARTClass::availableForWrite(void)
{
  return drv_uart_tx_available(_uart_num);
}

Where:

uint32_t drv_uart_tx_available(uint8_t uart_num)
{
  uint32_t length;


  length = DRV_UART_RX_BUF_LENGTH - drv_uart_available(uart_num) - 1;

  return length;
}

Which appears to be dealing with RX queue, not the TX...

USB Serial: See what Baud rate the host is asking for....

There are times when a sketch would want to know which baud rate the usb host asks for. Example the Dynamixel Manager and R+ Manager sets the host baud rate, which I assume the default OpemCM9.04 firmware uses to set the DXL baud rate...

Another example the example program c_Serial_Serial2_Converter program, would be a lot more functional if it could change the Serial2 Baud rate on the fly to whatever the host says it wants...

It is currently possible to do this: The base code already receives the CDC_SET_LINE_CODING message and saves the desired baud rate into the variable: LineCoding.bitrate

So for example the Serial to Serial2 converter can today do this, maybe looking something like:

#define BAUDRATE 57600
extern USBD_CDC_LineCodingTypeDef LineCoding;
uint32_t g_baud_rate = BAUDRATE;
void setup(){
  Serial.begin(115200);
  Serial2.begin(BAUDRATE );
  pinMode(BOARD_LED_PIN, OUTPUT);
}

void loop(){
  if(Serial.available()){
    Serial2.print((char)Serial.read());//send data coming from USB to Serial2
  }

  if(Serial2.available()){
    toggleLED();
    Serial.print((char)Serial2.read()); //send data coming from Serial2 to USB(PC)
  }
  // See if the host asked to change baud rates
  if (LineCoding.bitrate != g_baud_rate) {
    g_baud_rate =LineCoding.bitrate;
    Serial2.begin(g_baud_rate);
  }
}

Warning, I typed the changes in on the fly, so may not be 100% correct, but do have simple DXL forwarder with this, which is switching baud rates.

While the above works, I might suggest making it easier to do.
That is currently if you do:

    Serial.print("USB Serial Baud: ");
    Serial.println(Serial.getBaudRate(), DEC);

Currently getBaudRate simply returns the value usb_cdc_bitrate
Which I found a an extern definition for this variable and some binary file...

When I tried printing this value out, it returned the value 536891392, which is 0x20005000.

Maybe would be better if getBaudRate returned the value from LineCoding.bitrate.

Using OpenCM9.04 + Exp 485 boards to communicate directly with ROS

Hello,

I'm currently having problems to communicate the OpenCM9.04 + EXP 485 boards with the dynamixel_workbench ROS package. I can detect the motors fine using the find_dynamixel script with Arduino IDE, but the ROS package node can't find any motors.

https://i.imgur.com/kOls0X9.png

https://i.imgur.com/q6LSFJS.png

I tried to use the script below to send communication from Serial (USB) over Serial3 (OpenCM 485) but ROS package still hasn't detected any motors:

#define CMD_PORT Serial   // USB
#define DXL_PORT Serial3  // UART1
#define DXL_BAUD 1000000

void setup() {
  CMD_PORT.begin(115200);
  DXL_PORT.begin(DXL_BAUD);
}

void loop() {
  update_dxl();
}

void update_dxl() {
  // USB TO UART1
  if (CMD_PORT.available()) {
    DXL_PORT.print((char) CMD_PORT.read());
  }

  // UART1 to USB
  if (DXL_PORT.available()) {
    // toggleLED();
    CMD_PORT.print((char) DXL_PORT.read());
  }
}

Is there any usb_to_dxl script that I can use with the OpenCM9.04 + EXP 485 boards to communicate directly with ROS?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.