Intro: Programming the Propeller Microcontroller
It's especially useful for creating Hi-quality audio, multi-tasking and TV (video) output. Here's tiny sample of Propeller Powered Projects to get you thinking;
- Bill Paxton Pinball, from Ben Heck
- Open Stomp, Open-Source Guitar effects pedal
- Replica 1, an Apple 1 clone
- ybox2, Networked set-top box
- AttoPilot, Autopilot system for R/C vehicles
You can learn more about the Propeller on Parallax's site. Here's a video of the program we'll walk through and a basic breadboard setup;
Step 1: What You'll Need
- A Propeller. You can learn more and see an example circuit on Parallax's site
- A Programming Stick. Either a USB-to-Serial Converter, Prop Plug, or grab a Protoboard from Parallax that has built-in USB
- A Computer. PC, Mac, or Linux (Sorry Amiga!)
- A Breadboard, resistor and LED for our sample program, and a power source (2x AA's will work). I used a 3mm green led and 270 ohm resistor.
Software / Downloads
Step 2: Hardware Setup
Step 3: Spin Basics
Spin is the most commonly used high-level language for the Prop probably because it's (1) easy, and (2) there's a spin interpreter on the Prop. There are other languages out there, but I figured I'd talk about Spin because it's the one I know best."Imagine if BASIC and PASCAL hooked up at bar time and 9 months later a new language popped out - well that’s SPIN for you." - Ben Heck
YOUR FIRST PROGRAMReady for your first program? Here it is:
Take the program above, put it into the Propeller tool and hit F10. It will quickly compile and load into the Propeller. The code will blink an LED connected to P0 every other second (1/2 Hertz) forever. Let's break down each line to understand what it's doing;
PUB mainSpin is organized into blocks;
PUB and PRI
These 2 blocks hold actual code. If you're familiar with php or BASIC or C, these operate a lot like functions. They have names (the name of this block is 'main'), and you can pass them values (function(passedval)).
The remaining blocks are not required for a valid program;
CON holds program constants. If there's a constant you use throughout the program, the CON block allows you to change it once and it will be reflected every time you use it. Here's an example of the blinky light program using a CON block;
The VAR block holds program variables. In the blinky lights program, I haven't used any system variables, but here's a version of blinky lights using variables
There are 2 more blocks, DAT and OBJ, but we'll skip those for now - OBJ is useful when incorporating someone else's code, and DAT is another place to hold variables, it's also where you put assembly code (if you want to use it).
Anyway - back to our original program. The next line is:
dira :=1Every pin on the Propeller can be set to an input or an output. When the Prop boots up, each pin is set as an input, so we'll need to set P0 to an output.
To set P0 as an output, we'll change the value of dira to 1. The := is an assignment operator in spin. Can you guess how you'd set P10 to an output? dira := 1. You can also change a range of pins with a single command. To change P0,P1,P2, and P3, just use dira[0..3] := 1.
repeat tells the Propeller to run a block of code multiple times. You can specify a repeat condition (repeat i from 1 to 100) or just repeat forever by not specifying anything else. This repeat block will repeat forever.
Code to be repeated is delineated by tabs. Note the soft gray lines under the repeat block? The Propeller Tool put those gray lines there to show you what code is in the repeat loop.
outa := 1outa tells the propeller to connect the pin to ground or to V+. outa works just like dira, you can set the output of a single pin (outa := 1) or a group of pins (outa[0..3] := 1). Note that outa is only meaningful if the pin has been switched to an output with dira.
Further, the Propeller uses Tri-state logic. Each pin can be connect to ground, V+, or set in a high impedance state.
A high impedance state lets the pin sense whether it's connect to ground or V+ without changing the signal. It lets multiple pins share the same data channel and do stuff like charlieplexing.
Connect the pin to ground with:
dira[pin] := 1
Connect the pin to V+ with:
dira[pin] := 1
outa[pin] := 1
sense if the pin is connected to a low or high signal (high impedance state):
dira[pin] := 0 (default on bootup)
pinstatus := ina[pin]
ina works just like outa and dira, except it's read only. If the pin is set as an input, ina will hold the current input value.
Step 4: Spin Basics, Continued
Let's continue with out blinky lights program. The next line is:
Before we break down this instruction, let me first explain clkfreq and cnt;
waitcnt(clkfreq + cnt)
The Prop can run at multiple clock frequencies, from 20kHz all the way to 80MHz. clkfreq is a system variable equal to how many clock cycles (ticks) are in 1 second. If the Prop is running at 80MHz, clkfreq will = 80,000,000. If the Prop is running at 20kHz, it will = 20,000.
cnt is the system clock. On bootup, cnt = 0 and it increments on each tick all the way to 2³² before rolling over to 0. cnt is a read-only value, you can't change the system clock, just read what it is.
Now, waitcnt: It pauses program execution until the system clock reaches the value in the parenthesis. What is the value in parenthesis? The current system clock (cnt) PLUS the number of ticks in one second. waitcnt(clkfreq + cnt) tells the prop to hold up for 1 second before going to the next instruction.
What if we wanted to wait for a half a second? waitcnt(clkfreq / 2 + cnt). How about 5 seconds? waitcnt(clkfreq * 5 + cnt)
So, in our program, we've flipped pin 0 to an output, connected it to V+ (driving it high) to turn on the LED, and waited for one second. Here's the next instruction;
outa := 0This instruction flips pin 0 from being connected to V+ to being connect to ground. It turns the LED off. Note that pin 0 is still an output, but it's connected to ground.
waitcnt(clkfreq + cnt)Just like last time, it pauses program execution until the system clock equals the value in parenthesis. In this case it will pause exection for one second.
Wrapping it upThe final instruction in our repeat loop has completed. Because our repeat loop has no end condition, it will start again on the first line (outa := 1) and keep running indefinitely.
Step 5: Cleaning Up Our Code
Let's clean up our code with a few operators. Note that these operators won't change what your code does, they're just shortcuts to make it easier to read.
Here's a cleaned-up version of the code
Like many languages, you can use '++' to increment a variable (i++ will increment the variable i). There are many more operators at your disposal, here are a few I've used in the cleaned-up code;
~~ (double tilde)
The double tilde will set the preceding variable to TRUE. So instead of dira := 1, we can just use dira~~
The ~(single tilde) sets the preceding variable to FALSE.
! (exclamation mark)
The exclamation mark flips the value of the succeeding variable. If it's set to TRUE, it will be be flipped to FALSE. Often, it's referred to as 'toggle' because that's what it does.
There are a lot of operators you can use in Spin, ++, --, comparisons, max and min's, and so on - check the Propeller Manual starting at page 42 to see all of them.
Step 6: Basic Video
The Propeller has built-in video hardware, so doing video is pretty easy:
First, we'll need to change our circuit a bit;
We've added 2 things;
A 5MHz crystal on pins 30 and 31. The Propeller needs some speed and precision to generate video data, the Prop will take that 5MHz input crystal and multiply it by 16 for a 80MHz clock speed.
A RCA (composite) video jack
you'll connect 3 pins to generate the video,
P12 goes through a 270 ohm resistor to the jack
P13 goes through a 560 ohm resistor to the jack
P14 goes through a 1.1k ohm resistor to the jack
Now that the video jack and crystal are set up, here's the program;
Running the program will get this image to display on your TV:
I'll briefly walk through this program to give you an idea what's going on, but I'll save the detailed analysis for a future instructables. Let's start with the CON block;
CON holds program constants. There are 2 special constants here;
This constant tells the Propeller what clock speed it should run at. If you don't specify anything, the prop will use an internal oscillator to run around 20MHz. This setting (xtal1 + pll16x) tells the Prop to take the crystal frequency and multiply it by 16. Take a look at the Propeller Manual for other valid clock settings.
If you're using a clock speed that uses a crystal, you'll need to tell the Prop how fast the crystal is! setting the _xinfreq to 5_000_000 tells the prop that the crystal frequency is 5MHz. NOTE: in Spin, underlines (_) are disregarded, so people often use them to make reading large numbers easier.
OBJThe obj block tells the compiler: "If I refer to a method (PUB or PRI) in another file, this is where you should". I'll reserve a full discussion of using Objects for another instructable, but for now, just think of Objects as a way to include other code.
The code we're using here comes with the Propeller Tool. tv_text is code to start a TV and display simple text information on it. There are a TON of other objects available on Parallax's Object Exchange, too.
PUB mainThis is the main block of code. text.start refers to the PUB start method in the text object. It starts up the TV and reserves memory for the screen.
text.str refers to the str method in the text object, it uses the Propellers built-in font to display a text string. We use the string() function of spin to declare the text string to display.
That's it! There are other TV display objects available. The graphics demo (included when you download the Propeller Tool) includes methods to display text, color, and graphics, a screenshot is below. You can also download the graphics demo on the Object Exchange.
Step 7: Next Steps
Multitasking - Our blinky light program only used 1 core, but there are 7 other cores at your disposal.
Object Oriented Programming - Spin is an 'OOP-lite' language, and code re-use is straightforward. Objects have already been built to control and read sensors, servos, motors and a bunch of other devices.
Advanced Graphics and Audio - MIDI & wav file playback, graphics and games.
Here are a few additional resources to help you get started:
- Propeller Manual, education kit, datasheet, and app notes (here)
- Propeller Forums
- Jon Williams' Spin Zone columns in Nuts and Volts Magazine
- Alternate Programming Languages for the Prop:
- Propeller Object Exchange