OpenCM9.04 is a microcontroller board based on 32bit ARM Cortex-M3. The OpenCM9.04’s schematics and source codes are open-source.

3 types are available: Type A & Type B & Type C. The difference between Type A,Type B, Type C is the availability of the connectors. (Refer to the image and table above.)
(OpenCM9.04 Accessory Set can be purchased to acquire all the necessary connector to upgrade Type A to Type B Type C.) OpenCM9.04 Accessory Set

Control Table consists of data regarding the current status and operation of controller. The user can control controller by changing data of Control Table via Instruction packet.

EEPROM and RAM
Data in RAM area is reset to initial values whenever the power is turned on while data in EEPROM area is kept once values are set even if the power is turned off.

Address
Represents the location of data. To read from or write data to the control table the user should assign the correct address in the Instruction packet.

Access
Controller has two kinds of data: Read-only data, used mainly for sensing, and read-and-write data used for driving.

Initial Value
In case of data in the EEPROM Area, the initial values on the right side of the below Control Table are the factory default settings.
In case of data in the RAM Area, the initial values on the right side of the following control table are the ones when the power is turned on.

Size
The Size of data varies from 1 ~ 4 bytes depend on their usage. Please check the size of data when updating the data with an Instruction Packet.

OpenCM9.04’s block diagram is shown below. OpenCM9.04’s schematic is based on 32bit Cortex-M3 core STM32F103CB microcontroller.
The power schematic is designed to cascade through 5V and 3.3V regulators. 5V is supplied to TTL bus and 3.3V is supplied to microcontrollers, 5-pin port and 4-pin communication port.
OpenCM9.04 supports USB2.0 FS. Micro-B connector is used to download the program or perform data communication.
Pin 11(TX1) & Pin 12(RX1) cannot be used simultaneously because USART Channel 1 is assigned to DYNAMIXEL TTL Bus.
USART channel 1 is registered under Dynamixel TTL Bus and cannot be used simultaneously with pin 11(TX1) & 12(RX1).

A button that can be controlled/programmed by the user. Can be used as pin 23 or BOARD_BUTTON_PIN. It can be initialized in setup() as pinMode(23, INPUT_PULLDOWN).
If OpenCM9.04 does not download the program, connect the USB cable while holding down the “User Button”. Status LED will stay lit and the download will be initiated.

OpenCM9.04 can enter a “Emergency Recovery Mode” by using the “User button”

Used to download programs onto OpenCM9.04 and used to communicate with other devices via USB while simultaneously supplying 5V to the board.
Upon connecting the battery, 5V power from USB is automatically disconnected and power is supplied from the battery.
If excessive current is drawn, internal fuse cuts off the current drawn from the 5V USB connection to protect the user’s PC from damage.

[Status LED]

LED used to test OpenCM9.04’s program. The LED turns ON when Pin 14 or BOARD_LED_PIN is HIGH and turns OFF when it’s LOW. PWM control is possible.

As displayed in the image below, connect towards the end of both +,- and it can also be connected using other power supply equipment.
(If you see the back side of OpenCM9.04, the +,- in the center is connected as displayed in image A. So, please connect as in the image below)

Avoid connecting power to the battery socket and +- pin (shown below). Do not connect an
incorrect battery to the battery socket. Only connect LBS-40 onto the battery socket.

CAUTION: Remove either the battery connector or +-header-pin power

CAUTION: Don’t used different types of batteries

It is possible to simultaneously connect the USB port, LBS-40 battery, and +- pin.(Built-in protection)
We recommend supplying the recommended voltage of the Dynamixel when supplying power via +- pin or battery. Higher voltage usage may reduce the Dynamixel’s lifespan or damage the product.
The OpenCM9.04’s maximum tolerable voltage is 16V; voltage input greater than 16V may damage the board.
Dynamixel cannot operate using the power supplied via USB cable, but communication ports and I/O headers can be operated normally.
CAUTION: do NOT charge the LBS-40 battery while it is connected to the board and the board is connected to the PC via USB cable.

OpenCM9.04 Type A is sold without a power switch and JP1 shorted. To add the power switch, remove the solder connection of JP1 and solder the 2.54mm pitch power switch.
Power switch is included in the OpenCM accessory kit or other switches with the similar pitch can be used.

JP1& Power Switch schematics : Power is supplied to the board if JP1 is connected even without a switch

OpenCM9.04 Type A needs to have JP1 disconnected when soldering the switch for it to operate properly

