Video With the Propeller
Before we begin, let's review the tools we have to generate video: The Prop has no on-board peripherals except each core (a.k.a. cog) has 2 dedicated 'counter' modules (CTRA and CTRB) and a video generator (VCFG). This might sound crazy, but the Prop is fast enough to do stuff like 1-wire, i2c, UART, etc. in software. If you need UART, you just grab the UART object, and so on. Objects are available for tons of stuff.
The counter modules are 'set it and forget' and can be used to do:
- frequency synthesis
- frequency measurement
- pulse counting
- pulse measurement
- multi-pin state measurement
- pulse-width modulation
- duty-cycle measurement
- digital-to-analog conversion
- analog-to-digital conversion
By 'set it and forget it', I mean that you can tell each counter to do something (like synthesize a frequency or count pulses) and continue with your program. You can check back later and see how many pulses the counter counted, or stop / change the frequency being synthesized.
The Video generator consumes most of a core's time and can be used to generate PAL, NTSC, or VGA signals. The Propeller Tool (The IDE) comes with a number of objects to simplify running video, so it's common for Propeller Programmers to utilize these objects when programming.
Usually, I just use video to display simple information, so I use the tv_text object, and that's what I'm going to go over in this walkthrough, but there are other libraries available:
Anyway - let's get started using the TV_text object
Here's the video circuit for the Propeller. You just need 3 resistors to generate video. I've connected them to p12,13,14 which is the most common pinouts for generating video.
Here's the entire program
You'll see this program starts with a CON(stants) block, where I specify a clock mode (Use the crystal and multiply it by 16) and the speed of the crystal (5,000,000 Hertz). You'll often see the '_' delimiter in Spin. The compiler ignores underlines, so it's often used to help make reading large numbers easier.
The next block is OBJ(ects). I'm using one other object, tv_text, which is built-in to the Propeller Tool IDE. There are a few different built-in object. tv_text is nice because it uses fonts that are on the Propeller ROM, and it takes less memory. tv_text is best for displaying text information.
By including tv_text as an object, I'm telling the compiler: If I refer to a method in an object by the the name 'text', check the file tv_text.spin.
The final block is a PUB block. Because it's the first PUB block listed, it's where program execution begins.
First, I call the start method in the text object. If you look up the start method in the text object, where's what it says:
Pretty clear, right? So my code, 'text.start(12)' starts video output with a video dac starting at pin 12.
A new object != new core
Important point: by calling a method in another object, you aren't necessarily starting a new core. If you examine tv_text, you'll see the text.start method calls a method in another object: tv.start. This method starts up a new cog just to handle video output. So this example program will run with 2 cogs: 1 running our main program, a second handling tv output.
Most objects that use a new core have a 'start' method and a 'stop' method. The start method turns on a new cog, and the stop method lets you free up that cog when you're done using it. The surest way is to look for the 'cognew' command, that's how a new cog is started. The 'cogstop' command stops a cog.
The next line in my program calls the str method in the text object. What does the str method do? Let's look:
So, text.str prints a string. I can either specify where (in memory) the string is, or I can just declare the string in-line with the 'string' command. The string command compiles the string and returns the memory location of where the string is located. When you run the program, here's the result:
MAKING IT MORE USEFUL
I usually use tv_text to display the value of variables, the status of an event, or simple menus. But it's up to you! TV_text uses almost no memory (3k) and is pretty flexible. There are other graphics libraries out there, too, for drawing charts, graphics, images and more.
Demo using the graphics object: