Saturday, March 29, 2014

Further Wanderings in Low Power Land

Introduction to Low Power

On this Arduino Day 2014, I thought I would investigate very low power operation of the ATmega328P-PU.

With low power and low energy battery powered devices becoming the norm, the desire to run the microcontroller on low voltage, derived from a coin cell or single AA cell is becoming increasingly popular. Some microcontroller manufactures, including Atmel, Silicon Labs and Holtek have identified this need for "single cell operation" and have built a simple boost converter into their device. Others - particularly, EM Microelectronic, have a core, the EM6682 that will actually run at 0.9V.

So we are going to see a proliferation of low power microcontroller solutions, and as a preliminary investigation into what was to come, I thought I'd explore the performance of a very common micro, as used in all Arduino Unos - the ATmega328P-PU, one of Atmel's PicoPower range.

This post is inspired by Nathan Seidle's Spark Fun post of 2011 "Adventures in Low Power Land".

Nate wanted to get a ATmega328 to run at the lowest possible sleep current whilst used in a digital watch application.

Now typically, an ATmega328P running code at 16MHz will draw about 7mA at 3V3, and whilst asleep, with almost everything turned off, Nate's investigation showed that 1.0uA operation was feasible.

I wanted to explore the territory between these two extremes, and determine whether there were other "safe havens" of operation, which could be usefully be exploited for low power applications.

I wondered whether by a combination of low power techniques it would be possible to run the Arduino at a greatly reduced clock speed, and at a lower voltage, and still have the microcontroller  running code and communicating via the UART.

Please note that this investigation is entirely experimental.  Several of the ATmega peripherals will no longer function at low voltage and low clock speed - in particular the ADC.  Also it should be remembered that just turning on an LED is going to consume many times more microwatts than just the microcontroller running code.

Getting Started

My initial experiments involved using  the prescaler on the external 16MHz crystal oscillator. On the standard Arduino Duemillenove with ATmega328 16MHz, the brown out detector is set to 2.7V. With this setting, a supply of 2.8V and the prescaler set to give a 62500Hz clock, the current dropped to a more reasonable 750uA.  This was a modest first effort, as even at less than 1mA, a coin cell is only going to last about a week.

I then decided that the 16MHz oscillator was always going to be power hungry, so I followed Nate's example and configured the device as an Arduino Pro 3V3 8MHz using the internal 8MHz oscillator.  I also turned off the Brown Out Detector (BOD) because I soon realised that this would prevent the IC running at low voltages.

I divided the 8MHz internal clock oscillator using the maximum prescaler value of 256. This meant that the code was executing at 31250 Hz, or 1/512 of the usual execution speed.

By setting Serial.begin(76800), I was able to get 300 baud communications from the new divided clock frequency.

BOD Alert!

There have been a number of cautionary tales about disabling the BOD, which could lead to corruption of the flash memory, but as this was entirely an exercise in pushing the device to investigate it's lowest limit of supply voltage and current, I accepted that there may come a point where I could no longer guarantee code integrity.

So I disabled the BOD, and the current started to creep down, first to 450uA, then 300uA. I then remembered the post in Jeelabs, about how the MCP1702 regulators start to draw large amounts of current when the supply voltage falls below their minimum LDO point.

So after I removed the MCP1702 regulator and set up a 2.0 V supply, the current dropped massively, remaining close to 100uA.  I then wondered if I could lower the supply to closer to 1.8V and see what current consumption would result.

I quickly learned that the CP2102 serial adaptor was supplying current to the application via the Rx line. The greater voltage on the Rx line leaks through the input protection diodes on the Rx input and contributes about 80uA - which caused the super capacitor to charge up!  I disconnected the Rx line, to ensure that subsequent measurements were accurate.

A rather poor, unregulated supply made from a potential divider on the 5V supply from my CP2102 cable, allowed me to get a datapoint at 1.8V, where the average current was close to 60uA.  The individual characters sent from the UART at 300 baud, were clearly visible in the current measurement.

Unfortunately, I didn't have access to a variable low voltage power supply, so I charged up a 0.22F super capacitor and ran the ATmega from this, monitoring the voltage and current drawn, via the voltage drop across a 1000 ohm resistor in the +ve supply lead, as the super capacitor slowly discharged.  Here are some voltage and current way-points during the discharge - it really highlights how dropping the supply voltage reduces the power (microwatts) drastically:

Volts        Current             Power

3.30V       450uA              1485uW
2.50V       100uA              250uW
2.00V       70.5uA             141uW
1.95V       64.7uA
1.90V       62.5uA
1.85V       61.3uA
1.82V       60.0uA
1.80V       58.9uA             106uW
1.75V       57.6uA
1.70V       55.6uA
1.65V       53.9uA
1.60V       51.1uA
1.55V       48.2uA
1.50V       44.5uA             66.75uW
1.45V       39.8uA             57.71uW
1.44V       38.7uA           - Dead!

Current consumption shoots up after 2.5V!
Power / uW in red also increases dramatically
As can be seen from the graphs - Low Power Land is definitely entered below 2.0V supply voltages!

Using this method I was able to show that code was still running at 1.71V supply and 55.8uA average consumption - printing serial to the terminal every second or so.

At 1.68V supply the CP2102 would no longer correctly receive characters - although the ATmega was still sending them - but at a much reduced amplitude.

So the ATmega328P-PU will still run code at 1.45V  consuming about  58 microwatts of power.

Later in the evening, I realised that it was my CP2102 serial adaptor cable Rx input that was giving up at 1.7V, and failing to read the very low voltage signals from the UART.   I continued to monitor the ATmega UART output with the scope running code right down to a supply voltage of 1.43V and 39.5uA of current. The ATmega328P-PU was actually running on 56.5 microwatts of power.

If you are concerned about disabling the BOD, then assume that the minimum safe supply voltage is stated as 1.8V in the datasheet, for clock frequencies below 4MHz. Set the BOD to this lower limit and accept that you can run the IC at between  60 and 100uA, depending on clockspeed and what peripherals you have enabled.

Applications

So why is this important?  It means that we can have very low power consumption from Arduino based hardware, making it compatible with Bluetooth low energy. A simple interrupt from the BLE module can wake the '328 to whatever clock frequency is needed to handle the RF data.

Additionally, it allows new power sources to be developed, such as energy harvesting devices, or even a small 3" x 2" photovoltaic collector, illuminated by ambient lighting is sufficient to power the microcontroller.

Clearly their will be a compromise between fast and slow clocking, and a combination of spending long periods asleep, and waking up to run at high clock speed, may be more advantageous than plodding along at 31kHz. It's definitely a tortoise and hare situation, and the overall winner is likely to be highly application dependent.

Photos and more detail to  follow.




Saturday, March 22, 2014

Clarity of Vision

A simple serial port graphing program helps debug high speed sensor data.

This week, I have been debugging a high speed 24-bit ADC, connected to an STM32F303 ARM microcontroller. Unfortunately my usual arsenal of debugging tools were starting to creak under the strain. Here I discuss existing methods, plus a new approach which will be of interest to the hobbyist/Arduino community.

The Old Fashioned Way...

With any microcontroller project, during debugging, it is essential that you have the tools available to get data in and out of the micro so that you can see what's going on. Often this may just be a UART link to a serial terminal program which allows you to print out results and enter serial commands to control the application.  Frequently, when I start with a new microcontroller, I use a simple framework program that provides the serial link with basic functions such as

putchar(x);            // Prints the ASCII character of x, sends x to the uart transmit buffer

print_num(x);       // Prints x as an integer

getchar();            // checks to see if there is a character waiting in the uart receive buffer

Now putchar and getchar  are as old as the hills, and have been associated with character input and output - probably before C was even thought of.  They may be as simple as testing for a uart flag to be set, and then writing or reading the uart tx or rx registers, but once you have these working, and can get characters in and out of your application program, then debugging becomes a whole lot easier. With just putchar you can do hex dumps of memory, send data to a file or even make a very simple realtime horizontal bargraph display - handy if you are looking at time varying analogue data.