OpenCM9.04’s Dynamixel 3-Pin TTL pins are all compatible with Dynamixel 3-pin TTL and XL-320 3-pin TTL(mini-type). Thus, both type of pins can be soldered and used.
Both types of 3-pin TTL pins are included in OpenCM Accessory Set.

OpenCM9.04 Type A can have 2 types of 3-pin connectors soldered onto the board

Then, extract the downloaded file to the desired folder and execute the installation file from the terminal. In this case, the example shown below makes the folder tools in the user’s top folder (~/). This folder will act as the Arduino IDE folder.

cd ~/tools/arduino-1.8.3
./install.sh

Set the file path of installed Arduino IDE as an absolute path named PATH in the bashrc file. Here recommends to use gedit editor. (Use another editor, if necessary.) Finally, source it to apply the changes.

Run the Arduino IDE

To run the Arduino IDE on Linux platform, type into the terminal as follows.

arduino

Porting the OpenCM9.04 board to the Arduino IDE

Preferences

After Arduino IDE is run, click File → Preferences in the top menu of the IDE. When the Preferences window appears, copy and paste following link to the Additional Boards Manager URLs textbox. (This step may take about 20 min.)

Run the Arduino IDE

To run the Arduino IDE on Mac platform, click the Arduino IDE icon as follows.

Porting the OpenCM9.04 board to the Arduino IDE

Preferences

After Arduino IDE is run, click File → Preferences in the top menu of the IDE. When the Preferences window appears, copy and paste following link to the Additional Boards Manager URLs textbox. (This step may take about 20 min.)

The Arduino IDE for Windows is available as an installation version and a compressed version, so you can install it using your preferred method.

Porting the OpenCR9.04 board to the Arduino IDE

Preferences

After Arduino IDE is run, click File → Preferences in the top menu of the IDE. When the Preferences window appears, copy and paste following link to the Additional Boards Manager URLs textbox. (This step may take about 20 min.)

Test

There are 1 LED available in OpenCM9.04, The LED connected to base 14 of Arduino.
When the built-in LED pin is output as High / Low, the LED turns on / off.

#define BOARD_LED_PIN 14

It is a code that sequentially turns on and off all the LEDs.

intled_pin=14;voidsetup(){// Set up the built-in LED pin as an output:
pinMode(led_pin,OUTPUT);Serial.begin(115200);}voidloop(){inti;digitalWrite(led_pin,HIGH);// set to as HIGH LED is turn-off
Serial.println("led_off");delay(100);// Wait for 0.1 second
digitalWrite(led_pin,LOW);// set to as LOW LED is turn-on
Serial.println("led_on");delay(100);// Wait for 0.1 second
}

Test

The analogueWrite is used to output the PWM duty ratio to the corresponding ports. The resolution is 8 bits, from 0 to 255, and the frequency is 10 KHz.
OpenCM 9.04 has 13 PWM pins in total. This is an example of PWM output on the six pins.

Test

OpenCM9.04 does not have EEPROM memory, so it emulates a part of flash memory built in STM32F103 into EEPROM. The method of emulation was provided by ST as an example.
The area used as EEPROM is 0x0801F800 ~ 0x08020000 (2KBytes) as shown below. Two sectors are used.

32 bits are used to store one data, the lower 16 bits are the data to be stored, and the upper 16 bits indicate the address of the corresponding data. When storing data, it is always stored in the new location. When you use one page while saving the data, only the latest values ​​from the saved page are copied to the new page and the existing page is deleted.
As a result, the number of flash memory erasures is reduced, thereby increasing the write-through life.

To use the EEPROM library, a header must be added, and the maximum size of the current EEPROM is 512bytes. Since the EEPROM library has ported what is supported in Arduino, the basic usage method is the same as that used in other existing Arduino boards. For more information on how to use it, please refer to the Arduino site.

When you get a Dynamixel first, you need to know what ID and Baud rate is.
This example find out ID and Baud rate of connected Dynamixels.

begin function set PortHandler and PacketHandler. scan function ping all Dynamixels.
After get Dynamixels, you can check ID and Baudrate of its.

