A Forth-based Embedded Controller Development System
Follow projectParts list
Qty | Product | Part number | |
---|---|---|---|
1 | MikroElektronika Clicker 2 for dsPIC33 MCU Add On Board MIKROE-2567 | 144-8343 | |
1 | Development Kit USB to UART Interface for use with CP2102N USB Bridge | 184-0913 | |
1 | MikroElektronika MIKROE-1154 | 791-6485 | |
1 | Microchip Microstick II MCU Development Kit DM330013-2 | 749-6445 | |
1 | FTDI Chip USB to UART Cable for Raspberry Pi - TTL-232R-Rpi | 767-6200 | |
1 | Parallax Inc, BoE Prototyping Shield for Arduino - 35000 | 781-3027 | |
The Project
This write-up will be a repository for FORTHdsPIC documents such as the latest User Manual and source code (see Downloads below). The source code is fully annotated and may yield some useful assembler-language routines to anyone working with the Microchip dsPIC33 digital signal controller chip. I’ll also add FORTH source code for my various robotic projects as and when.
The FORTH Programming Language
In the early 1970’s a computer language appeared that bore little resemblance to the heavyweight mainframe languages available at the time, such as FORTRAN, ALGOL and COBOL. Called FORTH, it had a number of features making it very popular amongst engineers seeking a high-level language compiler able to create code for real-time applications running on the early microprocessors. These features included:
- Does not need an operating system (OS) - simple development board required, not an SBC.
- High-level compiled structures such as BEGIN….UNTIL and BEGIN….WHILE…. REPEAT.
- 16-bit single-precision numbers with 32-bit double-precision available.
- High-speed (for the time) program execution.
- It has both an interpreter to execute a line of code immediately, and a compiler to create new 'words'.
- Stack-oriented operation for maximum efficiency (as in LIFO push-down stack).
Professional software engineers saw no problem with the last item in the list above, but the non-algebraic source code format (Reverse-Polish Notation) ensured that those new to programming would stick to BASIC or Pascal! To find out more about Forth and its origins, see this excellent website. Also look at the Forth Interest Group Archive and the Jupiter Ace Archive. Both contain lots of useful, downloadable material including original manuals and free ebooks.
Forth's ability to create new commands or 'words' beyond the basic set is considered to be one of its most powerful features. Type VLIST at the console command prompt of any version of Forth and you will get a list of all the words it 'understands'. Look at the screen dump for FORTHdsPIC below. A program for making a simple humanoid robot walk has just been downloaded and compiled. The first block of core words may be executed immediately from a command prompt or used to create new word definitions. The second block provide the structure of a compiled program and cannot be executed directly. The third set of words were created when the user program was compiled.
Each of the words LEANLEFT, ROTATELEFT and LEANLEFTBACK defines a single movement of a particular joint servomotor on the left leg. They are combined in the definition for STEPLEFT which causes the left leg to move forward by one step. The other words do the same for the right leg. STEPLEFT and STEPRIGHT are used in the definition for STEP which moves the whole robot one step forward. Finally, STEP is executed repeatedly by a loop in WALK, making the robot 'walk' forward continuously. These new words could become the 'core' words of a robot programming language. ROBOFORTH from ST Robotics is a commercial robot arm programming language that was created in just this way.
What is FORTHdsPIC?
FORTHdsPIC has its origin back in 1982 when I was designing a portable instrument for measuring battery state-of-charge. The complex algorithm made it an ideal candidate for using digital processing, so a design emerged based on the then-ubiquitous Zilog Z80 chip. Forth was all the rage then; articles appearing regularly in computer magazines. There was even a home computer on the market - the Jupiter Ace - that ran Forth rather than the usual BASIC, from the designers of the Sinclair ZX Spectrum. After finding some outline code for a Z80-based compiler in a computer journal, I created LUT-Forth which fitted into a 4KB UV EPROM. The same code also ran on a Kemitron computer under the 8-bit operating system CP/M. The compiled code it produced was blown into another 4KB EPROM which was then plugged into a second socket on the instrument PCB. I didn’t know it at the time, but the result was what we now call an ‘embedded’ computer!
Many years later I gave in to an impulse to convert my original LUT-Forth Z80 code (actually a subset: 8085 code) to a more modern processor and see how it performed. I chose the dsPIC33 and FORTHdsPIC was born. Current microcontrollers have many features that the poor old microprocessors of the 1970/1980's didn't, so it wasn't going to be too difficult to create a better Forth:
- On-chip non-volatile programmable Flash memory. And lots of it.
- Huge variety of on-chip peripheral hardware interfaces.
- Powerful instruction set with hardware multiply/divide instructions.
- And a whole lot more besides.
First version: 40MIPS dsPIC33FJ128MC802 in 28-pin DIL package
Flash memory: 128KB RAM: 16KB
The first host I used for this project was an Arduino-format board made by a firm in Hong Kong and obtained via eBay. It was perfect for this job as it had a USB-UART Bridge chip on board - a Silicon Labs CP2102, and a USB-B connector. This device is so common, all I had to do was connect the USB to a PC with Internet access and the driver was downloaded and installed automatically. The USB link supplies the all-important terminal or console connection needed by FORTHdsPIC for program entry and display.
The board also featured a Microchip PICkit 3 compatible ICSP header. A PICkit 3 provides the programming/debug interface and link to the MPLAB IDE running on the PC.
By the time I'd got to version 0.5 of the firmware I realised that it would be a good idea to switch to a more widely-available development platform. The Microchip MicroStick II seemed ideal as it retained nearly all the functionality of the old board and came with a built-in programmer/debug tool. The latter eliminated the need for the PICkit 3. I described the transition in this DS blog post.
Of course you lose the convenient Arduino header sockets, but gain header pins which will plug into any standard prototyping breadboard block. The USB connector provides a link to the PC running MPLAB IDE and the solder pads at the opposite end give access to the chip's UART1 used for the console. Very few PCs have serial COM ports nowadays, so to provide a console, a UART-USB bridge cable (767-6200) is needed together with terminal emulator software. I used (and still do) the freely available TeraTerm.
Size matters
It's amazing what you can do with 28 pins, but I began to realise that FORTHdsPIC was starting to out-grow the SPDIP package. At least as a development tool. A specific application might make do with an 8-pin chip and a 2-wire I2C bus to drive external peripherals. See my blog post on I2C serial communication. The 28-pin dsPIC33 device contains far more peripheral function modules than external connections, and pin assignments are programmable by the user. But I wanted all functions to be available at the same time, necessitating the change to a chip with many more pins.
Second version: 70MIPS dsPIC33EP512MU810 in 100-pin TQFP package
Flash memory: 512KB RAM: 52KB
The new home for the current (I hesitate to say final) version of FORTHdsPIC: 0.9, is a MikroElektronika Clicker 2 development board featuring a 70MIPS dsPIC33EP part replacing the old 40MIPS FJ.
Like its predecessors, this is not a Single-Board Computer (SBC) as it does not have the DDR RAM, GPU and other paraphernalia necessary to support an operating system such as Linux or Windows. In fact the only other major chip present, besides the dsPIC itself, is a power management device (PMIC) which reconciles the various power sources available including an optional Li-Polymer rechargeable battery.
Porting the code from MicroStick to Clicker 2 was not without a few niggling problems causing some frustration, but I got there in the end. Two recent DS blog posts here and here document the journey.
Click and the mikroBUS
A microcontroller development board is no earthly use to a designer unless the attachment of, and communication with, application-specific sensor/actuator circuits is both quick and easy. For me, that means at least one pair of parallel socket headers per expansion board should be provided, allowing matching peripheral modules to be mounted. This twin-header approach makes for a mechanically stable arrangement and is featured on Arduino, Beaglebone and MikroElektronika processor boards which take expansion modules called Shields, Capes and Clicks respectively. I’ve always thought the GPIO connector on one side only of the Raspberry Pi was a weak point in the design. Old-timers like me may remember the notorious 16K RAM Pack of the Sinclair ZX81 that flapped about in the breeze losing all your code just after you’d spent ages typing it in….
The Clicker 2 boards have a ‘belt and braces’ approach to expansion connectors: as well as sockets for two Click modules, there is provision for a 26-way GPIO header along each side of the board (See picture above). The functions of the 16-pin headers on a Click module are defined by the mikroBUS standard. Half of them are dedicated to communication: UART, I2C and SPI buses. Four are for power supply: +3.3V, +5V and two Gnd connections. The remaining four are given specific functions, but as they are tied to GPIO pins, they can be assigned for any purpose.
Forth functions available on Clicker 2 mikroBUS sockets
mikroBUS 1: UART channel 1 (Console), ADC channel 1, PWM channel 1
mikroBUS 2: UART channel 2, SPI channel 2, ADC channel 2, PWM channel 2
Forth functions available on Clicker 2 26-way headers
LH header: I2C channel 2, Servo channels 1 to 4, Tacho channels 1 & 2, SPI channel 3 CS 1 & 2
RH header: SPI channel 3, ADC channels 3 & 4
mikroBUS Shield
As it stands, the Clicker 2 board only supports two Click peripheral device modules. Even a moderate-sized development project is likely to need more than that. Here’s where those 26-way connectors come in. I soldered stacking headers to each side of the board: these are socket headers with extended solder pins enabling the Clicker 2 to take an expansion board on top and plug in to another underneath. The hand controller for my wireless mobile robot project needed four Click modules: two joysticks, a wireless module and a UART-USB bridge for program development. The mikroBUS Shield (791-6485) provided the answer: it has two sets of Click headers and a useful ‘prototyping’ area as well.
MikroElektronika’s modular system based on Click boards with their mikroBUS connectors is well thought out and allows robust prototypes to be built without the need for fragile wire links. My robot wireless remote-control unit is a good example: it’s strong enough to be tested without any danger of it falling to bits! The only precaution necessary is to keep fingers off the wireless module and its antenna.
The mikroBUS Shield provides two more Click sockets yielding access to different channels of UART, SPI and I2C communication to those on the Clicker 2 board itself.
Forth functions available on mikroBUS Shield sockets
mikroBUS 1: SPI channel 3 (CS1), I2C channel 2, ADC channel 4, Servo channel 1
mikroBUS 2: SPI channel 3 (CS2), I2C channel 2, ADC channel 3, Servo channel 2
Forth functions available on mikroBUS Shield 26-way headers
As for Clicker 2 board.
Off-board connections
Not all projects can be constructed entirely from Click modules, so I use the 26-way socket headers on the Clicker 2 for making single-wire connections to other boards. The mobile robot on the other end of the wireless link from the remote-control unit needs just such a connection for its two ultrasonic rangefinders. The SRF08 device is ‘intelligent’, receiving commands and sending back distance data via an I2C bus. I2C is a genuine ‘2-wire’ communication system with a complex protocol that can handle over a hundred addressable devices with just those two wires: one for data (SDA) and the other for the data clock (SCL). The dsPIC has two independent I2C channels: channel 1 appears on both mikroBUS connectors of the Clicker 2 board, channel 2 feeds the sockets on the mikroBUS Shield board (if fitted). For the time being, I’ve only written the driver for channel 2 as the Clicker 2 sockets only need UART or SPI comms, with channel 2 available on the 26-way header for off-board peripherals. My blog post on the wireless robot contains a lot more practical info on the I2C bus, including how to avoid some of those niggling design errors that can drive you crazy!
To be continued....
Related Content

Clicker 2, FORTHdsPIC and more Bare-Metal

How to set-up an ESD Control Plan

Bridging the Performance Gap Between Electric Double-Layer Capacitors and Batteries - Panasonic's HL Series as a Fit and Forget Device

Comments
Add a comment[Comment was deleted]
September 10, 2020 08:33
Fantastic article! I am author of RoboForth and one thing I have observed is that new users who have never programmed anything before get on to Forth and RoboForth very quickly indeed and get robot motion within minutes. For programmers used to syntactic languages like C or Python Forth can seem to be a paradigm shift.
September 10, 2020 08:32
@ROBOTICS1 Thanks! A piece of 'raw' Forth code with its RPN format can be really intimidating to newcomers - especially without indents and copious comments. I found I really enjoyed not having all the padding of procedural calls and bracketed lists of parameters, once I'd got the hang of it. Forth must be unique in allowing an 'expert' to create a much simpler and intuitive programming language for specific applications such as your RoboForth.
September 10, 2020 08:33
Back in the day (late 80s) I used Forth on an embedded microcontroller from Zilog - the Z8681 family. It was cost effective and C compilers were not well supported for that family at the time.
I inherited the device on 2 physical platforms designed by Arcom Controls and they provided a version of Basic compiled on a Z80 CP/M based SBC for embedded programming.
Using Forth from MPEForth in Southampton, I could test and compile on a PC - the first machine was an Apricot 286 based machine. During the compile of less than 32K of code there was time to make a coffee!
Forth was a joy to write code - indeed "fun" in the words of its inventor Charles Moore. The PC interpreter made it possible to run, test and debug code before compilation. Another money saver for a small business.
Two memorable incidents stick in my mind:
1. The hours spent debugging some code which used the keyword "WITHIN" to return a flag if the a value was in range of 2 other values. It turned out that the interpreter and compiler treated the boundary values differently.
2. The upgrade to a 486DX PC. I pressed the enter key to start the compilation and began to stand up from my chair to make the coffee. By which time the prompt had re-appeared and the compilation was complete. No more coffee breaks.
Thanks for reminding me of those times with this project.
September 11, 2020 15:39
@gazak Back in the early 1980's if you wanted to develop a microcomputer for anything like 'real-time' operation your only option was to program in the assembly language of the particular chip being used. Nearly all were 8-bit, apart from the new-fangled 16-bit Intel 8086 and the rather more obscure National Semiconductor INS8900 PACE. You really needed a 16-bit micro to run C - and a lot of memory. Forth slotted perfectly into the world of embedded control until micros became powerful enough with more 'regular' instruction sets to run compiled C. Even so, Forth stayed around, being the language of choice for designers of long-range space probes until quite recently. In those days, Forth language software was available for most home computers, including the ZX81, Spectrum and BBC micro. I just loved being able to test out a line of code with the interpreter, and then compile it almost as fast as the source text file loaded. Ah, happy days!