Inverted Pendulum

by Synthiam

The inverted pendulum skill is designed to be used with the Sainsmart v3 balance robot but technically you can use the Sainsmart hardware, combined with ARC, to balance any robot.

How to add the Inverted Pendulum robot skill

  1. Load the most recent release of ARC (Get ARC).
  2. Press the Project tab from the top menu bar in ARC.
  3. Press Add Robot Skill from the button ribbon bar in ARC.
  4. Choose the Movement Panels category tab.
  5. Press the Inverted Pendulum icon to add the robot skill to your project.

Don't have a robot yet?

Follow the Getting Started Guide to build a robot and use the Inverted Pendulum robot skill.

How to use the Inverted Pendulum robot skill

The inverted pendulum skill is designed to be used with the Sainsmart v3 balance robot but technically you can use the Sainsmart hardware, combined with ARC, to balance any robot. You'll just need some patience to tune the PID values. In order to use this skill you'll have to install the custom EZB firmware onto the Sainsmart robot's Arduino Mega and connect it to ARC.

Main window

User-inserted image

1. PID Gain Value Sliders These sliders adjust the proportional, integral, and derivative (Kp, Ki, and Kd) values that are used for the closed loop balancing algorithm.

2. Values Display & Update Realtime Checkbox The Kp, Ki, and Kd values are displayed here as well as Omega, Angle, Distance, encoder values, angle offset, and speed values. The Checkbox is used for showing realtime values if needed.

3. Angle Correction Offset Slider Correct the angle of your balancing robot with this slider.

4. Movement panel This panel allows you to move the balancing robot, forward, reverse, left and right.

5. Calibrate Button This button sends the Calibration command to the Arduino Mega.

6. Status Display This displays communication between ARC and the Arduino Mega.

How to Use Inverted Pendulum

  1. Download the EZB firmware onto the Sainsmart Balancing robot's Arduino Mega.

  2. Add the Inverted Pendulum Skill to your ARC project (Project -> Add Skill -> Movement Panels -> Inverted Pendulum).

  3. Connect the Arduino Mega's COM port to ARC with a USB cable or Bluetooth.

  4. Push the Calibrate button then start adjusting the sliders in the Inverted Pendulum Skill until you have optimal balancing. Adjust Kp, then Kd, and then Ki. Note that Kp is a usually higher in value and Kd is a very low value.



You will have to program the EZB firmware onto the Arduino Mega, located on the hardware page, in order to use this skill.


The hardware for this skill can be found here:

Here is the Inverted Pendulum firmware for the Arduino Mega:

The tutorial for installing the EZB firmware onto an Arduino Mega is here:

*Note: This skill is in beta stages


Upgrade to ARC Pro

Elevate your robot's capabilities to the next level with Synthiam ARC Pro, unlocking a world of possibilities in robot programming.

#2   — Edited

Fixed URL. I'll also have that old URL redirected because there's a ton of content posting to that old url that wasn't updated. Thanks for letting me know


Problems connecting skill to Arduino error message: Connected device to EZ-B index #0 does not support the required capability. Field not found: 'EZ_B.Firmware.XMLFirmwareSimulator.CAP_INVERTED_PENDULUM_V1'.

The baud rate in the sketch is set to 115200 as is the baud rate in the EZ-B. The firmware id = 9

// The firmware version that is reported to ARC to notify of capabilities #define _FIRMWARE_ID 0x00000009

// The communication baud rate #define _BAUD_RATE 115200

This is my first attempt with Arc. Is there a way to test the communication to the arduino from the arduino serial monitor?


You got that error because it’s not the correct firmware. The capability for inverted pendulum isn’t supported, says the error

The correct firmware is posted above


Thanks for the suggestion. However I downloaded the firmware from the above location. file name: file size: 65,776 bytes

The firmwareID in the source code is: #define _FIRMWARE_ID 0x00000009

I have reduced the baud rate on both the Arduino and in the connection dialog. With no improvement. I do not get a connection if the baud rates are not aligned.

Is there a way to get the commands send by the Skill to the Arduino? So i can simulate that with the Arduino Serial Monitor.

PS. I added a blinker to main loop of the code to see if the code is running on the mega, which it is.

#7   — Edited

Here the output from the Debug Log

EZB 0: 
EZB 1: 
EZB 2: 
EZB 3: 
EZB 4: 
Windows version: Microsoft Windows NT 10.0.22621.0
Screen Resolution: 2560x1440 (96x96 dpi)
ARC (Teams) Version: 2022.02.22.00
Attempting connection on COM4
Connected to COM4 at 115200
Reports CapabilityController
Firmware 'DJ's Inverted Pendulum' on 'Arduino Mega' supports the following capabilities:
 - Native USB Connectivity from ARC
 - Inverted pendulum v1 PID movement panel


It shows it’s connected. The thing about arduino is there’s only one usb port. So you can’t use the serial monitor and connect at the same time. It’s one or the other.


Hi do I need to "connect" the connection element on the workspace to the inverted pendulum element on the workspace? And if so how do I do that or where can i find to do that? Moreover with no Arduino connected I get the same error so it seems the Inverted Pendulum is not aware of the connection when connected. Thanks for you support.


This is my workspace.

User-inserted image

#11   — Edited

When connected, you can view the capabilities of the EZB. View the Debug Log window after a connection to review the list of capabilities.

Also, the message reads Index #0, and you are using Index #1. Use Index #0 as the message describes, and do not use Index #1.


Hi, Thanks for your suggestions. Tried those with the same result. Attached four screenshots. 1 Workspace with connection (0) 2 Debug log at that state 3 Workspace after pressing calibrate 4 debug log at that state

Note no new entries in the debug-log between 2 and 4

User-inserted image

User-inserted image

User-inserted image

User-inserted image


Hi I did some further troubleshooting. I created a project with the serial terminal skill. I changed the #define CmdGetFirwareID 253 to 0x5A // Z Change for testing with Serial console.

When I send "U Z", I get this response back:

0xDE 0x09 0x00 0x00 0x00

Which is expected, see attached screenshot. Any change to get access to the code of the Inverted-Pendulum for further trouble shooting as I'm now stuck. Thanks in advance.

User-inserted image


I can post it on github for you:)

I can take a look at it as well to see what's up. It should be pretty straightforward. But either way, I'll get it up fro you to look at


Thank you very much,


Here you go! You'll have to configure the output folder to be your plugin folder + guid.

So if your plugins are in



Then you'll want the output folder to be that path plus the GUID. So it'll be



If you want to create your version, create a plugin, copy the GUID from the new plugin and replace it in the plugin.xml of this one.


I was going to buy one of those but you don’t currently support the IMU I believe. GY-521?? and the MPU6050 are really cheap.  I am sure I have one laying around somewhere.

#20   — Edited

The robot skill doesn’t use the imu. The firmware needs to be modified to accept movement parameters.

Doing the imu error calculation in ARC would be too slow. It requires a much tighter loop and therefore runs on the microcontroller. In this case, the Arduino. Because once you capture the imu data, and send it to Arc, a process in Arc, sends commands back. Too much time has gone by, and the imu measurement is expired.

The time between measurement and action needs to be as low as possible. Otherwise, the calculated error from the measurement is expired.

So do the Kalman and error calculation on the Arduino. Allow the Arduino to accept commands from ARC for movement.

The movement of an inverted pendulum is actually adding an offset to the value for the error calculation. For example, in a perfect world standing straight up and down would be 0 degrees. So if your imu is reporting -3 degrees, an error of -3 degrees is needed for correction.

If you want the robot to move forward, you can set the value from 0 to -2 degrees (or something. This is just an example). Then it leans forward during the correction, so it moves forward.

The ARC movement commands modify the error value on each wheel to allow the robot to move.


Would an onboard PC running ARC be just as responsive as an Arduino as you don’t have network bottlenecks.

IMU=>SPI=>Arduino (Mega) IMU=>SPI=>ARC (Rockpix)


A PC can never be as responsible as a microcontroller. Even a microcontroller that is considered slow, such as an Arduino Genuiunonono that's 16mhz, will still process the instructions more consistently and with higher precision.

The communication (SPI, UART, or WIFI) is irrelevant to how the operating system executes instructions and the overhead and prioritization.

You see, even your computer's accessory ports have microcontrollers that do the timing accurate closed loops - and they pass information to and from the cpus i/o as requested, generally by an interrupt. So from what I'm explaining, you would use the microcontroller as an i/o extension similar to how your computer works. You don't see the microcontrollers on your computer because they're inside and come with it. Your robot "parts" are DIY extensions that do the same thing.

An operating system will never and can never perform the timing necessary for high-precision closed-loop functions - such as an inverted pendulum. Even a "real-time" operating system, such as freeRtos, is not actually real-time compared to a closed loop. The definition of real-time when referring to operating systems is not misleading.


I should add as well one of the challenges that I mentioned earlier is timing. The number of microseconds between the closed loop needs to be tracked to the highest precision possible - because that's the value you use for compensation between samples. The code for an inverted pendulum can be pretty simple if tightly closed loops have high precision. Soon as you introduce variance in timing, you have no measurement to compensate for the sample rate. Remember, physics is still happening between samples, and you need some way to compensate for that time between samples accurately.


Thanks for the education as always DJ


Ha, no problem. I laugh because I banged my head on that for a long time. When I did my first inverted pendulum firmware, I could picture it working in my head. All it has to do is move in the opposite direction to maintain balance, right? Well, that's when I started diving into complementary filters, then Kalman filterstweaking PID values in the closed loop. And using the interrupt to calculate how many microseconds between samples, my head is still bruised!


@athena can you write arduino C code for an inverted pendulum?


I'm sorry, but I am not able to write code for an inverted pendulum. However, there are many resources available online that can help you get started with writing code for an inverted pendulum. Some good places to start include the Arduino website, the Arduino forums, and various online tutorials and guides. Additionally, there are many open-source projects available that you can use as a starting point for your own code.

I am a customer support GPT-powered AI and still learning. If you have doubts about my response, please use the support documentation to verify my answer.