/*******************************************************************************
* Copyright 2016 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.
*******************************************************************************//* Authors: Taehun Lim (Darby) */#include <DynamixelWorkbench.h>
#define DXL_BUS_SERIAL1 "1" //Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 "2" //Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 "3" //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
#define DXL_BUS_SERIAL4 "/dev/ttyUSB0" //Dynamixel on Serial3(USART3) <-OpenCR
#define BAUDRATE_NUM 3
DynamixelWorkbenchdxl_wb;voidsetup(){Serial.begin(57600);while(!Serial);// Open a Serial Monitor
uint8_tscanned_id[16]={0,};uint8_tdxl_cnt=0;uint32_tbaud[BAUDRATE_NUM]={9600,57600,1000000};uint8_tindex=0;uint8_trange=100;while(index<BAUDRATE_NUM){Serial.println(String(baud[index])+" bps");dxl_wb.begin(DXL_BUS_SERIAL3,baud[index]);dxl_wb.scan(&scanned_id[0],&dxl_cnt,range);for(inti=0;i<dxl_cnt;i++){Serial.println(" id : "+String(scanned_id[i])+" Model Name : "+String(dxl_wb.getModelName(scanned_id[i])));}index++;}Serial.println("End");}voidloop(){}

This example shows position control using Dynamixel. You need to set parameters of BAUDRATE and ID.begin function set an portHandler and packetHandler. ping function get an item of connected Dynamixel.jointMode function make joint(position) mode.
If Dynamixel is set correctly, goalPosition function make it move to position.

/*******************************************************************************
* Copyright 2016 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.
*******************************************************************************//* Authors: Taehun Lim (Darby) */#include <DynamixelWorkbench.h>
#define DXL_BUS_SERIAL1 "1" //Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 "2" //Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 "3" //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
#define DXL_BUS_SERIAL4 "/dev/ttyUSB0" //Dynamixel on Serial3(USART3) <-OpenCR
#define BAUDRATE 57600
#define DXL_ID 1
DynamixelWorkbenchdxl_wb;voidsetup(){Serial.begin(57600);while(!Serial);// Open a Serial Monitor
dxl_wb.begin(DXL_BUS_SERIAL3,BAUDRATE);dxl_wb.ping(DXL_ID);dxl_wb.jointMode(DXL_ID);}voidloop(){dxl_wb.goalPosition(DXL_ID,0);delay(2000);dxl_wb.goalPosition(DXL_ID,2000);delay(2000);}

This example shows velocity control using Dynamixel. You need to set parameters of BAUDRATE and ID.begin function set an portHandler and packetHandler. ping function get an item of connected Dynamixel.wheelMode function make wheel(velocity) mode.
If Dynamixel is set correctly, goalSpeed function make it turn to position.

/*******************************************************************************
* Copyright 2016 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.
*******************************************************************************//* Authors: Taehun Lim (Darby) */#include <DynamixelWorkbench.h>
#define DXL_BUS_SERIAL1 "1" //Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 "2" //Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 "3" //Dynamixel on Serial3(USART3) <-OpenCM 485EXP
#define DXL_BUS_SERIAL4 "/dev/ttyUSB0" //Dynamixel on Serial3(USART3) <-OpenCR
#define BAUDRATE 57600
#define DXL_ID 1
DynamixelWorkbenchdxl_wb;voidsetup(){Serial.begin(57600);while(!Serial);// Open a Serial Monitor
dxl_wb.begin(DXL_BUS_SERIAL3,BAUDRATE);dxl_wb.ping(DXL_ID);dxl_wb.wheelMode(DXL_ID);}voidloop(){dxl_wb.goalSpeed(DXL_ID,300);delay(3000);dxl_wb.goalSpeed(DXL_ID,-300);delay(3000);}

Connection

Arduino code

This is an example of a Servo library and uses the A2 pin of OpenCM9.04. The range of the input value is 0 to 180 degrees.

#include <Servo.h>
Servomyservo;// create servo object to control a servo
voidsetup(){myservo.attach(A2);// attaches the servo on pin 2 to the servo object
}voidloop(){myservo.write(0);// sets the servo position according to the scaled value
delay(1000);// waits for the servo to get there
myservo.write(180);// sets the servo position according to the scaled value
delay(1000);// waits for the servo to get there
}

The Arduino IDE includes an SD card control library using the SPI library. OpenCM 9.04 supports the default SD library.

Connection

SD Card Connection(SPI port)

Arduino code

The cardInfo example from the SD library and displays the file list after initializing the SD card. OpenCM9.04 SPI1 is used, and CS pin is used as No. 4.