My framework program often uses getchar and a switch/case statement to select different modes of working. One example this week was being able to control the sampling and averaging of an ADC that I have been working on, just by sending a single ASCII character to the microcontroller.

Another good technique is to set up a timer channel to count milliseconds. This establishes a time framework to your application program.  By reading the millisecond counter, it becomes easy to co-ordinate tasks at given times, say once every 10mS, or once a second, and also to print out the millisecond count at each end of a task - to see how long it takes.

Fairly early on in your developments, you will want to start testing the I/O pins. One technique is to toggle an output port line each time you enter a given routine, this might drive a LED or better still connect a scope probe and use an oscilloscope to time the event. If you are going to be laying out a pcb for your next project, it is very worthwhile to break out some of the spare I/O pins, to say a 2.54mm header, which gives you something to clip a scope probe onto, or use jumper leads to a temporary array of LEDs. Modern microcontroller packages are very small, and the pins are not easy to probe individually - so break a few spare pins out - so you can get at them easily.

This week, I have been debugging a high speed 24-bit ADC, connected to an STM32F303 ARM microcontroller. Not only does this involve high resolution data, but it is output at high speeds, which makes seeing what's going on a little challenging.  The particular ADC would be producing 24 bit readings at approaching 20kHz, and data sent at 921,600 baud. Whilst a terminal program, in this case RealTerm would be a start, it's very hard to visualise what's actually happening with streams of hex digits scrolling up the screen at an alarming rate. Clearly a new approach would be needed.

The project involves reading very small changes in voltage signals - down to fractions of microvolts, and as such it is essential to have good analogue design, and use precision low noise components. I found a good application note from Linear Technology, which describes most of the techniques in detail. If you are interested in high resolution analogue datalogging, and low noise analogue techniques - this app-note is well worth a read

Unfortunately, electrical noise is a fundamental property of the universe we live in, so minimising noise to the point where it no longer interferes with your ADC readings, is quite a challenge.

The ADC and microcontroller are mounted on a small pcb, along with voltage  regulators, op-amps and an RS232 driver IC. Whilst RS232 might appear a little old fashioned, it is a robust way of communicating between instruments over moderate distances.

The microcontroller produces a 1MHz clock for the ADC, and every 8uS, the ADC interrupts the micro, to announce that it has another reading ready.  The micro then reads the ADC using SPI, does some quick calculations on the readings and then passes the results out through the serial port for analysis on a PC.

This might appear simple enough, until you realise  that even with some data averaging, the readings are being sent to the PC every 50uS, or 20,000 readings per second, and to achieve this, the UART has to run at 921,600 baud, nearly a megabit per second.

Visualisation of Your Data

During the debugging of this project some simple tools have been invaluable to capture the data, and allow visual analysis on a graphical display. By turning the ADC sample numbers from the sensor into a "scope trace" display I could see in real time what was happening.

SimPlot - A Simple Serial Plotting Program

After a quick search, I came across a program,  SimPlot  (downloadable here) This has been developed within the Arduino community, and allows up to four channels of data to be plotted against time, like an oscilloscope display. A few lines of code will produce the 16 bit integer data in the format needed by SimPlot, and it is very easy to use. The screenshot above shows one channel of data being captured from an Arduino at 115200baud, where the ADC input has been left floating.  SimPlot allows you to set both the number of samples in the horizontal axis, and also the range displayed in the vertical axis.  By choosing a certain sample rate, and setting the horizontal scale accordingly, it is possible to determine the frequency of the displayed waveform - in the above case it's just 50Hz mains hum.

Fortunately, SimPlot will handle high baudrates, and just typing in 921600 set it up correctly and I was soon able to view the amplitude of my data, noise and all.  It is so much easier to see what is happening with a realtime trace, than to try and look at reams of hex data, or capture the data to a file and analyse later using plotting programs such as KST.

As microcontrollers become more sophisticated, and often within the hobbyist community, they are now used to read advanced analogue sensors, such as accelerometers and gyros, having a 4 channel display of analogue data like this is an absolute god-send. You can see in real time the changes in the signal, it's sensitivity to changing external parameters, such as temperature, and monitor drift and noise.

24 bit ADCs - what's available.

24 bit ADCs are now becoming more widely available, at an affordable cost.  Most of the recent developments have been with the Delta-Sigma converters, which have an internal architecture that suits high speed digital signal processing and efficient translation into silicon. As a result Delta-Sigma converters tend to be cheaper and more widely available than the more traditional successive approximation (SAR) converters.

However, Delta-Sigma converters are about a magnitude slower than the SAR converters, max sample rates of about 10,000 samples per second, and as you sample faster, the weight of noise increases, so that a 24 bit converter, might only return about 17 noise free bits at 4kHz, rising to 20 bits at 2kHz sample rate.

Nevertheless, there are some good Delta-Sigma converters, and the LTC2440 from Linear Technology is a good representation of what is available.  There has been some work done within the Arduino community on this device, and a link to a report on its performance whilst being read by an Arduino is here.

These converters are available for about £11 (Farnell) - but you will need a TSSOP adapter pcb in order to make use of them. They don't exactly lend themselves to breadboard prototyping either.

The resolution of a 24 bit converter is such that if we chose a 5V range, then the voltage represented by a single count would be 298nV - or approximately 0.3 microvolts.  Compare this to the 10 bit converter on the Arduino, where the smallest voltage step is 4.88mV,  or 16384 times larger.  However this resolution is somewhat theoretical, and not really achievable in practice. Most Delta-Sigma converters are used at very low sampling speeds, often below 10Hz, in applications such as weighing scales.

Successive Approximation converters can convert much quicker, and the AD7767 I have chosen for my project can produce a maximum of 128,000 samples per second.  The conversion rate is controlled entirely by the clock frequency you supply it with, up to a maximum of 1.024MHz. A new conversion is available every 8 clock cycles.  Currently I am clocking it at 800kHz, in order to achieve 100,000 samples per second.  These are averaged down, so that a new result is available every 8 samples - or 12.5kSps, or if you only wish one sample, then these can be output at 20KSps - which is limited by the speed of the RS232 interface.



Sunday, March 16, 2014

Joining the Dots .......

In the Beginning..

In the early 1960s, Digital Equipment Corp, were contracted to build a system to control and monitor certain processes at a Canadian nuclear power station which would convey data back to a mainframe computer. One of the young hardware engineers, Gordon Bell, came up with the proposal, that rather than building a one-off, custom digital control system from their digital modules, that they should build a small and low cost programmable 12 bit computer. It's programmability would make it more flexible, and, as a general purpose product, could be sold to other customers. Thus the DC-12, later the PDP-5 was conceived. It was the fore-runner of the PDP-8, which was the first true minicomputer, benchtop sized and a major commercial success for DEC.

The idea of using a small computer to perform specific tasks, whilst interfaced to a larger machine was not entirely new.  Seymour Cray had developed the CDC-160 back in 1960, again a 12 bit machine, reportedly designed over a 3 day weekend!

History indeed repeats itself, as some forty years later, the Arduino team first designed their product to be an input/output board, which would interface with a desktop or laptop machine, running Processing. The easy to program Arduino could be connected to analogue and digital signals and make these available to the laptop for controlling or graphing, in a way that previously had been a lot of hard work. Either you needed to be an embedded specialist, with a register level knowledge of programming microcontrollers or use proprietary software.

It's now 10 years since the creation of the first Arduino, and this will be celebrated around the world on Arduino Day, March 29th.  Whether you love or loathe Arduino, you have to accept that it has introduced a whole generation of youngsters to open source technology, and some of them are destined to become the programmers, developers, designers and entrepreneurs of tomorrow.

Arduino is just one of the ways in which technology has been opened up - a process that began about 25 years ago, with the creation of the World Wide Web, and followed by other notables including Linux, open source software, Android and open hardware, trailblazed by Arduino, and followed by many.

