Today, Society for Science and the Public published a blog that I wrote for them. They asked me a bunch of questions about my experience in Washington D.C. as part of the Broadcom MASTERS competition. Here’s a link to the blog, check it out. In the blog, I talk about my science fair project, my science hobbies, and my plans for the future. Tell me what you think of it in the comments below.
After my dad and I got an LED to dim using Pulse Width Modulation on my Raspberry Pi, we decided to try to spin a servo motor. We had a bunch of old servo motors on my robotics team at school so I used one of those, but I didn’t have any information on the pulses that they use. It was a HiTec HS-485SB. So, we started off following this YouTube video to modify the code from the LED to operate the servo. Of course . . . it didn’t work.
There were a couple of reasons why it didn’t work. First, the video didn’t really talk about how to hook up the servo to the RPi. Second, every servo is a little different. The colors of my wires were even different than the colors of his wires. Third, I didn’t know what pulse widths to use with my servo. The only thing that I could find is that it used from 0.9 to 2.1 ms so I assumed that means that 0.9 is CCW, 1.5 is center, and 2.1 is CW similar to the video, but not exactly the same.
So, we hooked up the red wire to the 5 volt pin, the black wire to ground, and the yellow wire to pin 21. I typed in the code from the video and changed all of the pin 7 to pin 21. I changed all of the pulse widths to match my servo. I ran the program and bzzz . . . I got a tiny little buzz out of the servo and the whole raspberry pi froze up. My dad said that he read that you can destroy a RPi by hooking up a servo the wrong way, so we decided to hook the red and black wires up to four AA batteries instead. So, with much anticipation (and cutting, stripping wires, and soldering batteries), I ran the program again . . . bzzzz, a little buzz and the program stopped.
I figured that it must be the pulse widths, so I played around with the numbers and couldn’t get anything else to work after many, many tries. Same thing over and over. It would rotate about 45 degrees counter-clockwise and stop (at least it doesn’t freeze up anymore).
So, I started doing research. I came across this blog where a noob, like myself, was trying to learn how to spin a servo. People suggested using something called servoblaster (too complicated for me) and lots of other things that I’d already tried. But then something jumped out at me that I hadn’t tried yet. It said that you have to connect the negative side of the batteries to the ground on the Raspberry Pi. I connected that one wire and bzzz, bzzz, bzzzzzzzzzzz, bzzz, bzzz, bzzzzzzzzz, it WORKED!
Here’s the exact code that came from the video link above:
import RPi.GPIO as GPIO
p = GPIO.PWM(21,50) #sets pin 21 to PWM and sends 50 signals per second
p.start(7.5) #starts by sending a pulse at 7.5% to center the servo
try: # I still don’t know what this does
while True: #starts an infinite loop
p.ChangeDutyCycle(4.5) #sends a 4.5% pulse to turn the servo CCW
time.sleep(0.5) #continues for a half a second
p.ChangeDutyCycle(10.5) #sends a 10.5% pulse to turn the servo CW
time.sleep(0.5) #continues for a half a second
p.ChangeDutyCycle(7.5) #sends a 7.5% pulse to center the servo again
time.sleep(0.5) #continues for a half a second
GPIO.cleanup() #supposed to stop when a key is pressed, doesn’t work
The percents work because at the beginning, we set it to send 50 pulses per second. So, 7.5% of 1/50 of a second is .0015 seconds or 1.5 milliseconds. That’s the pulse that it needs to center the servo as I explained in the beginning.
See the video below of my servo working! It doesn’t seem to be spinning the full 180 degrees, so I need to play with the numbers some more. Maybe I’m not giving it enough time to move all the way.
My dad zoomed in real close on the servo because he didn’t want you to see how bad the soldering was on the batteries. He’s terrible at soldering! But don’t tell him I said that.
This is Krystal’s dad guest posting again. Krystal wanted to control some servo motors with her Raspberry Pi because she’s on a robotics team that uses the Lego NXT brick as the controller and it easily controls servos. She wanted to see how easy it is on the Raspberry Pi. I wouldn’t call it an easy task, but we accomplished the first step in several hours one night. I am a complete novice to Raspberry Pi, Linux, PWM, python, and object-oriented programming in general, but I do know a thing or two about electronics and breadboards.
First thing, we read that Occidentalis is the way to go for using Pulse Width Modulation (PWM) to control servos directly from the Raspberry Pi without any controller boards connected. So, as Krystal described in this other blog post on how to install Linux on a memory card, we used Win32DiskImager to install the Occidentalis image onto a 4 Gb memory card. It went smoothly as soon as we remembered that we need to run Win32DiskImager as the Administrator on the computer (Right-click and “Run as Administrator”).
We popped in the memory card and started it up. We went through the raspi-config and did the typical settings to use the whole memory card and such. We noticed that there were no settings for overclocking in this version of Linux so we planned for tasks to take longer than we were used to with her jazzed up version of Wheezy that we usually use.
To start, we typed sudo apt-get update, but it didn’t work since we hadn’t configured the wifi yet. So, we looked up the instructions for how to do that on Occidentalis. We removed the wifi dongle, typed “sudo nano /etc/network/interfaces” and added our SSID and password and saved (CTRL^X, Y, Enter). We shutdown the Pi (sudo shutdown now), put the wifi dongle back in, and turned the Pi back on. We’ll skip a few trial and errors that occurred here and just skip to the part where it worked. When we typed ifconfig, our IP address showed up. This was actually the easiest time we’ve had connecting to wifi. You can read about her other adventures with wifi in a past blog post.
So, we did the update and started watching a video about using PWM (but not on the RPi because there’s still no simple method to watch YouTube videos on the Pi). We figured that we’d start by dimming an LED before running servo motors. So, we went to http://youtu.be/uUn0KWwwkq8 and tried to reproduce his results. Of course, you know what comes next if you’ve been following this blog at all . . . it didn’t work.
We kept getting the message that there was no module named RPi.GPIO. So, we researched how to install RPi.GPIO and tried it time after time after time and kept getting the same error message. So, we reinstalled and updated Python then installed Python3. Still didn’t work. Updated Python3, still didn’t work. Typed startx to open Midori and research some more and found where we could download the RPi.GPIO module, unzip it, and install it from the graphical interface.
Didn’t work. Kept getting an unexpected end of file error when extracting. So, we tried installing Gzip to extract the files. Couldn’t get that to work. Finally, instead of doing a Save As and then extracting, we chose “Open” after clicking the download button and it worked. (Download the module here: https://pypi.python.org/pypi/RPi.GPIO) Then, we just typed “sudo python3 setup.py install” (as we read on the raspberrypi.org website) (and we admit that we failed several more times before coming to this solution) and it seemed to install. But, it still didn’t work. Turns out that one of the things that we’d tried in order to fix it earlier was the case of the letters in RPi.GPIO. We’d changed it to rpi.gpio. Once we changed it back, it worked (almost, we had to connect it to the right pin on the GPIO and that took several tries. Why aren’t Pin 7 and GPIO7 the same thing?????).
Here’s the code that we used (Krystal was in bed by now and hasn’t seen this working as I’m writing this.)
import RPi.GPIO as GPIO #This line alone caused 90 minutes of frustration
GPIO.setup(21, GPIO.OUT) #set pin 21 to output
p = GPIO.PWM(21,50) #set the PWM on pin 21 to 50%
p.start(0) #I don’t remember what this does but trust me, you need it.
for i in range (100):
time.sleep(0.02) #These last three lines are going to loop and increase the power from 1% to 100% gradually
for i in range(100):
time.sleep(0.02) #These three lines loop and decrease the power from 100%-1% gradually
pass #This is supposed to stop the program if a key is hit, but it doesn’t work for us. Only ctrl^c works
It works! We have an LED that goes from dark to bright to dark again gradually over and over. The only difference between our program and the one in the video referenced above is that we used pin 21 for our LED and he used pin 7.
So, I started playing with the numbers. I found that the duty cycle is not allowed to go over 100. By changing the time.sleep value, I can change how fast the dimming and brightening cycle is. Changing it to 0.01 gives a nice, steady pulse. We could change the i in range to 50 if we didn’t want the LED to go to full brightness.
Next step is to control a servo motor instead of an LED. It should be a very similar process. After that, we’ll try and take over the world, dun dun duh.
Raspberry Pi, power supply, keyboard, mouse, USB hub, etc.
Occidentalis distro of Linux
Wifi dongle or other direct internet connection
Infinite patience (no URL for that one)