• More human-friendly firmware

    Ville Tiukuvaara06/04/2018 at 03:16 0 comments

    The revision 2 PCBs are have shipped but are expected to arrive on Tuesday, so unfortunately they won't make it for the Hackaday Prize robotics contest deadline. Meanwhile, I've been tweaking the firmware. The firmware is on Mbed, so you can compile it for other supported microcontrollers as well. I've been using the STM32L073 and STM32L476 MCUs, so these at least have the required PWM functionality on the correct pins.

    The EEZYBot ARM MK2 uses three servos to control the arm and a fourth servo for the end effector. The Wii Nunchuck controller has a joystick and two buttons. This essentially allows control of three "axes". Two of these are from the joystick (up/down and left/right) and the third from the two buttons. Originally, my firmware used these three to control the three main servo directly, For example, moving the joystick up/down moved a single servo. This is easy to implement, but it is not very intuitive to use since the end of the arm does not move just horizontally or vertically, but rather along a more complex trajectory.

    I thought it would be nice to be able to press up/down and have the end of the arm move just in the vertical direction. This is a little more complex to implement since it involves moving multiple servos and doing some math to figure out how they need to move. The math is just high school trigonometry, as shown in my sketch below. Essentially, I need to calculate the angles α (the sum of α₁ and α₂) and γ, which can be used to calculate the angles of the main arm (l₁) and the little arm labelled l₂.

    This math is implemented in the pos_to_angle function:

    void pos_to_angle(double *horz_angle, double *vert_angle, double radius, double height)
        double alpha1 = atan(height/radius);
        double bf_2 = radius*radius + height*height;
        double alpha2 = acos((bf_2 + L1*L1 - L5*L5)/(2*sqrt(bf_2)*L1));
        *horz_angle = PI/2 - (alpha1 + alpha2);
        double beta2 = acos((L1*L1 + L5*L5 - bf_2)/(2*L1*L5));
        *vert_angle = PI - beta2 - alpha1 - alpha2;

    I made a quick video to show the firmware in action:

    The firmware first allows you to calibrate, which involves positioning the arm so that the main arm is vertical and the other one is horizontal.  Pressing SWITCH 2 performs the calibration, which saves offsets for each of the servo motors. Note that the firmware is written so that it works with the EEZYBot ARM MK2. To use other robotic arms, you would need to adjust the constants (e.g. l₁) and perhaps the math, if the arm has a different kinematic linkage.

    Actually operating the arm is very intuitive. Up/down on the joystick moves the end effector horizontally. The two buttons on the back move it vertically, and left/right on the joystick rotates the arm around the base. To open/close the end effector, pushing the two buttons simultaneously activates another "mode" where up/down on the joystick now opens/closes the end effector.

    I'm pretty happy with how the project has gone so far. Assuming that the revision 2 PCBs that are shipping fix the issue with the power enable signal, this project will be done!

  • Exported Rev 2 Gerbers

    Ville Tiukuvaara05/29/2018 at 02:25 0 comments

    Gerbers for revision 2 are done. Changes from the first revision are:

    • Changed POW_EN signal to a 5V tolerant pin on the STM32 MCU so that the protection diodes don't clamp the voltage and prevent the PFET from turning off (discussed in the previous log).
    • Made the nunchuck connector a little wider. It was too narrow in the first version and I had to file it down a bit.
    • Moved some of the PWM signals to different pins. The STM32 MCUs are not fully pin-compatible so I chose pins that have PWM available on more MCUs.
    • Added some silkscreen labels for the supply headers (used mainly for debugging).

    The PCB is over at GitHub.

  • Trying out the first PCB

    Ville Tiukuvaara05/19/2018 at 22:29 0 comments

    I got the PCBs in the mail this week and soldered one up using the reflow skillet method. So far, it is mostly working. The main issue that I have come across so far is that the power enable signal, which is pulled up to 5 V, has its gate a few hundred millivolts too low when it should be high, so the PFET that it is controlling does not turn off.

    The PFET turns on the motors when POW_EN is pulled low.

    I am using pin PA4 on the STM32L476 in open drain mode to control it. I thought that this should work, but unfortunately this pin is not a 5 V tolerant pin. Looking at the datasheet, there are protection diodes on the pin that I believe are causing the issue. This means that the power enable signal unfortunately does not work on this revision of the PCB. It should be connected to a 5 V tolerant pin, also called a "TT" pin in the datasheet, such as PA2.

    On a more positive note, the level-shifting circuitry is working. After debugging the above issue I had damaged the top copper layer so I did a messy soldering fix shown below to reconnect the 5V pull-ups. The NFETs convert 3.3V PWM from the micro controller to 5V for the servos. Note that since the FETs are inverting the duty cycle of the PWM signal also needs to be inverted. I was successfully able to move a servo motor, and have started putting together some firmware using the online Mbed compiler. The project is here.

    An ugly fix shorting a pin of R7 to Q2 to R13. This is on the 5 V net. Q2 is useless since it would never turn off anyways.
    The NFETs convert a 3.3 V PWM signal to 5V. You can control up to 6 servos.

    Lastly, I also checked the Nunchuck interface. Unfortunately, the connector is slightly too narrow, so I had to sand it down a bit. But I2C communication worked great using the WiiNunchuck library on Mbed.

  • A Nucleo expansion board for controlling servos

    Ville Tiukuvaara05/05/2018 at 03:38 0 comments

    The EEZYbotARM MK2 that I would like to control.

    I decided to put my Prusa i3 MK2 to use and have been 3D-printing the parts for the EEZYbotARM MK2 robotic arm. This thing uses three larger MG995 or MG946 servo motors, in addition to a smaller plastic SG90 servo for the "grabber" (formally called an "end effector" FYI). Rather than wiring up a some messy circuit or buying something already available, I decided to make a PCB for the job of driving the servo motors. This gave me the opportunity to add something not available on existing solutions: a Wii Nunchuck connector.

    The servo motors are controlled using a PWM signal, and the manufacturer specifies the operating voltage at 4.8 V - 6.6 V. The STM32 Nucleo boards work at 3.3 V, and I have read that a 3.3 V PWM would likely work for driving a servo motor. However, to be safe I have added some FETs to translate the 3.3V PWM to 5 V.

    The PWM signal for another servo motor (this one specified with a voltage up to 7.2 V rather than 6.6 V)
    6 connectors for servo motors

    The board has standard servo connectors (a.k.a. 3-pin 0.254 mm headers) for up to 6 servo motors. There is also a power enable signal that connects the servos to the 5 V supply via a FET with a low on-resistance.

    Lastly, I have added a Wii Nunchuck connector. This is basically just a PCB card edge connector that I duplicated from here. The Nunchuck uses a simple I2C interface, and I am planning to use it to control the robotic arm.

    The Wii Nunchuck connector (J2).

    This PCB is an STM32 expansion board, so it uses the Morpho headers that work with Nucleo boards, similar to how shields work with Arduino. The first layout of the first revision is done and has been sent to get fabricated.