I recall that 25 years ago, when I started my career, that a genuine IBM PC cost the equivalent of about 5 months wages, and you could spend a similar amount on the software packages to run on it.  Now you can purchase a tablet machine for a few hundred dollars, and we have come to accept that a lot of the software is bundled into that price, or open source, free and downloadable from the web.

In my opinion, it is this democratisation of technology that has brought about the rapid developments we have seen over the last 5 years.

On a hardware front, 32 bit ARM devices are competing in price with 8 bit devices.  $5 will buy you a lot of processing power,  or $10 or $12 will buy a dev board that is Arduino compatible. The open source GCC compiler and a free, unrestricted IDE can be downloaded.  So for a few dollars, you have more computing power than that 1985 IBM PC or the 1964 PDP-5, which back then cost $27,000, at a time when a new Mustang would be $2000.

Other drivers of this technology revolution include wireless communications and improved battery technology.  Devices will become smaller, smarter and run for years on low cost batteries.  The SmartPhone can provide a common interface for controlling household technology, such as channel hopping on the TV, when you can't find the remote,  programming the central heating controller, or selecting the correct program on the washing machine.

All of these applications are on convergent trajectories, powered by open source technology which is now accessible to the hobbyist.


Quick Hack - Arduino with Bluetooth Low Energy



This week, the nRF 8001 module arrived from Olimex. These are available for around $14 and take just over a week to ship from Bulgaria.

In order to connect it up, I used a "bare bones" Arduino like board of my own design, that runs at 3.3V This is important, as the nRF8001 IC from Nordic Semiconductor will not withstand 5V.  The board is simply an ATmega328, a 16MHz crystal, reset circuit, a 3V3 regulator and a 6 pin header for a FTDI cable.

The nRF8001 module from Olimex is breadboard friendly, and once having soldered a couple of headers to the underside, it can be mounted in a breadboard.

In the middle is the nRF8001 IC, with the 16MHz crystal above it. To the left is the low power 32kHz crystal, and to the extreme right of the  pcb is the L-shaped pcb trace antenna.  Another 22 surface mount passive components complete the design.

The close up above shows how just 8 jumper wires are needed to connect it. The top header connects 3.3V, 0V and Reset, and the bottom header connects MOSI, MISO, SCK and two handshaking signals REQN and RDYN on digital pins 9 and 8 respectively.  These are used to synchronise the transfer of data between the ATmega328 and the nRF8001.

Once I had downloaded the latest Nordic Semiconductor nRF8001 example sketches and Library from Github, and loaded the nRF UART app from the Google store (Apple version also available), it was very quick and easy to get the example running.  Within a few minutes I was able to type ASCII characters into the phone and have them appear on the Arduino serial terminal window, and vice versa.

Other example code allows the phone to control the various ports on the Arduino remotely over the BLE link.  Once connected the nRF8001 uses only about 600uA average current, whilst the ATmega uses about 7mA!

 



More ARM Adventures





Update 28/03/2014.

An excellent online book "Discovering the STM32 Microcontroller" by Geoffrey Brown is now available.  This comprehensive, up to the minute text leads the beginner through the main techniques involved in writing applications, and interfacing hardware devices to these increasingly popular microcontrollers. Communications with serial, SPI and I2C are covered, also interfacing to a colour LCD, a SD card and a Wii Nunchuk.

In an earlier post, I described how 32 bit ARM microcontrollers are now making substantial inroads into applications previously hosted by 8 bit micros.

In order to get started with ARM devices, I decided to make a minimalist breakout board for the STM32F303, which has an ARM Cortex M4 core. This has a floating point unit and additional DSP instructions making it quick for math intensive code.

The STMF32303 has a maximum clock frequency of 72MHz, but has several low power modes where it can be clocked from a low frequency internal clock source.  This is important for battery powered devices,  where battery life may be an important issue.  At 72MHz, I measured the current consumption at 35mA from the 3V3 supply.

One of the biggest challenges to the ARM newcomer, is understanding the vast menagerie of on-chip peripherals and how to initialise them.  Once this is mastered, programming becomes as simple as any other microcontroller.

Arduino manages to make the task of programming easier, by providing a few memorable C++ functions, which take care of basic I/O operations, effectively shielding the user from the minutiae of bit manipulation at register level.  It is this hardware/register abstraction layer which makes programming the Arduino so much simpler for beginners.

There is no reason why these user friendly functions cannot be recreated on the ARM. So if you prefer 

digitalWrite(1,HIGH);

Instead of 

GPIO_SetBits(GPIOA, GPIO_Pin_1);

then this is perfectly understandable, and a lot less typing.  Abstracting complex functions to simpler, easier to remember commands is definitely the way to introduce newcomers to programming.  I'll cover more on this in a future blog-post.

For those wishing to remain within the Arduino comfort zone, Leaf Labs has produced an Arduino "look-alike" IDE for their STM32 based Maple, and Maple-mini products.  However, most of their IDE developments have been restricted to Linux platforms, having abandoned the PC as a platform a couple of years ago.

Peripherals

The STM32F303 has a rich set of peripherals including USARTS, Timers, SPI, I2C, ADCs and DACs. Additionally it has programmable gain op-amps and comparators which can help reduce the amount of analogue circuitry needed in an application.  There is also a capacitive  touch-sensor interface allowing user controls to be implemented easily on the pcb.  Almost all of the I/O pins are multi-function, and getting to know what is available where is one of the hardest tasks when first getting started with the ARM.

On the ARMiGo board, I have tried to simplify this by primarily putting the analogue interface signals along one side of the pcb and the digital signals along the other, but a closer inspection of the datasheet will show that further pin-swapping between functions is possible.

ST Microelectronics provide a comprehensive set of "wrapper" functions to assist the user in the process of setting up the peripherals. Ultimately these functions set the individual bit patterns in the peripheral control registers, but abstract a lot of this low level bit manipulation from the user.

In the same way that Arduino has a setup() function where most of the hardware initialisation is performed, I chose to have a separate file, which I call periph_config.c, where I put all of this setup code, and a single function Init(), called from the start of my main code, which calls the relevant functions in periph_config so as to initialise the hardware. It's then an easy matter just to change periph_config when you need a slightly different hardware configuration.

It would be relatively straightforward to automatically generate the periph_config file from some sort of GUI. Here the user would select the various functions needed and the file would be automatically generated.

Applications

ARMiGo is intended to take over when the Arduino just runs out of steam.  It has a 72MHz maximum internal clock frequency, provided from an 8MHz crystal that drives a phase locked loop. So raw speed is available when necessary, but using the clock divider, the 8MHz clock can be divided down to a plodding 125kHz, when much lower power is needed. In this condition the ARM will consume around 1mA.

Full speed USB is available on-chip, and STM have provided source code for CDC, virtual com port VCP and other USB profiles.  As well as being able to communicate directly over USB, as a slave device, with a PC or other device acting as host, all of the STM32 family have an embedded (factory programmed) bootloader which allows firmware to be programmed into the device directly from USB. This is known as DFU - device firmware upgrade.

For communicating with other devices, the STM32F303 has 3 USARTS available, plus SPI and I2C interfaces. In a recent application, I have sent data to a PC using one of the USARTs, at 921,600 baud, whilst using the SPI bus to take readings from a 24 bit ADC (AD7767) at 125kHz sampling frequency. One of the timer channels provides a 1MHz clock signal for the ADC.

The STM32F303 also has four individual 12 bit ADCs, which can sample at 5MHz. Each ADC has a front end multiplexer, allowing up to 4 analogue signals to be read from each ADC. This opens up interesting applications in energy monitoring, or as a low cost multifunction test instrument.  The excellent Miniscope project is based on the STM32F303 - be sure to watch the video of the arbitrary waveform generator - which uses one of the 12 bit DAC channels.

