Start Here with PIC16F690
Presented here is my rendition of the Start Here robot using a PIC16F690 and programmed in Assembly with the MPASM Assembler.
In addition to the micro, parts include (approx price paid in US dollars):
Texas Inst SN754410 H-bridge $2.35
Solarbotics GM6 gear motors $5.75 (x2)
RC airplane wheels $2.00
Sharp GP2Y0A21YK proximity sensor w/ JST connector $17.00
T Pro SG90 servos $3.00 (x2)
The base is made of styrene and the caster is a cabinet knob. Other miscellaneous parts include a breadboard, sockets, batteries and holder, resistors and capacitors.
Having built a few little house bots based on various PICAXE parts, I got the urge to learn how to program PICs using Assembly, so I bought the PICKIT 2 starter kit that came with the programmer and a demo board populated with the 16F690. I decided the best way to figure the whole thing out would be to go soup-to-nuts and migrate from the Start Here. This approach worked out really well for me. Rather than sitting and staring at a jumble of tutorials and generic example routines, I had a fairly clear map of what I wanted to accomplish. The relative simplicity of the Start Here philosophy kept the project manageable, and the fact that I had built each of the sub-assemblies many times with PICAXE meant that I already had an understanding of how they were supposed to work.
I broke the programming/learning task into a number of smaller chunks. Some basic things required to do a Start Here include:
- Implement fundamental programming constructs such as:
-Variable Data
-Branching
-Looping
-Conditional Execution (IF/THEN/ELSE)
- Turn pins on and off to drive the H-bridge
- Read an analog sensor
- Control a servo
Although once I got rolling things moved along pretty well, I found getting started with the Assembly language to be challenging. I had some hobby level experience with Assembly on my Intel 286 way back when, so I had a vague notion of what it means to work in low level language. Nonetheless, moving into MPASM (Microchip's assembler for PICs) required quite the paradigm shift. Higher level languages - BASIC, Javascript, C - all have a layer of abstraction that sits between you and the micro. Tasks that can be accomplished in one or two lines of high level code can require dozens of lines in Assembly. Because Assembly maps directly to the machine language opcodes that make the micro run, each and every step of every process gets coded. In a FOR-NEXT loop, for example, you do the following:
- Load the working register with a value for how many loops you want to execute
- Move that value from the working register into a RAM register so that you can use it to keep count
- Mark the spot in the code where the loop begins
- Execute whatever process is internal to the loop
- Subtract 1 from the memory register holding the count
- Test that register to see if you've counted down to zero
- If you have counted down to zero jump out of the loop
- If you haven't counted down to zero jump back to the marker you left
You spend much of your time in Assembly reading and writing to various registers and ports. All of the peripherals included on a PIC are accessed via a register. For example, the analog to digital converter (ADC) is managed by flipping various bits in the ADCON register, and then the results are retrieved from the ADRESH and ADRESL registers. This sounds simple enough (and it is) but in practice it takes some getting used to.
Another factor that made getting going difficult was the fact that much of the reference material I could find assumes that you are already pretty savvy in all aspects of electronics and programming. This presumption was definitely a problem with the 12 "lessons" that are advertised to accompany the PICKIT. I doubt anyone could learn much about PICs relying on those lessons!
As stated, however, getting going was the hardest part. For the 16F "mid-range" PICs, there are only 35 instructions and once my intuition started to develop I was able to start chipping away at my goal of building a basic robot. By far the most elaborate coding required was to control the servos. I used two servos in a pan and tilt arrangement. As most LMR readers will know, to hold a servo position requires a precise pulse of between 1-2 milliseconds that is refreshed about every 20 milliseconds. Having the PIC do other things in the 16 or so milliseconds between pulses was the hard part. I had to configure the internal timer and prescaler to operate in the background and then trigger an interrupt. Fortunately, I was able to find some good examples online, but I still had to really understand the use of the timer and interrupt functions before I could adapt them.
All in all I found the experience of learning to use MPASM and the associated tools very gratifying. I think it's helped to expand my understanding of how micros function and opened the door to some new ideas. It's also given me an increased appreciation for PICAXE and all the intricate functionality they've managed to build into the RevEd implementation of BASIC.
For my own next steps, I plan to work on the detect and avoid algorithm on this bot which is sketchy at best, smooth out the readings on the Sharp detector which I think are a little jittery, and then slowly get into some more advanced mapping. I'd also like to work out a better algo for the servos. At the moment each servo fires in sequence and I'd like to get them firing simultaneously - perhaps even be able to run my 12 servo hexapod with a single PIC. I've ordered up some 18F series chips and I'm going to play with them. I used the 16F because it came with the demo board and it turned out to be a pretty good chip. However the 18Fs have a lot of interesting features not present on the older architecture that I'm looking forward to playing with.
I've posted the Assembly code here. I've tried to comment it well enough that someone could follow the logic, and I hope it might be of some use to others who would are just getting started with PIC Assembly. Although the bot works well enough, I'm sure the code is full of beginner flaws, so please be kind! I will try to keep up with it and if I develop any fundamental improvements I will update the post.
Thanks to everyone who has contributed to LMR!
Navigates by IR - avoids obstacles.
- Actuators / output devices: Solarbotics GM6 gear motors, T Pro SG90 servos
- Control method: autonomous
- CPU: PIC16F690
- Power source: 4xAA niMH
- Programming language: Assembly
- Sensors / input devices: Sharp GP2Y0A21YK proximity
- Target environment: indoor