Close

3-DOF Servo Arm v1: Code

A project log for Exploring a 3-DOF Servo Arm

Creating a simple elbow manipulator, and exploring its kinematics & dynamics.

jamie-ashtonJamie Ashton 04/21/2025 at 16:050 Comments

Overview:

This is the code for v1 of the arm, in which it is manually controlled by 3 potentiometers. This code was written in C++ in Mbed Studio as I was using the STM Nucleo-F401RE microcontroller.

Servo Class:

To begin with I searched for an Mbed servo library, ideally one similar to the Arduino library. I found this one by Simon Ford https://os.mbed.com/teams/Biorobotics-Project/code/Servo/ which works very well. 

Potentiometer Class

I then added a basic potentiometer class with basic functionality, I am planning to refine this later especially when I have more going on. 

class Potentiometer //Begin potentiometer class definition
{
private: //Private data member declaration
 AnalogIn inputSignal; //Declaration of AnalogIn object
 float VDD; //Float variable to speficy the value of VDD (3.3 V for the Nucleo-64)
public: // Public declarations

//Constructor - user provided pin name assigned to AnalogIn. VDD is also provided to determine maximum measurable voltage
 Potentiometer(PinName pin, float v) : inputSignal(pin), VDD(v) {}
 float amplitudeVolts(void) //Public member function to measure the amplitude in volts
 {
 return (inputSignal.read()*VDD); //Scales the 0.0-1.0 value by VDD to read the input in volts
 }

 float amplitudeNorm(void) //Public member function to measure the normalised amplitude
 {
 return inputSignal.read(); //Returns the ADC value normalised to range 0.0 - 1.0
 }
};

This is a class from my Microcontroller Engineering II module, studied earlier this year, that I reused.

Pot-Servo Class

As the arm was going to be using minimum 3 servos (we'll get to the end-effector later) I decided to write a class that combined the functionality of the Servo class and the Potentiometer class - PotServo. This allowed me to instantiate each joint and its control as a single object.

class PotServo {
    private:
        Potentiometer pot;
        Servo servo;

    public:
        PotServo(PinName potPin, float vdd, PinName servoPin)
        : pot(potPin, vdd), servo(servoPin) {}

    void update() {
        float position = pot.amplitudeNorm();
        servo.write(position);
    }
};

Main Loop

I only had access to 2 potentiometers, so for the time being I tested the code with just 2 servos.

int main()
{
    PotServo servo1(A0, 3.3, PA_7);
    PotServo servo2(A1, 3.3, PB_6);

    while(true){
        servo1.update();
        servo2.update();
    }   
}

Discussions