The STM32F303 has up to 35 I/O lines available, making it a little more flexible than Arduino or other ATmega328 boards. However, it should be appreciated that it is a 3.3V part, and whilst the digital I/O lines are 5V tolerant, the analogue ones are not.  This comes as a mixed blessing, as it can interface directly with newer 3V3 devices without the use of level converters, but caution is needed when using in a project that has mixed supply voltage logic.

ARMiGo is a low cost/low tech product to get people started with ARM. Whilst many other boards use ARM devices, the ARMiGo tries to remove to remove the clutter and provide direct access to all ports and peripherals, in an easy to use, plug in module.



Monday, March 10, 2014

ARMiGo - A breakout board for STM32F303 ARM Microcontrollers



As integrated circuits get smaller, and more powerful, it becomes increasingly difficult for the hobbyist to utilise them easily. Soldering tiny SMT parts is a challenge for many - but an amazingly useful skill, once mastered.

32 bit ARM microcontrollers are now virtually the same cost as older 8 bit devices, yet offer a many fold increase in performance, as a result of their 32 bit architecture and faster clock speed. In addition to this, they come with a rich set of peripherals, making them ideal for more demanding applications.

For the hobbyist who may have first gained exposure to microcontrollers via 8 bit products such as the Arduino, the move to 32 bit may appear a little daunting.  However we all have to progress and keep up with the times, and so now the time has come to move up to the "big school".

For a particular microcontroller to gain traction in the hobbyist community, it has to meet a few basic requirements:

1.  Low cost development boards
2. Free to use, open source toolchain
3. Lots of online code examples, projects, forum support
4. Support from a vibrant user community
5. Easy to use and incorporate into projects
6. Easy to upgrade to different devices from within the same microcontroller family


1.  Low Cost Hardware

After some investigation, and triggered into action by exceptionally low cost development boards, I have settled on the ST Microelectronics STM32F range of microcontrollers as being the basis for future projects.

These micros are already being used extensively in a range of hobbyist boards including Maple, Netduino, Olimex, Expruino, mbed, MicroPython and STM's own range of very low cost Discovery boards, which are priced around the range  ($11 - $18).

A recent offering from mbed in collaboration with ST is offering boards for as little as $10, and come complete with a detachable ST Link programmer, which can be used for programming other boards.

These boards are now available from suppliers including Farnell, Newark,  Mouser, Digikey.

Low cost hardware is the new trend, with dev kits often being sold at close to cost price,  so, gone are the days when you forked out £20 for your first Arduino, and then another £20 when you wanted to build it into a more permanent project.

2.  Open Source Toolchain


Free to use toolchains are nothing new. Microchip realised in the 1990's that they would sell more chips if they made the coding tools free. Fortunately the ARM microcontroller is supported by GCC, and there is a free to use IDE,  called CooCox CoIDE, which supports a wide range of ARM chips from several main manufacturers.


3. Lots of Online Support and Code Examples

Getting started with ARM chips is as easy as dowloading the free tools, installing some drivers and learning the basics from a wide range of code examples easily found online.  The STM32 range of microcontrollers have been available for about 4 years now, and so there is a rapidly growing resource of online code examples, reference designs and supporting documentation. ST Microelectronics produces a firmware pack for all of its evaluation and Discovery boards, and this is a good place to start for code examples. Other online examples,  which are easily Googled, are downloadable from repository sites such as Github amongst others. YouTube is also a good place to search for STM32 projects. As the processors are considerably more powerful than 8 bit devices, they are often used with LCD colour displays, and there are several examples of these on YouTube.

4. A Large User Community.

All popular devices build up a loyal user community and the STM32 is no exception.  The popularity is driven by low cost hardware and free tools, and is ever expanding as new products based on the STM32 are released.  Again a simple Google search will often turn up a blog from an enthusiast who has already covered a lot of ground and is happy to share it. 

5. Easy to Incorporate into Projects.

This is where things are not so clear-cut.  The problem with most dev boards is that they are either too big, or use header pin layouts that are incompatible with breadboard or stripboard.  This can be a major inconvenience, and often force the user to buy some form of shield for mounting other hardware expansion, or resort to using female/male jumper leads, so that the headers can be jumpered into a breadboard. Either way the result is not ideal, and a rat's nest of jumper wires is neither permanent nor easy to work with.

6. Easy to move between devices in the STM32 family range.

There are now a considerable number of devices in the STM32Fxxx family, based broadly around the Cortex M0, M3 and M4 ARM architectures. Whilst to the newcomer the range of different parts may seem confusing, STM have designed the family in such a way which makes it relatively easy to move between parts.

The first thing to realise is that they are all microcontrollers, with on chip SRAM, and only the larger packaged parts will support external memory.

Secondly, all parts share identical, or very similar I/O and peripheral architectures, so if you are using USART , or Timer 2 on a 48 pin pack, you will find the same peripherals, and more, in the 64, 100 and 144 pin packages.

Thirdly, you will find that you can switch between family members - because they share common pin-outs. This means if you have designed a pcb for a 48 pin STM32F103, and you want to move up to the STM32F303, then you will find all the ports, clock lines and power pins are exactly the same - so no pcb changes are needed.

Here are some guidelines to selecting a part:

1.  How much I/O will my application require?  The GPIO ports are 16 bits wide, and devices are made with between 2 and 8 ports.  The 48 pin package provides 2 ports PortA and PortB,  the 100 pin package provides 5 ports PortA - PortE.

2. Choose the appropriate amount of flash memory and SRAM.  The smaller parts have 128kB of flash and 32kB of SRAM. The largest parts have 2MB of flash and 256k of SRAM.

3.  Choose the Cortex family member.  M0 is the cheapest with the slowest clock, and generally without USB. M3 is a good starting point with a 72MHz clock and on chip full speed USB.  M4 is similar to M3, but supports clock speeds up to 180MHz and has a floating point unit (FPU) which may be useful for intensive maths code such as used in robotics and flight controllers.

Getting Started.

Initially I bought a Discovery F3 development board, which uses a 100 pin STM32F303 processor and has  compass, accelerometer and gyro devices on the board. It was exceptionally good value at under $11 from Newark.  However, whilst it provided a platform to get me started writing code and getting the framework to support my application built, it was just too big and the double row headers are not the friendliest of connectors to use. I didn't need all of the  80 lines of I/O provided by the 100 pin device,  so I settled on the 48 pin part, which somewhat smaller, cheaper and more manageable in terms of pcb layout.

My solution was to create a 51mm x 19mm  double sided pcb, which mounts the STM32F303 microcontroller,  its clock and reset circuits and USB/programming connectors. This small breakout pcb, converts the pins from the 48 pin LQFP to an easier to use 40 pin dual in line module, and provide the minimum of features to get the STM32 to load and run code.  

This approach is not new and has been used in minimalist products such as the Maple Mini and the Arduino Pro Mini and Nano, all of which have been around for some time.

I decided to name the board "ARMiGo" in respect to its user friendliness and I designed the ARMiGo to be as open and flexible as possible, so that it can be used as a core for incorporation into other designs.  The essential parts of that core are the microcontroller, the 8MHz crystal, the reset circuit, USB connection and programming header. 


The first of the prototypes arrived this week, and now working running some simple test code.

ARMiGo uses the STM32F303 Cortex M4 ARM device which runs at a maximum of 72MHz.  The pcb also supports the STM32F103 which is based on the M3 core.

The board is the same size as a standard 40 pin DIL format IC - making it ideal for breadboarding, and small enough to be used as a plug in module in a 40 pin socket, on a larger board.

All 35 I/O lines of the ARM chip are brought out to standard 2.54mm spaced headers.

The 5 pin right angle header on the left accepts the clock and data signals from the "ST-Link" programmer/debugger device.  These are available very cheaply from ebay/taobao/deal xtreme etc.
However it is relatively simple to use the embedded STM bootloader and program it via either the mini-B USB connector on the right or via one of the USART channels.