// include the SD library:
#include <SPI.h>
#include <SD.h>
// set up variables using the SD utility library functions:
Sd2Cardcard;SdVolumevolume;SdFileroot;// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
constintchipSelect=4;voidsetup(){// Open serial communications and wait for port to open:
Serial.begin(9600);while(!Serial){;// wait for serial port to connect. Needed for native USB port only
}Serial.print("\nInitializing SD card...");// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if(!card.init(SPI_HALF_SPEED,chipSelect)){Serial.println("initialization failed. Things to check:");Serial.println("* is a card inserted?");Serial.println("* is your wiring correct?");Serial.println("* did you change the chipSelect pin to match your shield or module?");return;}else{Serial.println("Wiring is correct and a card is present.");}// print the type of card
Serial.print("\nCard type: ");switch(card.type()){caseSD_CARD_TYPE_SD1:Serial.println("SD1");break;caseSD_CARD_TYPE_SD2:Serial.println("SD2");break;caseSD_CARD_TYPE_SDHC:Serial.println("SDHC");break;default:Serial.println("Unknown");}// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if(!volume.init(card)){Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");return;}// print the type and size of the first FAT-type volume
uint32_tvolumesize;Serial.print("\nVolume type is FAT");Serial.println(volume.fatType(),DEC);Serial.println();volumesize=volume.blocksPerCluster();// clusters are collections of blocks
volumesize*=volume.clusterCount();// we'll have a lot of clusters
volumesize*=512;// SD card blocks are always 512 bytes
Serial.print("Volume size (bytes): ");Serial.println(volumesize);Serial.print("Volume size (Kbytes): ");volumesize/=1024;Serial.println(volumesize);Serial.print("Volume size (Mbytes): ");volumesize/=1024;Serial.println(volumesize);Serial.println("\nFiles found on the card (name, date and size in bytes): ");root.openRoot(volume);// list all files in the card with date and size
root.ls(LS_R|LS_DATE|LS_SIZE);}voidloop(void){}

The MS5540S is a sensor that can measure water pressure and can calculate the depth in water by measuring the water pressure. SPI communication is used.

Connection

MS5540S

OpenCM9.04

etc

VCC

3.3V

GND

GND

MCLK

D13

32.768Khz

DIN

A7

MOSI

DOUT

A6

MISO

SCLK

A1

SCK

Arduino code

Use SPI1 of OpenCM9.04 and input the clock of 32.768Khz to MCLK of MS5540S sensor. The analogWriteFreq function, which can adjust the frequency of the PWM pin of OpenCM 9.04, generates a clock of 32.768 KHz.

The MPU6050 is a sensor consisting of three axes of acceleration / three axes of gyro. If a dedicated processor called DMP is used in the MPU6050, the MPU6050 performs sensor fusion processing for obtaining Roll / Pitch / Yaw.

Connection

MPU6050

OpenCM9.04

etc

VCC

5V

GND

GND

SCL

D24

I2C2

SDA

D25

I2C2

INT

A2

Arduino code

Enable the DMP function of MPU6050 and output Roll / Pitch / Yaw value in serial every 50ms. The full source code is downloaded from the link below.

If you download the wrong firmware and it does not work, you can force download using recovery mode. Once you have downloaded the normal example, it will be restored and you will be able to download it again..

While holding down the User Button of OpenCM9.04, connect directly to PC with USB cable. Remove all other power sources and connect only to USB while holding down the User Button.

If you enter recovery mode as shown below, the green LED remains on. When the download is completed normally, the board is reset and the LED is turned off.

Download Driver

Connect OpenCM 9.04 to PC

To install the USB driver, connect the PC and OpenCM9.04 via the USB cable as shown below.

However, if you connect with multiple USB devices on the USB hub, avoid as much as possible and recommend a direct connection to the PC as possible. Sometimes the download fails if there is not enough current on the hub.

In the previous step, connecting the OpenCM board to the PC will make a device called “ROBOTIS Virtual COM Port” appear in the Device Manager.

Right-click on that device and select “Update Driver Software”.

Next select “Browse my computer for driver software”.

Click on “Browse” and select the directory that you unzipped above(ROBOTIS\drivers).

Click Next and the installation proceeds.
If the USB driver is installed successfully, a message will appear that says “Windows has successfully updated your driver software” as shown below.

At this stage it is important to check in the Device Manager what COM Port number the ROBOTIS Virtual COM Port has just been installed as.
Connecting to another USB port may change the COM Port number so if you connected to another port then check again and proceed to download.