Pulse Width Modulation, or PWM for short, is a useful signal used to control servos, electronic speed controllers(ESC) and LED lights. It is an essential arsenal for any roboticist.
This blog will be about my adventures with PWM signalling. Along the way, I sprinkle my pro tips.
I initially assumed that the AIY vision bonnet would do the trick of providing me the two PWM signals that I needed to control the ESC and servo of my RC car. The bonnet supplied 4 GPIO pins and even added a 5V power source. I started using the pigpio library and realized that the PWM signals were very twitchy and noisy.
I decided to go with a Teensy board, but my professor suggested I try checking to see if the vision bonnet had some unused GPIO pins from the RPI 3B board. As luck would have it, I was able to find two PWM pins unused by the vision bonnet which output hardware PWM 0 and 1.
At this point, I will diverge to talk about hardware PWM. There seems to be two main types of PWM signalling, one being software PWM and the other being hardware PWM. I guess software PWM also has many variants which perform better or worse, but I won't go into the details. All that one should know is that hardware PWM is more robust than software PWM in terms of jitter and can output faster frequencies. The downside is that the GPIO port in question must be able to support this hardware PWM functionality.
Luckily, the google guys who maintain the vision bonnet kit github repo kindly answered which GPIO pins the bonnet uses, and I was able to create a nice schematic.
At this point, lets diverge again and take a look at the schematic. You will notice that there are two numbers for each pin. The GPIO pin number is called BCM numbering and is the numbering used if you opt for the BCM mode in the GPIO libraries. The second number are the BOARD numbers and is the number actually written on the RPI board and Vision Bonnet. GPIO pins 19 and 18 are able to supply the hardware PWM signals on the RPI 3B. I felt relieved because the RPI only supplied two separate ports for each of the two hardware PWM signals and I needed both.
You may think, "Jesse seems to be making progress." Truth be told, the adventure had just begun.
Instead of using the pigpio library, I got curious and tried to use the rpi.GPIO library. Turns out that the rpi.GPIO library only supports software PWM. Then I tried using the RPIO.GPIO library, which was supposed to be an upgrade from the original rpi.GPIO library with the hardware PWM functionality. Turns out that the RPIO.GPIO library does not work with RPi model 3B. So I ended up going back to the original pigpio libary. Quite a detour. Pro Tip Number One: Use Hardware PWM signalling from the pigpio library.
I spent the longest time ever trying to figure out why the servo would not work when the ESC always worked with the PWM signals from the RPi GPIO pins. Turns out that the JST-to-PWM wire I bought from Ebay had the positive wire and negative wire switched around. It was a good thing that my arduino wires melted before causing serious damage to my servos. I would have been very angry. Pro Tip Number Two: Never trust Chinese retailers on Ebay; double check the products you purchase to see if they are legit. The second reason why the servo did not work is that the servos needed to use the servo function in the pigpio library, not the hardware PWM function. The ESC also proved to be a huge pain to work with because the android app used to calibrate the ESC worked only half the time. Most of my time was spent crossing my fingers in hopes that the micro usb cable did not experience a disconnect during a firmware update.
People usually look at the Google search engine for answers, but the answers that people post are never 100% accurate. For example, if you search "pwm frequency" online, the majority of answers will indicate that the PWM frequency for servo and ESC control should be 50hz or 20ms. For the longest time, I blindly believed them. My reasoning was, "If 10 answers on Google indicate a PWM frequency of 50hz, it must be 50hz." Funny enough, the ESC and servos never worked robustly. So I got down on it with a bitscope (USB-to-PC Oscilloscope) and measured the PWM frequency coming out of my Futaba receiver. 74hz. Pro Tip Number Three: Avoid blindly believing in Google search engines; instead, scope out the PWM signal for yourself. As it turned out, the length of max throttle was 1.96ms, neutral was 1.5ms and min throttle was 1.2ms. This was quite different from the 2ms, 1.5ms, 1ms values people posted online. Trust the scope.
After three pro-tip revelations and a lot of tweaking, I was able to get a smooth throttle/steer response. Stay tuned during my weekly meeting presentation for a boss demonstration video.
In summary, I reiterate my pro tips.
<Jesse's pro tips for PWM>
- Use Hardware PWM signalling from the pigpio library.
- Never trust Chinese retailers on Ebay; double check the products you purchase to see if they are legit.
- Avoid blindly believing in Google search engines; instead, scope out the PWM signal for yourself.