There is a really rich mix of on-chip peripherals, which gives these small ARM parts tremendous flexibility - including the following:

Full speed USB interface

4  Fast (5 Msps)  12bit ADCs, each with up to 4 input channels

4 Programmable gain op-amps and 7 comparators

2  12 bit DACs

3   USARTS

3   SPI

2   I2C

RTC with 32768 Hz oscillator and dedicated output pin for "alarm"

10 timer channels,  2 basic,  6 general purpose and 2 advanced:5  General purpose  16 bit timer channels with up to 4 outputs for PWM generation, timing, counting etc.

1 general purpose 32 bit counter/timer - for optical encoder reading etc

2 advanced 16 bit timers for complimentary PWM generation etc.

In addition, the analogue section of the IC contains programmable gain op-amps and comparators which feed the ADC channels, and can be used to replace external analogue circuitry.

This small 48 pin packaged part contains 128KB of Flash and 40KB of SRAM - of which 8K can be battery backed up when the rest of the IC is powered down.

In the attached picture, most of the lower row of pins is the analogue I/O, and the upper row is mostly digital, although there are many options for allocating the peripheral functions to different pins.

With 5MHz 12 bit analogue interfaces it offers greater resolution and much faster sampling speed than Arduino. Additionally the 72MHz clock and 32bit wordsize will all make for a much faster data thoughput.

The combination of 35 I/O lines, on chip USB and a user friendly module, should make ARMiGo the starting point for a wide variety of new projects. Prototypes can now be breadboarded or easily built on stripboard, and the module just plugged straight in.

If you want more details about ARMiGo - please drop a comment.

















Sunday, December 29, 2013

The Elements of Language

Charles H. Moore is one of my all time computer heroes. He has to be up there amongst Kernighan, Ritchie and Thomson for his contribution to computer languages.

In the 1960s, computer programmer Charles H. Moore developed a new programming language that he called FORTH.

He was convinced that there must be an easier and more productive way to  program and interact with a computer and he wanted to create the language tools to do it. Computers at that time were generally mainframes which required the vast resources of assembler, compiler and linker, plus the costly time of specialist computer operators just to generate a program and run it. Moore wanted to develop a self contained programming environment, over which he had complete control, that would allow him to become a more productive programmer. Better programming efficiency would mean less time spent paying for expensive mainframe time.

Moore went on to port FORTH to many different computer systems, and it was also adopted by the homebrew computer community. In the 80's, Moore turned his attention to using FORTH as a machine language, which was executed directly by the microcontroller. He wrote CAD software in FORTH to help him design new ICs, and now in his mid 70's he is still working on state of the art multi-processor arrays which execute a dialect of FORTH.

It is in this spirit that I have spent the last few days tinkering with SIMPL and have borrowed some of the ideas from FORTH. I make no claims that it is a fully fledged programming language, but it does contain all the elements which allow simple programs to be written and run, edited and re-run from the a serial terminal without having to constantly edit and re-compile C code in order to make changes.  It allows the user a greater level of interaction with the program so that ideas can quickly be tried out and changes made with just a few keystrokes.

SIMPL is based on a tiny interpreter called txtzyme written by Ward Cunningham.  Ward initially wrote txtzyme to run on the Arduino, but as it is written in bog-standard C, it can easily be ported across to other micros. During this Christmas week, I have ported my version of SIMPL across to a STM32F4xx ARM Discovery board.

The original Arduino version of txtzyme only has 9 commands, and allows access to basic input, output and looping and timing functions.  The core interpreter is only 90 lines of C code - taking up about 3.6K when compiled for an Arduino. The language is easily extended, as we shall see later.

As stated above, Moore wanted to develop a self contained, comfortable programming environment which involved less typing and a more direct involvement in the program application, rather than the mechanics of compiling and assembling it.

In the same way, SIMPL allows you to perform simple I/O operations directly from the serial terminal, without having to go through the edit-compile-upload cycle every time you wish to make a slight change. Whilst this interactive serial interface makes it easier to experiment directly with the hardware from a serial terminal, the simple character interpreter at the core of txtzyme has much more powerful tricks up it's sleeve.

By way of illustration, I'd like to mention at this stage Java and the Java virtual machine.  Basically any computer, be it PC, MAC or Linux, can be programmed to emulate the Java virtual machine. By sending this virtual machine programs in Java bytecode, any platform can be made to run the same software. Whilst this may be an over simplification of Java, it serves to illustrate how vastly differing platforms can be made to run the same programs.

So now apply this to a range of microcontroller hardware platforms.  Give them the means to interpret a common language, and then you can get them to run the same programs. If this language is an efficient character based language like txtzyme, then programs can be conveyed to the hardware devices using strings of just a few characters, served from a browser interface.  We now have a common language to implement the internet of things, small enough to run on the simplest of 8-bit microcontrollers for the most trivial of applications.

A remote device that is executing one particular program, could easily be reprogrammed with a text string of just a few characters, to execute an entirely different program. This text string could come from a server directly, or via SMS or Twitter or be embedded in a web page or wiki document.

Here, Ward Cunningham explains this concept in a short video

Txtzyme is not only a simple language for microcontrollers to interpret, it is easy to read, write and understand by humans. With each character representing an entire function, a lot can be written in a very short text string.

Take the classic Blinking LED program - say from Arduino, to flash a LED on pin 13, 10 times, for 500mS on and 500mS off.  Here it is in C

for(i==0; i<=10; i++)
{
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}

In txtzyme this becomes just 16 characters:

10{1o500m0o500m}

If you want it to read an ADC channel 5 and print it to the terminal the txtztme is now just three more characters

10{1o500m0o500m5sp}

In C, you would have had to add the following line, recompile and upload again

Serial.println(analogRead(6));

So, to sum up, it's easy to implement the txtzyme interpreter on any micro. It's already available for Arduino, Teensy 1 and 2 and now the STM32F4 Discovery board.  Once a micro can interpret txtzyme strings it may be controlled from any browser or from a Wiki, using the txtzyme plug-in.

To be continued.......




Saturday, December 28, 2013

SIMPL on the STM32F4xx Discovery Board

Back in the summer, I posted some musings about a very small programming language that I named SIMPL  - Serial Interpreted Micro Programming Language. It's an extended version of Ward Cunningham's Txtztme, described as a Nano Interpreter - which is documented here.

Well over the period of the Christmas break, I have had the opportunity to port SIMPL, which is written in fairly standard C, across to the STM32F4 ARM Discovery board. It is now working to the point where I can program simple I/O operations and loops on the Discovery board.

SIMPL is fast on the STM32F4x you can create a pulse as short as 200nS, or toggle a pin on and off at 372kHz. By comparison on the Arduino (using digitalWrite) the pulse time is 10uS and 47.8kHz maximum frequency, though better could be achieved by direct port manipulation.

Ward Cunningham has ported txtzyme to the Teensy board, as a means of controlling hardware over a USB connection, and from a remote server. Ward is using txtzyme to control hardware remotely as part of his Federated Wiki project. A video explaining the project with some demos is here, and well worth a watch for some interesting background.

I've chosen to follow a slightly different route to Ward's project, to use SIMPL more as a programming language, but as the txtzyme interpreter is common to both the Teensy and my ARM implementation, then either hardware can interpret txtzyme strings.

Although SIMPL started off life on an Arduino, it seemed a natural choice to port over to the ARM Discovery board. The additional RAM and program space allow far more elaborate programs to be written, and as the ARM runs at 10 times the clock speed of the Arduino Uno, - the code is blistering quick.  

You might recall that SIMPL is based on an interpreter, which interprets serial character strings and decodes them into functions which are executed in turn.

SIMPL generally uses a mix of small characters and punctuation marks as the primitive command set, and then a capital letter can be used in a similar way to a Forth word, to execute a sequence of commands.

Small characters, maths symbols and punctuation marks are used as the primitives. When encountered by the interpreter, they are used to call a function directly, such as p to print a character, or h to set a port line high.  The maths symbols are used, obviously to allow maths operations to be executes, such as + - * /  and tests such as < and >.  The overall simplicity of using a single ascii character as a command, means that the entire interpreter can be coded as a simple switch-case statement in C.  For example when h is encountered:

      case 'h':                               // set bit high
      digitalWrite(x, HIGH);
      break;

Where the interpreter encounters a number character 0 to 9, these are scanned in, and accumulated into variable x with the correct decimal place shift, for as long as the next character in the buffer is a number. The following few lines of C perform this number interpretation

      x = ch - '0';
      while (*buf >= '0' && *buf <= '9') {
        x = x*10 + (*buf++ - '0');
      }

Punctuation marks are used to help program flow. For example the open and close brace structure defines a portion of code to be repeated as in a loop. Suppose we want to loop some code 10 times, for example print 10 Green Bottles.  The Green Bottles will be printed if it is written thus _Green Bottles_ and the loop structure uses a loop index k, which is decremented each time around the loop. kp will print the current value of k, each time decrementing.

10{kp_Green Bottles_}

Unfortunately p also introduces a newline character, so the output is not quite as desired :-(

Words

In this interpretation scheme, I have reserved the upper case letters to represent "words" - in the Forth sense. In order to maintain the same simplicity in the interpreter, single characters are decoded as calls to the code stored in the word definition.  This may sound confusing, so to illustrate with an example.

Suppose I liked the "Green Bottles" code so much, that I wanted to preserve it and use it again, and again. Well I can do this by making it into the form of a colon definition (again borrowed from Forth), such that I can assign it to a memorable word, say B for bottles.

The colon : tells the interpreter that the next character will be a word, followed by the code that will be executed when the word is called

:B 10{kp_Green Bottles_}

This will place the code 10{kp_Green Bottles_} at a location in memory that can be accessed everytime that the interpreter sees the letter B.  Instead of interpreting the contents of the keyboard buffer, the interpreter is now pointed to a word buffer, containing the code body that makes up B.

This process can be extended by adding together words to make new words

:A   10{B}

This defines A as ten iterations of B, or about 100 Green Bottles!

The word definitions are stored in a RAM array, and the ? command can be used as a means of listing all the current word definitions.

SIMPL is now starting to take the form of a very concise language.  It can handle numbers, character commands from the terminal and perform simple maths. It can perform loops and output numbers and text to the terminal. The next thing is to allow it to access the peripherals and I/O.

SIMPL has been developed to be "close to the hardware".  As almost all microcontrollers have a mix of on chip peripherals, such as timers, ADCs, DACs and general purpose I/O, SIMPL has primitive commands designed to exercise this hardware directly.

For example, suppose you have an output port on Port D13 controlling a LED,  then the command 13h will turn the LED on and 13l will turn it off,  h and l being the commands to set the named port 13, either high or low.

For analogue input from an ADC channel,  the command s for "sample" is used. So to read the ADC channel 10 and print to the terminal, we enter 10sp.

Commands can be repeated within loops using the {  } loop structure.

To read the ADC channel 10, ten times and print the result to the terminal, we use:

10{10sp}

or to slow this down to once a second, we can delay with the millisecond delay m command which puts a 1000mS pause in the loop.

10{10sp1000m}

We can now put a few of these commands together so as to flash the LED for 100mS each time we take an ADC reading

10{10sp900m13h100m13l}

Note that we are still looping 10 times,
reading ADC channel 10 and printing it out,
pausing for 900mS,
setting LED 13 high,
pausing for 100mS,
setting the LED low,
returning to the start of the loop.

So it's quite easy to build up complex commands, just by concatenating a few primitives together.

What if you were to write this in C? It would be somewhat longer, about 8 to 10 lines of code, and then need to be compiled, tested, and if you weren't happy, edited and compiled again. SIMPL breaks us out of the edit, compile, test cycle, and allows ideas to be tested quickly and easily, straight from the terminal.

This was exactly what Forth language pioneer, Charles Moore realised in the mid-1960s. He too wanted to break free from the edit-compile-test cycle, in order to improve his efficiency in coding, as computer time was expensive back then, and also to make himself no longer reliant on compilers and assemblers that he had no control over.  He wanted to develop a self-written, self-contained programming environment that could easily be moved from one system to another, and require few and simple resources to get it running.

If you are interested in the early history of Forth, Charles "Chuck" Moore describes the early development of the language here:

History of Forth

Whilst SIMPL is not Forth, and never will be, there are several nice techniques borrowed from Forth, which are used to enhance SIMPL.

We have come a long way since the early development of the computer languages, such as C and Forth, which were often hosted on very primitive machines, with limited RAM and tiny disks by today's standards.

One early machine, the PDP-8, was of a simple enough architecture, that it has often formed the basis of study in computer science courses. Additionally, the PDP-8 has been implemented in many different technologies over the years, including TTL, VLSI and as a FPGA implemented in Verilog or VHDL.

The reason for interest in the PDP-8, is that whist primitive by machine standards now, it represented a revolution in architecture simplification, such that the whole system could be sold for $18,000 back in 1965. It was the first of the true minicomputers, available at a tenth of the cost of competing systems.

Additionally, the PDP-8, is comparable in resources to those that we find on a low cost microcontroller, costing a few dollars. So the practices used in the 1960s to write code for the early minicomputers has significant relevance these days.

Whilst generally we use open source C compilers, such as GCC, and integrated design environments (IDEs) to develop programs, there is no reason why a simple interpreted language, running in the background would not make sense, when developing applications on a new microcontroller. It puts the control of the hardware, directly at your fingertips and allows quick experimentation.

Modern 32 bit microcontrollers, such as the ARM range of cores, are now rapidly replacing 8-bit devices in a range of applications, at very little additional extra cost. The resources and peripherals available on a typical ARM device, are vast compared to 8-bit processors, and with clock speeds roughly ten times faster, a huge amount of processing power is available, compared to only a few years ago.

With clock speeds in the 100-200MHz range, it's now perfectly possible to host an interpreted language on the microcontroller, and have it run at speeds only previously available through the compiled language route.

SIMPL consists of an interpreter running within a loop.  The interpreter is written in about 300 lines of standard C, and additionally includes several I/O and memory functions, which are tailored to the particular microcontroller, to create a standardised machine model.

To the Arduino user, these I/O routines will be familiar:

digitaRead                               Read the state of a digital input
digitalWrite                             Write a digital output high or low
analogRead                              Read the value of an ADC channel
analogWrite                             Write a value to an analogue PWM or DAC channel
delayMilliseconds                   generate a delay in mS
delayMicroseconds                  generate a  delay in uS
printNum                                  print an integer number to the terminal
putChar                                    print an ASCII character to the terminal
getChar                                     read an ASCII character from the keyboard or terminal input buffer

All microcontrollers for embedded applications should have the hardware means to execute these routines, and although setting up the I/O and peripherals may take a bit of time on an unfamiliar hardware device, once done the basic routines will be used frequently in any application that may be developed.

delayMilliseconds can simply be derived from 1000 times around the delayMicroseconds loop, or can be derived from a hardware timer, depending on the device.

Whilst putChar would normally send a character to the UART transmit buffer, it might instead be used to bit-bang an output pin, if no UART is available. Fortunately most microcontrollers have one or more UARTs available these days, so bit-banged serial comms is less of a requirement.

printNum is just a convenient means of getting integer numerical output from the microcontroller. It will use the C routine "integer to ASCII" and putChar to send an integer to the terminal.

getChar is intended to read in a character at a time either directly from the keyboard or from the terminal input buffer.

With these routines, you can now interface to a serial terminal, read and write to I/O lines, read analogue inputs and control PWM or DAC outputs.  With the ability to specify accurate delays to give a sense of timing to the program flow, there is little else that the micro needs to do, except perhaps for memory operations.

Thanks for the Memory

In bygone days, when microcontrollers had very little memory, it was easy to get obsessed about the placement of code and data within memory. Memory was a precious commodity, and it was necessary to squeeze your program and your data into what little memory was available. Every byte was precious, so clever tricks were devised to pack data into as few bytes as possible.

These days, this is not so much of a problem.  The STM32F407 has a 1Mbyte flash for program and storage of constant data, and 196Kbytes of SRAM, 4Kbytes of which can be battery backed and made non-volatile. Other STM32F4xx family members have 2Mbyte of flash and 256Kbytes of SRAM. This might not seem much by PC standards, but for an embedded application it is more than plenty.

To be continued.








Friday, December 27, 2013

Discovering the STM32F407 - first steps into ARM territory

Having tinkered with the Arduino and it's clones for a few years, the opportunity arose to move up to a much more powerful 32-bit ARM Cortex M4 device, which is now available cheaply.

The ARM is a somewhat more complex device than the humble 8-bit Atmel AVR so it took a little while to get things up and running to the point where I could do useful development work with it.  I hope that this blog post will be a help to anyone else considering such a move.

If you read some of the historical documents describing the development of computer languages in the 1960s and early 1970s, there is a common underlying theme - the desire of the computer pioneers to make things quicker and easier and create a more comfortable programming environment.

Ken Thompson, who wrote 'B', the precursor of C had a very limited DEC PDP-7 at his disposal, and according to Dennis Ritchie in the 2003 C History paper "Thompson wanted to create a comfortable computing environment constructed according to his own design, using whatever means were available."

Similarly, Charles Moore, creator of the Forth programming language, describes in his Forth history, how he continually strove to make things simpler, so he could focus on the application and not get bogged down in the primitive tool set.

So, in true tradition, when encountering a 32-bit ARM microcontroller for the first time, I wanted to get things quickly up and running and get it within my comfort zone, and treat it like any 8 bit or 16 bit mcu, such as the AVR.

ST Microelectronics have licensed ARM cores for several years, and have encouraged newcomers to their product by way of very low cost development boards.  The STM32F4 Discovery board, which is a target for the ARM Cortex M4 microcontroller is available for as little as £10, or $15 in the US.

If you have come from an Arduino background, here is a low cost board, bristling with 80 I/O lines, an accelerometer, an audio codec and a built-in programmer/debugger which runs at 168MHz.  Compared to the Arduino it runs at 10.5 times the speed, has 32 times the Flash and 98 times the SRAM, all for less than the cost of a Uno.

All those I/O lines take a little getting used to, as many of them are shared between the various on-chip peripherals, and you need to do a little bit of configuration work to make sure you have access to the mix of peripheral functions needed by your application.

One approach is to arrange the I/O and peripherals into a familiar format - and it is not unsurprising that the peripherals are a good match to the Arduino resources. In one configuration we can get:

4  USART Serial ports
3 SPI interfaces
12 ADC Inputs
2 DAC Outputs
2 I2C interfaces
12 PWM channels
2 Quadrature encoder channels
Numerous digital I/O

So in terms of I/O resources, the Discovery is a good approximation to the Arduino Mega, or Due but with a good speed and memory advantage.

The downside for newcomers, is that it does not come with the Arduino IDE, but this is not altogether a bad thing, because it encourages you to broaden your horizons and finally cut the Arduino apron strings.

All of the tools needed to program and debug the Discovery board are available open source, and very quickly you can be programming your application code. However, it's always good to take a few old friends along on any voyage of discovery, so here's how to get the basics up and running for the newcomer.

First you should install the IDE from CooCox. You can download their CoIDE from here

Additionally you will need to install the GCC toolchain - which is accessible from the CoIDE page.

The Discovery board has it's own on-board programmer/debugger known as the STLink.  You will also need to download the driver for this - again available from the CoIDE page.

There is now a rapid increasing number of user examples of Discovery code.   A quick search will bring up several good resources e.g.

https://github.com/k-code/stm32f4-examples

Lastly, ST Microelectronics have released a standard peripherals library, and a good range of examples and application notes to support their dev kit.   You might want to look through their examples here

The standard procedure for getting any microcontroller up and running, is to initialise a UART, and as a bare minimum provide the means to get serial input and output. Once this is achieved, debugging becomes a whole lot easier, and as likely as not, the final application will need serial communications - so it's not wasted effort.

The STM32F407 on the Discovery board is provided with up to six UARTS of which 4 are USARTS - meaning that they can handle both synchronous (clocked) and unsynchronous serial comms. Whichever USART is chosen, there is a certain amount of initialisation code to be executed first, and then some relatively simple code to handle character input and output.

Once the UART is up and running, you have the means to send numerical debug information to a serial terminal, and to control programs using simple serial commands.

One method I have used many times is a simple serial command interpreter based on a switch/case statement.  It uses an alpha command and a numerical argument.  For example, in a motor drive application, the serial  command F100 could be entered to make the motor run forwards at 100rpm, and R100 would reverse it at 100rpm.  These simple serial commands are easy to implement and a quick way of proving that your hardware and the various driver routines are working. Each new project I have worked on for the last few years has had some variant of this serial command interpreter programmed in as a prerequisite.

The other on chip peripherals are initialised using a similar set of functions. Most importantly is to remember to enable the clock to both the GPIO port you are using AND the peripheral you wish to use. Failure to do this is a common cause for non working peripherals.

The main.c routine posted up to Github Gist enables a number of peripherals:

USART1 and USART 2 for serial communication with a host computer.
ADC1, six 12 bit ADC channels enabled
Timer 2 and Timer 5 for 32 bit pulse counting (quadrature encoder) applications
Timer 1 for three complementary PWM channels for motor drive etc
Timer 3 is used to generate three independent PWM signals
Timer 4 is set up as a milliseconds tick timer
GPIO D is set up to have four general purpose outputs, used to drive the on board LEDs.

Further initialisation routines will follow to allow the SPI and I2C interfaces to be accessed, for SDcard and EEPROM devices. This will be covered in a later post.




Sunday, June 02, 2013

Extensions to SIMPL

In the last week I have been thinking about the user interfaces used on minicomputers of the 1960s, in particular the PDP-8, and wondering if a similar front LED and switch panel could be created cheaply as a nostalgic retro accessory shield for the Arduino.

I have added some LEDs to the 12 available digital I/O pins of the Arduino, so that I can recreate LED chaser and "vintage computer" style displays.

I've extended the SIMPL command set so that I can more easily address each LED in turn, or alternatively treat all twelve as a binary numerical display, to display address or data numbers in the range 0 to 4096.

The latest version of SIMPL can be found here on Github Gist:

https://gist.github.com/anonymous/facc9a262c0778aec7b6

Just download the Gist and compile it as an Arduino sketch.  You can then start typing SIMPL commands using the serial monitor window at 115200 baud. Make sure that you have selected the "Both NL and CR" option for the serial monitor.

Output Commands

In order to gain more immediate access to the I/O, I have added some new commands:

a   - sends an analog.Write value to a pin previously named with d
b   - prints out the current value of the milliseconds counter, allowing loop timing to be calculated
c   - prints out the current value of the microseconds counter

h   - sets a digital pin high    eg  6h
l    - sets a digital pin low     eg 13l
n   - decodes a number up to 4095 and displays it on digital pins 2 to 13     eg  1234n

n can be thought of as a very simple binary display.  It has a fast response time and allows the user a simple visible means of checking that a program is executing.

The n command can be useful to examine the characters stored in RAM.  Here it is used to output 1000 characters to the LEDs, starting at RAM address 256.  The characters are sent every 100mS and also printed to the terminal.

255!1000{y@rn100m}

255!    Store 255in y as the starting RAM address
1000{  Perform the loop 1000 times
y         Increment y each time around the loop
@        Move y into x
r          read the contents of RAM into x
n         Send the value to the LED display
100m   100mS delay to slow things down to a sensible speed
}         End of the loop

Decision Making

SIMPL currently lacks the if, then, else decision making, or the switch case structure. This would be a useful addition and I am currently working on some ways of implementing it.

It might be possible to test the x value against certain constants and then execute one of the upper case routines if the test was equal.

Other SIMPL Commands

SIMPL instructions are a mix of lower case ASCII characters, symbols and punctuation marks. These are the primitives, which are interpreted in sequential order by a simple interpreter.  The interpreter is an extension of Ward Cunningham's Txtzyme interpreter, which recognises the following:

a          Send an analog write (PWM) value to a pin
b          print out the current milliseconds count
c          print out the current microseconds count
d          define a digital port pin
e
f
g
h          set pin high
i           read an input
j          skip next instruction
k          access the loop counter
l           set pin low
m         define a delay in milliseconds
n          display a number on a line of LEDs
o          set an output
p          print the x variable to the terminal
q         query a block of RAM locations ( as character)
r          read from RAM
s          read an analogue input
t
u          define a delay in microseconds
v
w         write to RAM
x          increment x
y          increment y (as used in incrementing loop structures)



{}       loop the code contained within the braces

@       copy y to x
!         store x in y
?        Dump the contents of RAM to show the existing words

+
-
*
/
<
>


Numbers can be typed in the range  0 to 65535 and are stored in the x variable and used to control the above instructions.

eg.   6d            define digital port pin 6
       100m       define a delay of 100mS
       10{....}    go around a loop 10 times
       20p          Print 20 to the terminal

To these basic instructions I added a y variable, so that I could do simple maths.  You can store a number in y by using the store symbol !

      20!          Stores the value of 20 into y (by transferring it from x)

To get the contents of y back, we use the fetch symbol  @

     20!@p      Prints the value of 20 from y

We can do simple addition, subtraction, multiplication and division on x and y

     20!5+p      Adds 20 to 5 and prints result       (x=x+y)

     5!30-p      Subtracts 5 from 30 and prints result  (x=x-y)

     16!8*p     Multiplies 8 by 16 and prints result     (x = x*y)
    
     6!30/p       Divides 30 by 6 and prints result      (x=x/y)

Downloading the SIMPL sketch from Github Gist and programming it into a standard Arduino is the first step to discovering a new way to control physical computing devices.

Saturday, June 01, 2013

Extending SIMPL and flashing a few LEDs

I have been experimenting with SIMPL, and have added a few new commands to give it greater functionality.

I've wired Digital outputs 2 to 13 to a line of 12 LEDs, to give a very simple means of displaying numerical values.  It also allows LED chaser displays to be tinkered with.

I have added a command to allow the analogWrite function to control an output pin.

Name the pin first, e.g.  6d and then  the PWM value  such as 127a  This sets the PWM to about 50%  duty cycle.

I've also been investigating how fast the commands run, so added a couple of timing commands  b and c.   b prints the current value of the millisecond counter millis(), so typing b before and after a list of instructions will allow you to calculate how many milliseconds it took to execute.  c does the same, but uses the microseconds counter micros().

By timing 10000 cycles of a loop, I can show that SIMPL will add two 16 bit integers in about 6 microseconds.

I have added some commands for easier control of the I/O.    h and l are now used to set a port pin high or low  eg. typing 6h and 5l will immediately set those pins high and low.

After my experiments with LED chaser displays, I also wanted a way to immediately write an 8 bit number to 8 consecutive LEDS.  So the "n" command  displays a number on a row of LEDs.

Typing 255n will turn all the LEDs on Digital 2 to Digital 9.

To make incrementing loops easier, the command "x" now increments x and "y" increments y.

0!10{y@p}

This prints out the numbers from 1 to 10.    0! sets y to zero,    y increments the y variable.

The q,  r and w commands have been used to access the RAM.

300r will print the character stored at address 300.




SIMPL instructions are a mix of lower case ASCII characters, symbols and punctuation marks. These are the primitives, which are interpreted in sequential order by a simple interpreter.  The interpreter is an extension of Ward Cunningham's Txtzyme interpreter.  SIMPL now recognises the following lower case instructions:

a          Send an analog write (PWM) value to a pin
b          print out the current milliseconds count
c          print out the current microseconds count
d          define a digital port pin
e
f
g
h          set pin high
i           read an input
j          skip next instruction
k          access the loop counter
l           set pin low
m         define a delay in milliseconds
n          display a number on a line of LEDs
o          set an output
p          print the x variable to the terminal
q         query a block of RAM locations ( as character)
r          read from RAM
s          read an analogue input
t
u          define a delay in microseconds
v
w         write to RAM
x          increment x
y          increment y (as used in loop structures)



{}       loop the code contained within the braces

@       copy y to x
!         store x in y
?        Dump the contents of RAM to show the existing words

+       Add x and y
-        Subtract x and y
*       Multiply x and y
/        Divide x and y
<      Is y < x
>       Is y > x

A Little Nostalgia

In the decade that spanned the 1960s, the cost of computers fell by about two orders of magnitude, and with volume manufacture possible, they found their way into general scientific engineering and industrial use.

One area of science that particularly benefited from more widely available computing power, was that of biomedical research.  Two computer designs, in particular, spurred on this advancement,  the LINC of 1962, and the PDP-8 of 1965.

About 50 LINC machines were built, and a few survive today. This video shows a restored LINC in use.

http://www.youtube.com/watch?v=atJUnQN65dE

These were the first "benchtop" designs, and set the trend in design for the machines that were to be known as minicomputers.  In 1965 the PDP-8 cost $18,000, still a huge amount of money, but cheap enough to be built in volume and satisfy the needs of university laboratories.

Both the LINC and the PDP-8, owed their design to the general purpose digital modules, that were manufactured by DEC from the late 1950s onwards. Each machine was a pared down 12 bit design, cost engineered for efficiency at every level, offering a machine capable of real work for a modest price.

Over the next 20 years, the PDP-8 architecture was to be revisited many times, as advancements in   logic ICs and memory allowed significant cost savings to be made.  The original PDP-8 was the size of a small fridge, within 10 years it was housed in a single 19" rack.  The very last PDP-8 machines used a microprocessor (Intersil/Harris 6120) to implement the CPU.

By the mid 1970s, microprocessors were starting to appear, which led to the era of 8-bit microcomputers.  Some of these, such as the MITS Altair 8800 paid homage to the style of the PDP-8 with a front panel of many LEDs and programming switches.  The simple LED indicators allowed the user to see precisely what the registers were holding, and the switches allowed simple programs to be "toggled" directly into memory.

These machines are now approaching 50 year old , yet there are many enthusiasts who started their scientific or engineering careers programming such computers.  The National Museum of Computing at Bletchley Park owns an early PDP-8, which they have restored to working order.  They have made a series of short videos depicting its operation.

Here's how a short program is loaded into the machine from the front panel switches.

http://www.youtube.com/watch?v=DPioENtAHuY

Notice how much noise was present in a typical computer room.  Fans, printers and teletypes produces a near constant din.

The machines were relatively slow and simple by today's comparison,  capable of some 300,000 instructions per second. Nevertheless, they were capable of real work, despite their limitations in speed and memory.

In the mid 1960s, the standard user interface was a teletype printer with paper tape punch and reader. Programs would be loaded into the memory from paper tape, but often only after a simple tape loader had been manually toggled into the machine from the front panel switches.

The second of the NMOC videos shows how program on the the paper tape was loaded into memory.

http://www.youtube.com/watch?v=SOOFHFnB0D8

Application programs had to fit within the 4K memory limitation.  This video shows a Chess program, and the user interaction using the ASR33 Teletype, that was supplied with every PDP-8.

http://www.youtube.com/watch?v=OyDufWHsNVE

Contemporary to the LINC and the PDP-8 was a low cost magnetic tape drive, commercialised by DEC as the DECtape.  The last of the NMOC videos, shows the DECtape in use

http://www.youtube.com/watch?v=TWTpYUTbW8s