Every year, around this time, I get interested in improving my central heating control system. With time off work, and heating being very important over the Christmas break, it's easy to start thinking that there must be a better way to improve the average home's heating controls.
UK homes, are by European standards, very poorly insulated and the average heating controls are very primitive. This combination makes for poor heating efficiency, and in times of rising fuel prices the cost of heating a UK house starts to get expensive.
A basic heating controller consists of little more than a timeswitch and a room thermostat. Very often the thermostat has been located in the hall, and often close to a radiator. This is the worst possible arrangement. Nobody spends much time in the hall, and as soon as the hall is at the set temperature, the heating will turn off - often leaving the other rooms of the house poorly heated.
The thermostat should be located in the room that you spend most time in, generally the living room, and it should be located at a suitable position and height to give an accurate reading of room temperature, free from draughts and the direct effect of any heat sources. If you live in an older house with solid brick walls, the thermostat should not be fixed to an outer wall - as these can be colder than the rest of the room, or an internal wall.
With the advent modern wireless devices, it is now common to have a wireless thermostat. This makes it possible to sit the thermostat in any convenient position, and if you spend a lot of time sitting on the sofa in winter, then having the thermostat on a coffee table, or low bookshelf is a convenient and practical place to put it.
Thermostats are becoming more sophisticated, often with the timeswitch function built in. These combined units are called wireless heating controllers and are generally battery powered - however they perform the same basic function, of turning on the boiler at a time when heat is demanded.
I've had a wireless thermostat for about the last 8 years, since I put in a new boiler in 2005. It's a simple device, by Drayton, and every 15 seconds sends a wireless packet to a receiver device, the packet corresponding to either a "boiler on" or "boiler off" request. As a safety feature, the receiver will automatically turn off the boiler if a valid packet is not received for a given time period. This is to prevent the boiler being left on if there is a block in the wireless signal, or if the batteries in the sender unit are exhausted.
The Drayton unit was easy to hack, and it was just a case of replicating the two boiler control packets at the right baud rate, using an ON-Off_Keyed (OOK) 433MHz transmitter, and the Drayton receiver was easily fooled into thinking that it was seeing packets from a legitimate Drayton thermostat. This quick hack has served me well, and I have had an Arduino controlling my heating since Winter 2009.
However, in the last couple of years, there have been some great advances in open source hardware, and with new devices available, it's time to revisit the home heating arena, and see what can be done to improve the system.
As heating fuel costs rise by some 10% per year, an external insulation is not really an option right now, the only way to reduce bills is to have the heating on for less time. This can be done by a combination of the following means:
1. Turning down the thermostat,
2. Reducing the time of the heating periods,
3. Heating less rooms - or adjusting TRVs to lower individual room temperatures
4. Not heating the water unless you really need it, and only as hot as you need it
5. Limit the heating in milder weather
6. Make small lifestyle changes to help reduce heating demand
Over the Christmas break, or at weekends and other times of high home occupancy there will be noticeably different demands put on the heating, compared to normal workdays where the house is seldom occupied during the day. However, I found that when I was working from home for long periods between 2003 and 2009, it was easier to maintain a better control over the heating and minimise gas consumption.
In older houses, it is often better to keep them heated at a low temperature than cycle the heating on and off twice a day. Once the fabric of an older house has cooled down, it takes considerable heat to get it back to a comfortable temperature.
So what features would make a better heating controller?
1. User friendly graphical display with simple user interface
2. Bath Boost - heats just the hot water tank and tells you how long it will take to reach temperature.
3. Comfort Indicator - RGB LED lets you know if your room is in the comfort zone.
4. Simple button interface "Increase Comfort" "Reduce Cost" - the choice is yours
5. Link to remote web interface
Not all of these requirements are easily met with one device, and so a practical system is likely to be based around two or possibly three modules. This modular approach allows the basic system to be set up first, and then further sophistication added later, if desired. I anticipate a system with three main devices:
1. A wireless operated relay unit to switch the boiler and any motorised valves for selecting heating or hot water or both.
2. One or more wireless thermostats located in the main rooms. One will have a graphical display and user interface.
3. A web interface for remote monitoring, control and update of the time and temperature program.
The simplest system consists of the wireless thermostat and the wireless relay unit. This is the equivalent of the most basic of commercial systems, but will be lacking in any real user interface.
The next level would be to replace the single wireless thermostat with a combined graphic display unit with user interface. The interface would be limited to a few buttons, so without an elaborate menu system might prove a little tricky to program.
The top level system would include a web connected microcontroller, providing a browser based user interface and full functionality for programming, remote control and monitoring. One possible, and popular candidate for this would be the Raspberry Pi - fitted with a suitable wireless interface so that it can communicate with the thermostat and the relay board.
The Hardware.
The open source hardware community is good at coming up with useful building blocks from which to construct a better heating controller. Central to this is a proliferation of low cost wireless enabled hardware, usually based on Arduino clones.
One particularly well matched unit is the GLCD module from openenergymonitor.org This is an Arduino compatible backlit LCD Graphic display fitted with a temperature sensor, LDR light sensor, 3 user buttons, red-orange-green LEDs and a RFM12B wireless device - compatible with the JeeNodes library. This will form the basis of the User Display. It can be located in the living room, in a suitable position to act as the thermostat, temperature display and user interface.
Secondly, we need to replace the existing time-clock/controller with a pair of wireless controlled mains relays. These allow the boiler, circulation pump and motorised valves to be switched, depending whether heating and hot water are needed.
This requires a special relay board to be designed - an early draft layout of this is shown below:
This board is still in final design stage, but is expected in a month or so.
It provides three mains relays, and a simple button and LED interface - for local manual control of the relays.
Additionally it can support a variety of temperature sensors - including thermistors and DS18B20 one-wire sensors.
It has wireless module and real time clock, and will accept a variety of microcontrollers, including the ATmega1284 and the RFMPi69 module from Open Energy Monitor.
---------------Getting along in the 21st Century with half the baggage you carried in the last.------------ /*************************Low cost electronic solutions for a low impact lifestyle.************************/
Sunday, February 22, 2015
Useful Hardware Helper Functions
As microcontrollers continue to offer ever increasing performance and overwhelming arrays of sophisticated on-chip peripherals, the task of getting an unfamiliar mcu up and running may at first appear very daunting.
One approach is to use a small library of useful helper routines, which allow you to achieve the basics, and confirm that the hardware is indeed working.
Most microcontrollers, these days come with some form of in-circuit serial programming capability, generally incorporated into the IDE - which makes loading a hex file into flash, quick and easy.
Every microcontroller needs a minimum hardware support system, consisting of a power supply, a clock oscillator and reset circuit. It's also a very good idea to make a serial communications (UART) port available - and the standard 6 pin "FTDI" USB cable connection, makes a very simple way of both powering and communicating with the fledgling target hardware.
For decades a program to print "Hello World" was normally the first program to be written for any new system, but for the microcontroller, turning on and off a LED connected to a digital output is often the best way of proving that there is indeed life in the target board.
This involves writing to two of the on-chip registers. Usually one defines the direction of the port lines - whether they are configured as input or output - sometimes called the Data Direction Register. The second is the Port Register itself, from which the port data can be written to or read from.
Arduino effectively deals with the low level register interaction with the pinMode, digitalWrite and digitalRead functions - and the equivalent of these are needed in your armoury for whichever micro you are dealing with.
The ability to change the state of an output pin, when entering or leaving a block of code, provides a simple but effective debug method. I often use an oscilloscope to check for changes of pin state, but a LED or even a small speaker could provide an indication of pin activity.
With high clock rates, code execution speed can be very fast - even when writing in a high level language such as C. Some means of introducing program delays is needed to slow things down to a more sensible speed. The simplest delay is a for loop, and by executing a for loop multiple times, delays of some microseconds can be achieved.
Suitable nesting of the microsecond delay loop can be used to achieve millisecond delays, but it should be noted that these are blocking delays, and the micro cannot execute any other task whilst in the middle of a delay. They are fine for initial debug, but generally should not be used in real code. As most microcontrollers have counter timer peripherals, these can be used to provide system tick or millisecond counting, which can be used later on for non-blocking delays and other task timing functions.
With a controllable delay and the means to change the state of an output pin, we are now in the position to flash an LED - and this is the classic "Blinky" popularised by Arduino. However, with time-controlled I/O operations it is possible to write functions to provide "bit-banged" serial communications, and this was often done where there was no on-chip UART provided. Bit-banging is a simple but powerful technique and can be used to communicate with shift registers or even SPI devices.
So with the means to provide serial output, we are close to sending characters and numerical output to a terminal program.
The simplest serial operation is to send a single ASCII character to a terminal - and in C this is generally called putchar. Using putchar with characters from an array, allows operations such as memory dumps to be performed and even simple file transfer. I often combine putchar into a function I call printnum, which provides the means to send an integer number to a debug terminal.
As most microcontrollers have an on-chip UART, it's fairly simple to write a version of putchar to send a character to the USART transmit register. To avoid embarrassment, it's best to check the UART Tx status flag first, to ensure that the UART has finished sending the previous character, before the next is loaded.
The complementary function to putchar in C is getchar. This reads the UART Rx register and returns any character that may be present in the Rx register. Once again the status flag should be read to wait for the character to be clocked in, before the Rx register is read.
The story so far....
We now have a small collection of 8 routines which will allow us the basis of input/output, timing and serial communications:
pinMode
digitalWrite
digitalRead
delayMicroseconds
delayMilliseconds
putchar
printnum
getchar
These routines can be considered the fundamental building blocks of any high level application as they are the ones that interact with the peripheral registers at the lowest level.
With these in place, others can rapidly be implemented to handle other peripheral functions that might be present such as ADC, Timers, SPI etc
analogRead
pwmWrite
spiRead
spiWrite
And a very useful millsecond counting function millis() will help immensely with programing time-keeping tasks and implementing non-blocking longer delays.
One approach is to use a small library of useful helper routines, which allow you to achieve the basics, and confirm that the hardware is indeed working.
Most microcontrollers, these days come with some form of in-circuit serial programming capability, generally incorporated into the IDE - which makes loading a hex file into flash, quick and easy.
Every microcontroller needs a minimum hardware support system, consisting of a power supply, a clock oscillator and reset circuit. It's also a very good idea to make a serial communications (UART) port available - and the standard 6 pin "FTDI" USB cable connection, makes a very simple way of both powering and communicating with the fledgling target hardware.
For decades a program to print "Hello World" was normally the first program to be written for any new system, but for the microcontroller, turning on and off a LED connected to a digital output is often the best way of proving that there is indeed life in the target board.
This involves writing to two of the on-chip registers. Usually one defines the direction of the port lines - whether they are configured as input or output - sometimes called the Data Direction Register. The second is the Port Register itself, from which the port data can be written to or read from.
Arduino effectively deals with the low level register interaction with the pinMode, digitalWrite and digitalRead functions - and the equivalent of these are needed in your armoury for whichever micro you are dealing with.
The ability to change the state of an output pin, when entering or leaving a block of code, provides a simple but effective debug method. I often use an oscilloscope to check for changes of pin state, but a LED or even a small speaker could provide an indication of pin activity.
With high clock rates, code execution speed can be very fast - even when writing in a high level language such as C. Some means of introducing program delays is needed to slow things down to a more sensible speed. The simplest delay is a for loop, and by executing a for loop multiple times, delays of some microseconds can be achieved.
Suitable nesting of the microsecond delay loop can be used to achieve millisecond delays, but it should be noted that these are blocking delays, and the micro cannot execute any other task whilst in the middle of a delay. They are fine for initial debug, but generally should not be used in real code. As most microcontrollers have counter timer peripherals, these can be used to provide system tick or millisecond counting, which can be used later on for non-blocking delays and other task timing functions.
With a controllable delay and the means to change the state of an output pin, we are now in the position to flash an LED - and this is the classic "Blinky" popularised by Arduino. However, with time-controlled I/O operations it is possible to write functions to provide "bit-banged" serial communications, and this was often done where there was no on-chip UART provided. Bit-banging is a simple but powerful technique and can be used to communicate with shift registers or even SPI devices.
So with the means to provide serial output, we are close to sending characters and numerical output to a terminal program.
The simplest serial operation is to send a single ASCII character to a terminal - and in C this is generally called putchar. Using putchar with characters from an array, allows operations such as memory dumps to be performed and even simple file transfer. I often combine putchar into a function I call printnum, which provides the means to send an integer number to a debug terminal.
As most microcontrollers have an on-chip UART, it's fairly simple to write a version of putchar to send a character to the USART transmit register. To avoid embarrassment, it's best to check the UART Tx status flag first, to ensure that the UART has finished sending the previous character, before the next is loaded.
The complementary function to putchar in C is getchar. This reads the UART Rx register and returns any character that may be present in the Rx register. Once again the status flag should be read to wait for the character to be clocked in, before the Rx register is read.
The story so far....
We now have a small collection of 8 routines which will allow us the basis of input/output, timing and serial communications:
pinMode
digitalWrite
digitalRead
delayMicroseconds
delayMilliseconds
putchar
printnum
getchar
These routines can be considered the fundamental building blocks of any high level application as they are the ones that interact with the peripheral registers at the lowest level.
With these in place, others can rapidly be implemented to handle other peripheral functions that might be present such as ADC, Timers, SPI etc
analogRead
pwmWrite
spiRead
spiWrite
And a very useful millsecond counting function millis() will help immensely with programing time-keeping tasks and implementing non-blocking longer delays.
Big Computer -Little Computer
Early in 1963, a couple of engineers from the recent technology startup company Digital Equipment Corporation (DEC), drove up to Ontario, Canada to visit a nuclear science laboratory at Chalk River.
The scientists at Chalk River wanted a custom digital control system to monitor a nuclear reactor and pass data back to their mainframe computer. The DEC senior engineer, Gordon Moore, realised that rather than building a custom piece of dedicated equipment for the Chalk River Labs, the job could be done much more easily with a very small programmable computer, and so the minicomputer was conceived.
The PDP-5 was a revolutionary design, and a champion of minimalist digital design - yet it still occupied 2 full sized equipment racks - as can be seen from the photo below.
What the PDP-5 offered for the first time was an affordable computer, and at $50,000, it was a lot cheaper than it's nearest competitor. It was cheap enough to use for scientific monitoring, and as it was fully programmable - could be applied to many different tasks. It could also be used as a data source for a larger mainframe, allowing the mainframe to get on with other tasks whilst the PDP-5 collected data.
This was one of the first examples of what I'll call Big Computer -Little Computer - a combination two machines of widely differing sizes connected together, in order to make a more overall flexible system.
The PDP-5 was by today's standards a very simple machine. In fact a $10 Arduino is many times more powerful than the PDP-5. But, as the predecessor of the renowned PDP-8, which using an instruction set based on that of the PDP-5, launched in Spring 1965, the minicomputer revolution. This led to the start of the microcomputer revolution, about 10 years later, in December of 1974 with the launch of the Altair 8800. The rest, as we say, is history.
The Big Computer - Little Computer concept has been exploited many times as a means of achieving functionality that exceeds the "sum of the parts".
Recent Examples.
In October 2011, ARM Holding announced their big.LITTLE heterogeneous computing architecture where relatively low power smaller cores are coupled to larger, power hungry devices, to give an architecture that can respond efficiently to dynamic changes in computing load, than just clock frequency scaling of the larger cores could achieve.
The scientists at Chalk River wanted a custom digital control system to monitor a nuclear reactor and pass data back to their mainframe computer. The DEC senior engineer, Gordon Moore, realised that rather than building a custom piece of dedicated equipment for the Chalk River Labs, the job could be done much more easily with a very small programmable computer, and so the minicomputer was conceived.
The PDP-5 was a revolutionary design, and a champion of minimalist digital design - yet it still occupied 2 full sized equipment racks - as can be seen from the photo below.
What the PDP-5 offered for the first time was an affordable computer, and at $50,000, it was a lot cheaper than it's nearest competitor. It was cheap enough to use for scientific monitoring, and as it was fully programmable - could be applied to many different tasks. It could also be used as a data source for a larger mainframe, allowing the mainframe to get on with other tasks whilst the PDP-5 collected data.
This was one of the first examples of what I'll call Big Computer -Little Computer - a combination two machines of widely differing sizes connected together, in order to make a more overall flexible system.
The PDP-5 was by today's standards a very simple machine. In fact a $10 Arduino is many times more powerful than the PDP-5. But, as the predecessor of the renowned PDP-8, which using an instruction set based on that of the PDP-5, launched in Spring 1965, the minicomputer revolution. This led to the start of the microcomputer revolution, about 10 years later, in December of 1974 with the launch of the Altair 8800. The rest, as we say, is history.
PDP-5 c 1963 |
Recent Examples.
In October 2011, ARM Holding announced their big.LITTLE heterogeneous computing architecture where relatively low power smaller cores are coupled to larger, power hungry devices, to give an architecture that can respond efficiently to dynamic changes in computing load, than just clock frequency scaling of the larger cores could achieve.
The PDP-8: A lesson in longevity
The PDP-8 was launched in March 1965 and was produced in various forms for the next 15 years, each time benefiting from technological advances and cost reduction.
Now as we approach the 50th anniversary of the PDP-8, there is still much to be gained from studying it's simple architecture and instruction set.
The PDP-8 was the immediate successor to the PDP-5 (1963), DEC's first 12 bit minicomputer. As such it ran the same instruction set, but more than 5 times as fast. First a little history of the PDP-5.
The PDP-5 was originally conceived as a "Digital Controller", and even a week before it's launch it was called the DC-12. In a mad rush, the management at DEC decided that it was a real computer, and designated it the PDP-5. They spent the week changing all their marketing literature to reflect the name change.
The PDP-5 was intended to be a "small computer" for industrial monitoring tasks, which was to be connected to a larger mainframe, originally the 18 bit PDP-4. This combination of a small computer, acting as an I/O handler for a larger machine was first developed by Seymour Cray in 1960, with the 12-bit CDC 160. Inspired by the CDC 160, the engineers at DEC decided to design their own small, 12 bit computer.
For a flavour of what it was like to work with a 1965 vintage PDP-8, I watched the excellent videos from the National Museum of Computing, based on their restored PDP-8. I later spent a great Sunday afternoon last summer, looking at the real PDP-8 at the Museum in Bletchley.
The architecture of the PDP-8 has been widely studied, copied, and implemented in various technologies from 7400 TTL gates right through to high speed FPGA designs, written in VHDL or Verilog.
Although originally built using discrete transistor and diode logic, using the standard logic modules DEC had developed in the late 1950's, as time progressed, and technology improved, the PDP-8 was re-implemented several times, each time getting smaller and cheaper.
Inspired by the simplicity of the early 12 bit designs, I pondered for a while how to make the essence of these machines more accessible to the enthusiast or hobbyist.
I'm not a FPGA engineer, so I decided that I would make an exploration of the PDP-8 architecture and instruction set and implement it on a modern hardware platform by way of an emulation based on the popular Arduino.
Instruction Set.
Wikipedia has a good description of the PDP-8 Instruction Set, and it shows just how much could be crammed into a very simple design. Unfortunately, the instruction set has very few op-codes, with only 8 basic instructions, - so if you wanted to do anything clever, it had to be done using some fancy tricks and multiple instructions. This led to the use of macros (multiple instructions), for some of the operations that today would normally be handled by a single instruction.
Later versions of the PDP-8 had an Extended Arithmetic Element (EAE), which was an add-on extra that provided multiply, divide and other arithmetic operations - accelerated by the use of dedicated hardware rather than coded in firmware.
C++ Interpreter - written on Arduino
The aim of this experiment - and it is little more than an experiment, was to determine whether a fairly modern 8-bit microcontroller, running at 16MHz and programmed in relatively standard C, and C++, could interpret PDP-8 machine code, at a rate that is comparable to the performance of the original 1965 machine.
This was the primary aim, but the project also has an educational basis, helping to teach the fundamentals of simple computer architecture, instruction sets and assembly language programming - and also trying to give some insight into what programming was like, almost 50 years ago.
In the 1960s, it was normal to represent numbers on computer systems using the octal system. At that time (before the introduction of ASCII), the fundamental unit for a printable character was 6 bits. So computers had word sizes based on multiples of 6 bits. Early DEC computers were designed around 36, 18 and 12 bit word lengths - so that characters could be efficiently packed into memory.
These days, it is hard to comprehend how much the core memory cost. In 1967, based on a DEC pricelist to extend the PDP-8 memory by 4K words, would cost almost half the cost of the $18,000 PDP-8 machine. (In 1967, a new VW Beetle cost $1769).
Now as we approach the 50th anniversary of the PDP-8, there is still much to be gained from studying it's simple architecture and instruction set.
The PDP-8 was the immediate successor to the PDP-5 (1963), DEC's first 12 bit minicomputer. As such it ran the same instruction set, but more than 5 times as fast. First a little history of the PDP-5.
The PDP-5 was originally conceived as a "Digital Controller", and even a week before it's launch it was called the DC-12. In a mad rush, the management at DEC decided that it was a real computer, and designated it the PDP-5. They spent the week changing all their marketing literature to reflect the name change.
The PDP-5 was intended to be a "small computer" for industrial monitoring tasks, which was to be connected to a larger mainframe, originally the 18 bit PDP-4. This combination of a small computer, acting as an I/O handler for a larger machine was first developed by Seymour Cray in 1960, with the 12-bit CDC 160. Inspired by the CDC 160, the engineers at DEC decided to design their own small, 12 bit computer.
For a flavour of what it was like to work with a 1965 vintage PDP-8, I watched the excellent videos from the National Museum of Computing, based on their restored PDP-8. I later spent a great Sunday afternoon last summer, looking at the real PDP-8 at the Museum in Bletchley.
The architecture of the PDP-8 has been widely studied, copied, and implemented in various technologies from 7400 TTL gates right through to high speed FPGA designs, written in VHDL or Verilog.
Although originally built using discrete transistor and diode logic, using the standard logic modules DEC had developed in the late 1950's, as time progressed, and technology improved, the PDP-8 was re-implemented several times, each time getting smaller and cheaper.
Inspired by the simplicity of the early 12 bit designs, I pondered for a while how to make the essence of these machines more accessible to the enthusiast or hobbyist.
I'm not a FPGA engineer, so I decided that I would make an exploration of the PDP-8 architecture and instruction set and implement it on a modern hardware platform by way of an emulation based on the popular Arduino.
Instruction Set.
Wikipedia has a good description of the PDP-8 Instruction Set, and it shows just how much could be crammed into a very simple design. Unfortunately, the instruction set has very few op-codes, with only 8 basic instructions, - so if you wanted to do anything clever, it had to be done using some fancy tricks and multiple instructions. This led to the use of macros (multiple instructions), for some of the operations that today would normally be handled by a single instruction.
Later versions of the PDP-8 had an Extended Arithmetic Element (EAE), which was an add-on extra that provided multiply, divide and other arithmetic operations - accelerated by the use of dedicated hardware rather than coded in firmware.
C++ Interpreter - written on Arduino
The aim of this experiment - and it is little more than an experiment, was to determine whether a fairly modern 8-bit microcontroller, running at 16MHz and programmed in relatively standard C, and C++, could interpret PDP-8 machine code, at a rate that is comparable to the performance of the original 1965 machine.
This was the primary aim, but the project also has an educational basis, helping to teach the fundamentals of simple computer architecture, instruction sets and assembly language programming - and also trying to give some insight into what programming was like, almost 50 years ago.
In the 1960s, it was normal to represent numbers on computer systems using the octal system. At that time (before the introduction of ASCII), the fundamental unit for a printable character was 6 bits. So computers had word sizes based on multiples of 6 bits. Early DEC computers were designed around 36, 18 and 12 bit word lengths - so that characters could be efficiently packed into memory.
These days, it is hard to comprehend how much the core memory cost. In 1967, based on a DEC pricelist to extend the PDP-8 memory by 4K words, would cost almost half the cost of the $18,000 PDP-8 machine. (In 1967, a new VW Beetle cost $1769).
Using the Arduino for Retro-Nostalgic Computing
In just about 4 weeks time we come to the 50th anniversary of the PDP-8 Minicomputer. (23rd March 1965).
As a tribute to this game-changing machine, in the last week I have been thinking about the user interfaces used on minicomputers of the 1960s and how the early computer users interacted with their machines.
It was common in this era for the machine to have a large front panel consisting of lights and switches, allowing the contents of registers to be examined and simple programs to be toggled into memory using the key switches. The machine that most typifies this period of computing was the PDP-8 - first introduced in 1965, and by many, said to be the first minicomputer.
Here's how it started 50 years ago:
It got me wondering if a similar front panel consisting of LEDs switches could be created cheaply - as a nostalgic retro computing accessory shield for the Arduino.
LEDs and switches can be easily serviced using shift registers - an ideal application for them, which saves on I/O lines - as per my posting "A Little Bit Shifty" .
A good example of this is in the recreation of the KenBak 1 computer - using an Arduino as the KenBak-uino- here.
Why should I not like a minimalist computer system that is virtually named after me :)
FPGAs.
These are becoming very popular as a means of creating custom hardware and emulation of old microcomputer/microprocessor hardware.
I had thought about implementing a PDP-8 cpu on an FPGA, and then thought whether I really wanted to get involved with PDP-8 assembly language - probably not. However it would be neat to have a front panel reminiscent of those from the mid-1960s, where you could see the value of the program counter and the various registers, lit up in lights, and blinking sequences as the program is run.
Having tinkered around with the SIMPL language on Arduino, I have added a few LEDs, and it is perfectly possible for an Arduino to mimic the LED register displays typical of the PDP-8. A few simple instructions can be used to echo the instructions stored in RAM up to the LED display.
The standard Arduino is limited to 18 I/O lines, if you assume that digital 0 and digital 1 are committed to the serial port. This allows a single 12 bit LED array, plus 6 inputs for either analogue or digital signals.
I wrote a little bit of SIMPL code to send a 12-bit number directly to 12 LEDs conected to Digital2 - Digital 13. This works well if you just want a quick binary number LED display. For larger displays and keyswitch inputs, it's generally best to resort to using shift registers. My blogpost of May 2014 describes how to write out patterns to both 8 bit and 16 bit shift registers and how to control stepper motors from SIMPL using commands to drive a shift register.
More LEDs and Switches
On the Arduino MEGA, there are 52 usable digital I/O lines plus 16 analogue inputs - that would be enough to recreate lots of blinkenlights and switches, without having to add extra ICs as LED drivers.
The first Arduino MEGA 2560 I bought cost about £45. They are now less than £12 from ebay/China, which makes the MEGA a very attractive, low cost starting point for a variety of simple computing projects.
However, it is unlikely that an AVR could satisfactorily emulate a PDP-8. The PDP-8 was a 12 bit machine, originally with 4K of RAM. The AVR cannot directly execute a program out of RAM, unless it is an interpreted language, such as SIMPL, Bitlash or Tiny BASIC.
It might be possible to program an Arduino with a PDP-8 machine code interpreter, written in C, but I suspect that the speed would be at best 1/10th that of the original PDP.
So it might be best if any efforts along these lines was done as a tribute to the computers of the 1960s, rather than a true emulation.
A penny a thought, - a pound for 32 bit thoughts.
The humble Arduino based on the 8-bit AVR ATmega328 is now showing it's age (21+). A new generation of small, very low cost 32 bit microcontrollers have arrived and are benefiting from a smaller architectural geometry and low pin count packages. If the Arduino was being designed in 2015, instead of 2005, it would use a 32 bit mcu. They are better than half the cost of the 8 bit AVR parts, and include more peripherals and better ADC resolution.
As a tribute to this game-changing machine, in the last week I have been thinking about the user interfaces used on minicomputers of the 1960s and how the early computer users interacted with their machines.
It was common in this era for the machine to have a large front panel consisting of lights and switches, allowing the contents of registers to be examined and simple programs to be toggled into memory using the key switches. The machine that most typifies this period of computing was the PDP-8 - first introduced in 1965, and by many, said to be the first minicomputer.
Here's how it started 50 years ago:
It got me wondering if a similar front panel consisting of LEDs switches could be created cheaply - as a nostalgic retro computing accessory shield for the Arduino.
LEDs and switches can be easily serviced using shift registers - an ideal application for them, which saves on I/O lines - as per my posting "A Little Bit Shifty" .
A good example of this is in the recreation of the KenBak 1 computer - using an Arduino as the KenBak-uino- here.
Why should I not like a minimalist computer system that is virtually named after me :)
FPGAs.
These are becoming very popular as a means of creating custom hardware and emulation of old microcomputer/microprocessor hardware.
I had thought about implementing a PDP-8 cpu on an FPGA, and then thought whether I really wanted to get involved with PDP-8 assembly language - probably not. However it would be neat to have a front panel reminiscent of those from the mid-1960s, where you could see the value of the program counter and the various registers, lit up in lights, and blinking sequences as the program is run.
Having tinkered around with the SIMPL language on Arduino, I have added a few LEDs, and it is perfectly possible for an Arduino to mimic the LED register displays typical of the PDP-8. A few simple instructions can be used to echo the instructions stored in RAM up to the LED display.
The standard Arduino is limited to 18 I/O lines, if you assume that digital 0 and digital 1 are committed to the serial port. This allows a single 12 bit LED array, plus 6 inputs for either analogue or digital signals.
I wrote a little bit of SIMPL code to send a 12-bit number directly to 12 LEDs conected to Digital2 - Digital 13. This works well if you just want a quick binary number LED display. For larger displays and keyswitch inputs, it's generally best to resort to using shift registers. My blogpost of May 2014 describes how to write out patterns to both 8 bit and 16 bit shift registers and how to control stepper motors from SIMPL using commands to drive a shift register.
More LEDs and Switches
On the Arduino MEGA, there are 52 usable digital I/O lines plus 16 analogue inputs - that would be enough to recreate lots of blinkenlights and switches, without having to add extra ICs as LED drivers.
The first Arduino MEGA 2560 I bought cost about £45. They are now less than £12 from ebay/China, which makes the MEGA a very attractive, low cost starting point for a variety of simple computing projects.
However, it is unlikely that an AVR could satisfactorily emulate a PDP-8. The PDP-8 was a 12 bit machine, originally with 4K of RAM. The AVR cannot directly execute a program out of RAM, unless it is an interpreted language, such as SIMPL, Bitlash or Tiny BASIC.
It might be possible to program an Arduino with a PDP-8 machine code interpreter, written in C, but I suspect that the speed would be at best 1/10th that of the original PDP.
So it might be best if any efforts along these lines was done as a tribute to the computers of the 1960s, rather than a true emulation.
A penny a thought, - a pound for 32 bit thoughts.
The humble Arduino based on the 8-bit AVR ATmega328 is now showing it's age (21+). A new generation of small, very low cost 32 bit microcontrollers have arrived and are benefiting from a smaller architectural geometry and low pin count packages. If the Arduino was being designed in 2015, instead of 2005, it would use a 32 bit mcu. They are better than half the cost of the 8 bit AVR parts, and include more peripherals and better ADC resolution.
What can I get for a Pound?
Poundland don't sell microcontrollers in their raw form - but if they did, they would probably sell these.
The STM32F0 range of 32 bit ARM micrcontrollers are designed for low cost applications that don't need on-chip USB.
They offer a 48MHz ARM M0 core, 16 - 64kB of flash memory and 4 - 8kB of SRAM and a good rich mix of peripherals.
Up to 2 USARTS
Up to 2 SPI
Up to 2 I2C
12 bit ADC - 10 channels
Several timers - including quadrature decoder and PWM
On-Chip USB - STM32F042 range
They are available in several package sizes from a 20 pin TSSOP to 64 pin LQFP, family members are pin compatible for easy upgrade - and they start at under £1 in 1 off quantity. For greater volumes - the price drops to around 34p.
The 48 pin LQFP is no bigger on the pcb than an ATmega328P-AU, but provides 35 lines of I/O plus the crystal oscillator and a 32768Hz oscillator for a Real Time Clock. It provides two USARTS and 2 SPI interfaces which massively increase the communications capability over the ATmega328. The 12 bit ADC offers a 4 fold increase in resolution over the Arduino. If you choose the STM32F042 range - they even come with on-chip USB, and don't even need a crystal.
There has never been a better time to take the Arduino philosophy and reinvent it using a cheap 32bit microcontroller - offering about 10 times the computational throughput.
By implementing it on a breadboard friendly 40 pin DIL footprint - a bit like the ARMiGo. It can be powered through the mini B USB socket on the right, and programmed via STLink and FTDI using the connector on the left.
The STM32F0 range of 32 bit ARM micrcontrollers are designed for low cost applications that don't need on-chip USB.
They offer a 48MHz ARM M0 core, 16 - 64kB of flash memory and 4 - 8kB of SRAM and a good rich mix of peripherals.
Up to 2 USARTS
Up to 2 SPI
Up to 2 I2C
12 bit ADC - 10 channels
Several timers - including quadrature decoder and PWM
On-Chip USB - STM32F042 range
They are available in several package sizes from a 20 pin TSSOP to 64 pin LQFP, family members are pin compatible for easy upgrade - and they start at under £1 in 1 off quantity. For greater volumes - the price drops to around 34p.
The 48 pin LQFP is no bigger on the pcb than an ATmega328P-AU, but provides 35 lines of I/O plus the crystal oscillator and a 32768Hz oscillator for a Real Time Clock. It provides two USARTS and 2 SPI interfaces which massively increase the communications capability over the ATmega328. The 12 bit ADC offers a 4 fold increase in resolution over the Arduino. If you choose the STM32F042 range - they even come with on-chip USB, and don't even need a crystal.
There has never been a better time to take the Arduino philosophy and reinvent it using a cheap 32bit microcontroller - offering about 10 times the computational throughput.
By implementing it on a breadboard friendly 40 pin DIL footprint - a bit like the ARMiGo. It can be powered through the mini B USB socket on the right, and programmed via STLink and FTDI using the connector on the left.
SIMPL - A Quick Start Guide
SIMPL
Serial Interpreted Microcontroller Programming Language
This draft post attempts to introduce SIMPL - a simple interpreted language for microcontrollers.
SIMPL is a small language resource that resides in flash memory on the target microcontroller. It contains an interpreter that allows the user to have control and interactive access to the memory and peripherals of the mcu without placing an unnecessary burden on its limited resources.
SIMPL can be used as a development tool to exercise new hardware, or as a compact and efficient programming environment that may be ported to virtually any microcontroller or FPGA soft core, that supports a C compiler.
SIMPL can be implemented in Arduino C++ code, or in standard C code. It compiles to under 10Kbytes on most systems so can reside alongside the user application program.
SIMPL defines a 16 bit integer virtual machine. With this VM present on the target microcontroller, the user need not get involved with the machine specifics of a particular microcontroller.
The Advantage of SIMPL
SIMPL is a minimalist interpreted language for direct control of microcontroller hardware, via a communications link. This may take the form of wired serial connection, a wireless or Bluetooth Low Energy link.
SIMPL reduces a program to a sequence of ASCII characters, which may be entered interactively from the keyboard. It offers a means of executing a series of subroutines (stored in Flash) from a sequence of characters stored in RAM.
SIMPL will run on virtually any microcontroller, or FPGA that supports a C compiler. It's instruction set is small, just 50 commands, and designed to be human readable. Snippets of SIMPL code are compact and can be embedded into communications packets or even web URLs (such as REST), for commanding remote devices.
SIMPL reduces program code down to a few lower case alphabetical and punctuation characters - which each character representing a function or block of functions, which are stored in the flash memory of the microcontroller. These operations can be further reduced to a concatenated block of code that is represented by a single upper case character, however these operations are stored in RAM, and can be updated and modified at run time.
In this way, a microcontroller device, containing the SIMPL interpreter in flash, will execute commands sent to it via a communications link - such as serial, or BLE UART link, or wireless packet protocol conveyed over low power wireless - for example RFM12B or RFM69 and Jeenodes. It can also be reprogrammed remotely.
A Brief Outline.
SIMPL uses a very small interpreter, that sequentially scans through characters stored in a buffer, decodes the character, and executes a small block of code from flash, that is associated with each character.
The interpreter looks at each character in turn, checking if it is a number (0-9), a lowercase character (a-z), a punctuation character, or an uppercase character (A-Z). Depending on the type of character encountered, the interpreter follows a different strategy. Non-printable ASCII characters (less than 32 or greater than 128) are currently ignored by the interpreter.
Numbers 0-9 are decoded into a 16-bit integer variable called x.
Lowercase and punctuation characters, known as primitives, and are decoded in a series of Switch-Case statements to execute small blocks of code.
Uppercase characters, known as Definitions, force the interpreter to jump to a given address in RAM, and execute the string of characters found there, rather than the input buffer.
SIMPL uses a very simple, 16 bit virtual machine model for its operation. This model fits nicely with C code and 16 bit integer maths.
It contains two 16 bit registers, x and y into which the operands are loaded. These registers are used as a pair of operands for all arithmetic, comparison and logic operations, with the result being placed in x. In this respect, x may be considered to be analogous to the accumulator in other systems.
x is also used as the data source and destination register for any memory or I/O operation. The y register is used to supply the address for memory operations.
In addition to x and y, there is a loop counter variable k. This is decremented each time a loop is executed and is used to force the interpreter to exit the loop when k reaches zero.
Implementation in C and Arduino
Whilst the SIMPL interpreter is written in C code ( and C++ on Arduino) for portability, it could be ported to run under the native machine language of any specific processor, if much greater execution speed were needed. However with mcu clock speeds now 10 to 100 times faster than early 8 bit processors, resorting to machine code may seldom be needed.
However, there is a case to warrant the use of direct register manipulation - especially for the digitalRead and digitalWrite commands as used in Arduino. These can be sped up by a factor of 10 using direct port manipulation.
Instruction Set
Alpha Primitives
a
b
c
d Define a digital port pin
e
f for-next structure
g
h Set an output pin High
i Read an input pin
j
k The loop counter operand
l Set an output pin Low
m A blocking delay in milliseconds
n
o Write to an output pin
p print x to the serial device as an integer number
q
r
s Get an ADC sample
t print the current microsecond count (for timing functions)
u A blocking delay in microseconds
v
w While structure
x The primary data (Accumulator) operand
y The secondary (Address) operand
z Sleep - a non-blocking pause for x zeconds - whilst still monitoring UART and I/O
Maths Group
+ Add x and y and put the result in x
- Subtract x from y and put the result in x
* Multiply x and y and put the result in 32 bit pair [y:x]
/ Divide y by x and put the result in x, and remainder in y
% Calculate y modulo x and put the result in x
space Move the number just entered to y (allows for 2nd variable)
Comparison Group
> If y greater than x, put result in x (equiv to x = y-x)
< If y less than x, put result in x (equiv to x = y-x)
= If y equal to x, put result in x (equiv to x = y-x)
Logical Group
& Bitwise AND of y and x
| Bitwise OR of y and x
^ Bitwise XOR of y and x
~ Bitwise Complement of x
Memory Group
@ Fetch the data into x from the memory address defined by y (PEEK)
! Store the data in x to the memory address defined by y (POKE)
Definition Group
: Start a colon definition
; End a colon definition
Block Group
{.................} Loop the code contained within the braces whilst loop variable k is +ve
(................ .) Conditionally execute (or skip) the code contained within the round brackets
[,,,,,,,,,,,,,,,,,,] Create an array of comma separated elements within memory (enumerate and store)
_Print String_ Print the string contained within the underscores
"Store String" Store the string between the quotes in memory
.A. Print the characters assigned to A (list the word A)
'A' Retrieve the string from memory stored at address A
Control and Miscellaneous
? Print out the contents of the program stored in user RAM (LIST)
, A separator between elements stored within memory - store and increment
\ Escape from interpreter - stop all commands
£ Restart interpreter
$ Load x with the ASCII value of next character - do not interpret/execute
# Send a number as a bit pattern to a device, such as port register or shift register
Timing, Sleeping, Pauses and Delays
Much of what a microcontroller does is to synchronise events with time. This might be as simple as flashing a LED once per second, or toggling a square wave from a port pin at a given frequency. Arduino has been equipped with the millis() and micros() functions, and the delay() and delayMicroseconds() functions to make time synchronised coding simpler.
The delay functions are blocking - in that the microcontroller cannot execute any other code until the delay period has elapsed. This is OK for short periods, up to about a second, but it prevents the system from responding to external events, such as a change on an input pin, or the User trying to stop the program. For this reason, SIMPL has been given a non-blocking delay command z, which allows it to pause for a while, whilst still monitoring the UART Rx buffer for certain characters - such as the \ escape character, or for a change in status of any input lines, which might signify an external event.
z - is often associated with sleeping, so appropriate for a command that effectively allows the microcontroller to take a nap, until something happens to wake it up.
I also propose at this point the zecond - that is a non-blocking nap for a second. This allows for naps of 1 zecond up to 18.2 hours to be defined.
Waiting for External Events
This is a common use for While statements for in C.
while(some condition is met)
{ Execute this block of code, and continue to test condition}
This simple construct needs to be efficiently coded into SIMPL.
For example - wait for a value to be exceeded on an ADC input, say 600 on ADC 5.
600 5s>(............)
600 is first loaded into x, and the space character transfers it to y. Then we read ADC 5 (into x) and compare it with the value in y. If the result in x is positive - we execute the code in contained between the round brackets. This code could just be an idle loop or a pause - non-blocking delay. After this code is executed, we need to test again.
To code this into SIMPL we need to have a mechanism to repeatedly perform the test, and a means to execute an idle loop.
We can make this distinction using the two flavours of brackets. The code to test for the condition is enclosed in round brackets, and the code for the tasks to be done whilst idling is enclosed in the curly brackets (braces). This makes our code as close as possible to the C construct.
We then have the general form, where w defines the while statement
w(...condition..){...idle loop.....}
or as in the example
w(600 5s>){loop here until condition returns zero or less}
This is a kind of conditional form of the general loop, which decrements the loop counter k each time around the loop, until zero is reached.
Can we use the same constructs to implement for-next loops?
General form in C
for(i=0; i<=10; i++)
Here we have a loop variable i, which is initialised to zero, tested against an upper limit (to execute a conditional block of code) and then incremented (or modified) each time around the loop.
Let' use f to designate a for loop. We need to supply 3 parameters
initial value, test condition, modifier
We could do this by setting up the initial value and modifier outside of the test condition - by using x and y
Lets run from 0 to 100 with a modifier of +1
0 1f(100<){ loop}
A better method might be to borrow the loop counter k, so that 3 parameters can be entered into the conditional statement.
Using the space as a stack pushdown, the sequence
10 11 12
puts 10 into k, 11 into y and 12 into x.
The Decimalisation of Time- A SIMPL means to handle regular events.
More Applications for SIMPL.
A few notable things have happened since I was last using SIMPL to control stepper motors and LED arrays using shift registers. I have developed a new compact RFM12/69 wireless I/O breakout board for the Raspberry Pi in association with my friends at Open Energy Monitor and I have invested in a couple of FPGA dev boards - launched via Kickstarter.
Both of these developments can benefit from using the SIMPL language to exercise them and try out ideas on new hardware.
The RFM-Pi board is a compact I/O board (33 x 28mm) fitted with an RFM12/69 wieless module and ATmega328P, running Arduino with the Jeenodes wireless protocol. The pcb plugs into the I/O header of the Model B+ and Pi 2, where it picks up 3V3 power, Rx and Tx from the Pi's UART and a GPIO line for reset. This is a very simple way of providing Jeenodes/RFM12 wireless communications for the Pi, so that it can be used as a basestation for the series of wireless energy monitoring products developed by OpenEnergyMonitor.
However, in the latest version of the RFM-Pi, I chose to make available most of the I/O pins of the ATmega328 - so that in effect, this board may also be used as a I/O expander for the Pi - providing up to 8 analogue input channels and 5V tolerant I/O pins.It can be used as an Arduino compatible wireless I/O extender for the Raspberry Pi. It breaks out 12 digital I/O pins and 8 analogue pins from the ATmega328 SMD package, giving almost complete Arduino functionality in a small form factor.
Additionally, the board may be used as a plug in module, providing RFM12 wireless and Arduino functionality for some other project. It can act as an analogue sensor interface, or hardware controller and be controlled remotely from distances in excess of 100m using the Jeenodes wireless library. It is compatible with the other products in the Open Energy Monitor Range - and could form the basis of a new form of sensor. It requires a 3V3 supply - which could be provided from a coin cell or from a larger lithium cell- such as these 2250mAh common size 18650CA cells.
By running the SIMPL interpreter in the background, the RFM-Pi board can execute SIMPL commands via a 250m range wireless link.
SIMPL is also great way of getting the Pi to drive the I/O board - by a series of easy serial commands. This would open up the Pi to driving LED arrays, stepper motors and indeed, anything that the Arduino can do - just with a few high level commands. The Arduino has 5V tolerance, so best to have it take the knocks when experimenting with I/O - rather than frying a more expensive Pi.
A SIMPL Compiler?
Having "lifted the hood" again on SIMPL, I have been thinking about the possibility of a SIMPL compiler. There might be a way in which C code source could be compiled into an interpreted SIMPL program. A machine compiler would help with more complex programs and reduce human errors in coding.
SIMPL has a number of primitive operators, that are mapped into machine language, using an interpreter written in C. Lower case alpha and punctuation characters limit the primitives to just 58 instructions. This ensures that a microcontroller that runs SIMPL - has a memorable and easily managed reduced instruction set. For future implementations it means that a machine could run SIMPL from a 6 bit instruction.
This would allow more complex SIMPL programs to be machine generated from C source code, and reduced to an interpreted text file to be run on any micro. It's kind of like the Java Bytecode idea where common code can run on a variety of different platforms - provided that they have the interpreter. Imagine what sort of a SIMPL program could be conveyed in a 140 character text message - sent to a remote device by SMS.
Better Branching
For this to happen, SIMPL needs some further augmentation to allow easier branching and decision making - in what I call "If this - then that" or IFTTT- popularised by a recent new IoT service.
Ideally, and in its simplest form, a parameter needs to be tested against a number (using subtraction) and then branch if the result is positive, negative or zero. The branch would be to either execute the next character (code block) or skip it. This would allow the popular constructs of If-Then-Else and While loops to be generated.
I have implemented a simple < or > test, but it's a little clunky and also needs an equality test as to be included as well.
The round brackets (.....) represent a block inline of code that should be executed on the outcome of a test or skipped. This would allow While and For constructs to be programmed.
The square brackets [....] could be used for a switch-case construct to be generated.
Whilst I am running out of lower case characters for the primitive commands - only e,f,g, t and v remain, there is loads more scope for expansion by using some of the remaining printable punctuation characters - a total of 32. Some such as +, -, *, / ,>, <, {, }, :, ;,@, !, _ and ? have already been defined leaving about 18 for later. Logical operators such as & and | (or) are an obvious extension leaving a few like £, $, %, ^, ~, # to acquire some meaning - probably similar to their meaning in a C context.
So in theory, SIMPL can have a maximum of (26+32) primitive commands plus 26 user defined words - as defined by uppercase alpha characters.
Better Arithmetic
SIMPL currently has an x variable and a y variable that can be set to the previously entered value of x using the @ (fetch) and ! (store) operators. This is a bit clunky and a better way of handling multiple variables would probably be by using a stack. I want to try to keep the interpreter simple, and not implement the full stack logic. As most microcontrollers only combine 2 variables in their math operations, just x and y will be sufficient to handle this.
In FORTH, numbers are automatically put on the stack, but in SIMPL, they always go into x, unless stored to y using the ! operator. A neat idea would be to use the space character (instead of !) to inform the interpreter that another number is expected immediately, and so that x should be stored to y, so that x is free to accept the second number.
This would make the math operations a whole lot more readable - just by separating the variables with a single space.
123 456+p would add 123 and 456 and print it out.
As well as the math operators, the logical operators would also benefit from this increased flexible notation. The space operator implies - push the top of the stack down to make room for another parameter - allowing constructs such as
123 456+ 23-p so the interim sum of 123+456 is pushed down by the 2nd space, allowing room for the 23 and the subtraction operation. This makes it a lot more FORTH like and very much improved readability for numerical operations involving two variables.
Rule: A space following a number implies that the number is automatically copied from x (top) to the y (next) variable.
More Operators
& Bitwise AND
| Bitwise OR
^ Bitwise XOR
~ NOT (invert)
$ String operator
% modulo operator
(...) Conditionally execute this block of code
[...] Use x to select an option from the list contained within the square brackets
£ Invoke SIMPL interpreter
#
, separate a list of integers
. Pop x and print it (FORTH compatibility)
? Print out the current set of definitions
\
"
'
: Start of colon definition
; End of colon definition
_ Text string identifier
Serial Interpreted Microcontroller Programming Language
This draft post attempts to introduce SIMPL - a simple interpreted language for microcontrollers.
SIMPL is a small language resource that resides in flash memory on the target microcontroller. It contains an interpreter that allows the user to have control and interactive access to the memory and peripherals of the mcu without placing an unnecessary burden on its limited resources.
SIMPL can be used as a development tool to exercise new hardware, or as a compact and efficient programming environment that may be ported to virtually any microcontroller or FPGA soft core, that supports a C compiler.
SIMPL can be implemented in Arduino C++ code, or in standard C code. It compiles to under 10Kbytes on most systems so can reside alongside the user application program.
SIMPL defines a 16 bit integer virtual machine. With this VM present on the target microcontroller, the user need not get involved with the machine specifics of a particular microcontroller.
The Advantage of SIMPL
SIMPL is a minimalist interpreted language for direct control of microcontroller hardware, via a communications link. This may take the form of wired serial connection, a wireless or Bluetooth Low Energy link.
SIMPL reduces a program to a sequence of ASCII characters, which may be entered interactively from the keyboard. It offers a means of executing a series of subroutines (stored in Flash) from a sequence of characters stored in RAM.
SIMPL will run on virtually any microcontroller, or FPGA that supports a C compiler. It's instruction set is small, just 50 commands, and designed to be human readable. Snippets of SIMPL code are compact and can be embedded into communications packets or even web URLs (such as REST), for commanding remote devices.
SIMPL reduces program code down to a few lower case alphabetical and punctuation characters - which each character representing a function or block of functions, which are stored in the flash memory of the microcontroller. These operations can be further reduced to a concatenated block of code that is represented by a single upper case character, however these operations are stored in RAM, and can be updated and modified at run time.
In this way, a microcontroller device, containing the SIMPL interpreter in flash, will execute commands sent to it via a communications link - such as serial, or BLE UART link, or wireless packet protocol conveyed over low power wireless - for example RFM12B or RFM69 and Jeenodes. It can also be reprogrammed remotely.
A Brief Outline.
SIMPL uses a very small interpreter, that sequentially scans through characters stored in a buffer, decodes the character, and executes a small block of code from flash, that is associated with each character.
The interpreter looks at each character in turn, checking if it is a number (0-9), a lowercase character (a-z), a punctuation character, or an uppercase character (A-Z). Depending on the type of character encountered, the interpreter follows a different strategy. Non-printable ASCII characters (less than 32 or greater than 128) are currently ignored by the interpreter.
Numbers 0-9 are decoded into a 16-bit integer variable called x.
Lowercase and punctuation characters, known as primitives, and are decoded in a series of Switch-Case statements to execute small blocks of code.
Uppercase characters, known as Definitions, force the interpreter to jump to a given address in RAM, and execute the string of characters found there, rather than the input buffer.
SIMPL uses a very simple, 16 bit virtual machine model for its operation. This model fits nicely with C code and 16 bit integer maths.
It contains two 16 bit registers, x and y into which the operands are loaded. These registers are used as a pair of operands for all arithmetic, comparison and logic operations, with the result being placed in x. In this respect, x may be considered to be analogous to the accumulator in other systems.
x is also used as the data source and destination register for any memory or I/O operation. The y register is used to supply the address for memory operations.
In addition to x and y, there is a loop counter variable k. This is decremented each time a loop is executed and is used to force the interpreter to exit the loop when k reaches zero.
Implementation in C and Arduino
Whilst the SIMPL interpreter is written in C code ( and C++ on Arduino) for portability, it could be ported to run under the native machine language of any specific processor, if much greater execution speed were needed. However with mcu clock speeds now 10 to 100 times faster than early 8 bit processors, resorting to machine code may seldom be needed.
However, there is a case to warrant the use of direct register manipulation - especially for the digitalRead and digitalWrite commands as used in Arduino. These can be sped up by a factor of 10 using direct port manipulation.
Instruction Set
Alpha Primitives
a
b
c
d Define a digital port pin
e
f for-next structure
g
h Set an output pin High
i Read an input pin
j
k The loop counter operand
l Set an output pin Low
m A blocking delay in milliseconds
n
o Write to an output pin
p print x to the serial device as an integer number
q
r
s Get an ADC sample
t print the current microsecond count (for timing functions)
u A blocking delay in microseconds
v
w While structure
x The primary data (Accumulator) operand
y The secondary (Address) operand
z Sleep - a non-blocking pause for x zeconds - whilst still monitoring UART and I/O
Maths Group
+ Add x and y and put the result in x
- Subtract x from y and put the result in x
* Multiply x and y and put the result in 32 bit pair [y:x]
/ Divide y by x and put the result in x, and remainder in y
% Calculate y modulo x and put the result in x
space Move the number just entered to y (allows for 2nd variable)
Comparison Group
> If y greater than x, put result in x (equiv to x = y-x)
< If y less than x, put result in x (equiv to x = y-x)
= If y equal to x, put result in x (equiv to x = y-x)
Logical Group
& Bitwise AND of y and x
| Bitwise OR of y and x
^ Bitwise XOR of y and x
~ Bitwise Complement of x
Memory Group
@ Fetch the data into x from the memory address defined by y (PEEK)
! Store the data in x to the memory address defined by y (POKE)
Definition Group
: Start a colon definition
; End a colon definition
Block Group
{.................} Loop the code contained within the braces whilst loop variable k is +ve
(................ .) Conditionally execute (or skip) the code contained within the round brackets
[,,,,,,,,,,,,,,,,,,] Create an array of comma separated elements within memory (enumerate and store)
_Print String_ Print the string contained within the underscores
"Store String" Store the string between the quotes in memory
.A. Print the characters assigned to A (list the word A)
'A' Retrieve the string from memory stored at address A
Control and Miscellaneous
? Print out the contents of the program stored in user RAM (LIST)
, A separator between elements stored within memory - store and increment
\ Escape from interpreter - stop all commands
£ Restart interpreter
$ Load x with the ASCII value of next character - do not interpret/execute
# Send a number as a bit pattern to a device, such as port register or shift register
Timing, Sleeping, Pauses and Delays
Much of what a microcontroller does is to synchronise events with time. This might be as simple as flashing a LED once per second, or toggling a square wave from a port pin at a given frequency. Arduino has been equipped with the millis() and micros() functions, and the delay() and delayMicroseconds() functions to make time synchronised coding simpler.
The delay functions are blocking - in that the microcontroller cannot execute any other code until the delay period has elapsed. This is OK for short periods, up to about a second, but it prevents the system from responding to external events, such as a change on an input pin, or the User trying to stop the program. For this reason, SIMPL has been given a non-blocking delay command z, which allows it to pause for a while, whilst still monitoring the UART Rx buffer for certain characters - such as the \ escape character, or for a change in status of any input lines, which might signify an external event.
z - is often associated with sleeping, so appropriate for a command that effectively allows the microcontroller to take a nap, until something happens to wake it up.
I also propose at this point the zecond - that is a non-blocking nap for a second. This allows for naps of 1 zecond up to 18.2 hours to be defined.
Waiting for External Events
This is a common use for While statements for in C.
while(some condition is met)
{ Execute this block of code, and continue to test condition}
This simple construct needs to be efficiently coded into SIMPL.
For example - wait for a value to be exceeded on an ADC input, say 600 on ADC 5.
600 5s>(............)
600 is first loaded into x, and the space character transfers it to y. Then we read ADC 5 (into x) and compare it with the value in y. If the result in x is positive - we execute the code in contained between the round brackets. This code could just be an idle loop or a pause - non-blocking delay. After this code is executed, we need to test again.
To code this into SIMPL we need to have a mechanism to repeatedly perform the test, and a means to execute an idle loop.
We can make this distinction using the two flavours of brackets. The code to test for the condition is enclosed in round brackets, and the code for the tasks to be done whilst idling is enclosed in the curly brackets (braces). This makes our code as close as possible to the C construct.
We then have the general form, where w defines the while statement
w(...condition..){...idle loop.....}
or as in the example
w(600 5s>){loop here until condition returns zero or less}
This is a kind of conditional form of the general loop, which decrements the loop counter k each time around the loop, until zero is reached.
Can we use the same constructs to implement for-next loops?
General form in C
for(i=0; i<=10; i++)
Here we have a loop variable i, which is initialised to zero, tested against an upper limit (to execute a conditional block of code) and then incremented (or modified) each time around the loop.
Let' use f to designate a for loop. We need to supply 3 parameters
initial value, test condition, modifier
We could do this by setting up the initial value and modifier outside of the test condition - by using x and y
Lets run from 0 to 100 with a modifier of +1
0 1f(100<){ loop}
A better method might be to borrow the loop counter k, so that 3 parameters can be entered into the conditional statement.
Using the space as a stack pushdown, the sequence
10 11 12
puts 10 into k, 11 into y and 12 into x.
The Decimalisation of Time- A SIMPL means to handle regular events.
This comes as a result of the need to control equipment at specific times during the day, and on specific days of the week.
It allows very simple code to be used to determine the time and day, and decide whether an action routine should be executed.
By
reducing the time and the day of the week to a 16 bit integer, simple
comparison operations can be done to decide the program flow.
In
applications such as central heating control, there is no need to
resolve to the nearest second, when 10 second accuracy is perfectly
acceptable. It also allows the table that schedules operations to be
condensed into an array of 16 bit integers.
Let's invent a new measure of time - the decond. A decond is 10 seconds and there are 6 deconds in a minute.
1 hour = 360 deconds
1 day = 8640 deconds
1 week = 60480 deconds (less than 65536 - so can be expressed as16 bit unsigned integer).
As
there are less than 10000 deconds in a day, the most significant digit
of the 16 bit number can represent the day of the week between 0
(Sunday) and 6 (Saturday)
In
addition, the Arduino millis() function can be used for timing, and
incrementing the decond counter. 10000 millis in a decond, and 60000
millis in a minute. Both of these will nicely fit into a 16bit unsigned
integer.
More Applications for SIMPL.
A few notable things have happened since I was last using SIMPL to control stepper motors and LED arrays using shift registers. I have developed a new compact RFM12/69 wireless I/O breakout board for the Raspberry Pi in association with my friends at Open Energy Monitor and I have invested in a couple of FPGA dev boards - launched via Kickstarter.
Both of these developments can benefit from using the SIMPL language to exercise them and try out ideas on new hardware.
The RFM-Pi board is a compact I/O board (33 x 28mm) fitted with an RFM12/69 wieless module and ATmega328P, running Arduino with the Jeenodes wireless protocol. The pcb plugs into the I/O header of the Model B+ and Pi 2, where it picks up 3V3 power, Rx and Tx from the Pi's UART and a GPIO line for reset. This is a very simple way of providing Jeenodes/RFM12 wireless communications for the Pi, so that it can be used as a basestation for the series of wireless energy monitoring products developed by OpenEnergyMonitor.
However, in the latest version of the RFM-Pi, I chose to make available most of the I/O pins of the ATmega328 - so that in effect, this board may also be used as a I/O expander for the Pi - providing up to 8 analogue input channels and 5V tolerant I/O pins.It can be used as an Arduino compatible wireless I/O extender for the Raspberry Pi. It breaks out 12 digital I/O pins and 8 analogue pins from the ATmega328 SMD package, giving almost complete Arduino functionality in a small form factor.
Additionally, the board may be used as a plug in module, providing RFM12 wireless and Arduino functionality for some other project. It can act as an analogue sensor interface, or hardware controller and be controlled remotely from distances in excess of 100m using the Jeenodes wireless library. It is compatible with the other products in the Open Energy Monitor Range - and could form the basis of a new form of sensor. It requires a 3V3 supply - which could be provided from a coin cell or from a larger lithium cell- such as these 2250mAh common size 18650CA cells.
By running the SIMPL interpreter in the background, the RFM-Pi board can execute SIMPL commands via a 250m range wireless link.
SIMPL is also great way of getting the Pi to drive the I/O board - by a series of easy serial commands. This would open up the Pi to driving LED arrays, stepper motors and indeed, anything that the Arduino can do - just with a few high level commands. The Arduino has 5V tolerance, so best to have it take the knocks when experimenting with I/O - rather than frying a more expensive Pi.
A SIMPL Compiler?
Having "lifted the hood" again on SIMPL, I have been thinking about the possibility of a SIMPL compiler. There might be a way in which C code source could be compiled into an interpreted SIMPL program. A machine compiler would help with more complex programs and reduce human errors in coding.
SIMPL has a number of primitive operators, that are mapped into machine language, using an interpreter written in C. Lower case alpha and punctuation characters limit the primitives to just 58 instructions. This ensures that a microcontroller that runs SIMPL - has a memorable and easily managed reduced instruction set. For future implementations it means that a machine could run SIMPL from a 6 bit instruction.
This would allow more complex SIMPL programs to be machine generated from C source code, and reduced to an interpreted text file to be run on any micro. It's kind of like the Java Bytecode idea where common code can run on a variety of different platforms - provided that they have the interpreter. Imagine what sort of a SIMPL program could be conveyed in a 140 character text message - sent to a remote device by SMS.
Better Branching
For this to happen, SIMPL needs some further augmentation to allow easier branching and decision making - in what I call "If this - then that" or IFTTT- popularised by a recent new IoT service.
Ideally, and in its simplest form, a parameter needs to be tested against a number (using subtraction) and then branch if the result is positive, negative or zero. The branch would be to either execute the next character (code block) or skip it. This would allow the popular constructs of If-Then-Else and While loops to be generated.
I have implemented a simple < or > test, but it's a little clunky and also needs an equality test as to be included as well.
The round brackets (.....) represent a block inline of code that should be executed on the outcome of a test or skipped. This would allow While and For constructs to be programmed.
The square brackets [....] could be used for a switch-case construct to be generated.
Whilst I am running out of lower case characters for the primitive commands - only e,f,g, t and v remain, there is loads more scope for expansion by using some of the remaining printable punctuation characters - a total of 32. Some such as +, -, *, / ,>, <, {, }, :, ;,@, !, _ and ? have already been defined leaving about 18 for later. Logical operators such as & and | (or) are an obvious extension leaving a few like £, $, %, ^, ~, # to acquire some meaning - probably similar to their meaning in a C context.
So in theory, SIMPL can have a maximum of (26+32) primitive commands plus 26 user defined words - as defined by uppercase alpha characters.
Better Arithmetic
SIMPL currently has an x variable and a y variable that can be set to the previously entered value of x using the @ (fetch) and ! (store) operators. This is a bit clunky and a better way of handling multiple variables would probably be by using a stack. I want to try to keep the interpreter simple, and not implement the full stack logic. As most microcontrollers only combine 2 variables in their math operations, just x and y will be sufficient to handle this.
In FORTH, numbers are automatically put on the stack, but in SIMPL, they always go into x, unless stored to y using the ! operator. A neat idea would be to use the space character (instead of !) to inform the interpreter that another number is expected immediately, and so that x should be stored to y, so that x is free to accept the second number.
This would make the math operations a whole lot more readable - just by separating the variables with a single space.
123 456+p would add 123 and 456 and print it out.
As well as the math operators, the logical operators would also benefit from this increased flexible notation. The space operator implies - push the top of the stack down to make room for another parameter - allowing constructs such as
123 456+ 23-p so the interim sum of 123+456 is pushed down by the 2nd space, allowing room for the 23 and the subtraction operation. This makes it a lot more FORTH like and very much improved readability for numerical operations involving two variables.
Rule: A space following a number implies that the number is automatically copied from x (top) to the y (next) variable.
More Operators
& Bitwise AND
| Bitwise OR
^ Bitwise XOR
~ NOT (invert)
$ String operator
% modulo operator
(...) Conditionally execute this block of code
[...] Use x to select an option from the list contained within the square brackets
£ Invoke SIMPL interpreter
#
, separate a list of integers
. Pop x and print it (FORTH compatibility)
? Print out the current set of definitions
\
"
'
: Start of colon definition
; End of colon definition
_ Text string identifier
Monday, February 09, 2015
Hello 2015 - What's New?
FPGAs
Last summer, I backed a couple of Kickstarter campaigns - and now they have both delivered.
I am now the owner of a couple of FPGA boards - and I am slowly learning FPGA technology - aided by the subtle democratisation of programmable hardware. More on this later.
Meanwhile, I am still tinkering with the minimalist programming language SIMPL. As of Feb 9th 2015 - I can report, with some joy and enthusiasm, that I have managed a quick and dirty hack, to port it to one of my FPGA boards. I now have a FPGA, hosting a 32 bit, 96MHz soft core processor - that runs one of the simplest interpreted languages on the planet. Is all a bit bass-ackwards, but it's fun.
The sketch is here as a Github Gist. You will need a Papilio Duo and perhaps a LogicStart Shield - or just run it, native on an Arduino if you want a quick play.
https://gist.github.com/monsonite/97730b0456762da20a98
I'm currently trying to condense all my Txtzyme and SIMPL experimentation into a single, easy to read, Quick Start Guide. please bear with me on this - it might take a little time.
SIMPL and BLE
A meeting with an old work colleague over a pub lunch, rekindled my active interest in SIMPL. As such I have compiled the various blog posts from 2013 and 2014, into a single document, and I am working out the best way to present it as a useful document describing SIMPL and how it can best be used.
We discussed the idea of passing SIMPL programs via a Bluetooth Low Energy (BLE) connection between a Smartphone and a BLE device. SIMPL programs are very compact and ideally suited to the short packet format of a BLE communication packet.
Lithium Battery Developments
I have also been doing some work developing hardware that runs on a single Lithium Ion cell. This has involved the use of the MCP1640 boost converter and also the MCP73832 battery charger IC. This development work has gone very well and I am confident that I can make an economical battery powered design based around these ICs. The MCP1640 at just 30p in volume, is a fraction of the cost of the LTC3525 boost converter. Combined with a small inductor - such as this one from Farnell - you have a very compact boost regulator for about 50p.
FPGAs - The Democratisation of Programmable Logic
Meanwhile, a couple of Kickstarters that I backed last summer have come to fruition - I have now entered the exciting world of FPGAs and soft-core processors. The great thing is that now an Arduino can be emulated by a 32bit 100MHz soft core processor on an FPGA, and as such SIMPL can be ported to the FPGA ecosystem. Here's an update on FPGA developments:
Last summer, I backed a couple of Kickstarter campaigns - and now they have both delivered.
I am now the owner of a couple of FPGA boards - and I am slowly learning FPGA technology - aided by the subtle democratisation of programmable hardware. More on this later.
Meanwhile, I am still tinkering with the minimalist programming language SIMPL. As of Feb 9th 2015 - I can report, with some joy and enthusiasm, that I have managed a quick and dirty hack, to port it to one of my FPGA boards. I now have a FPGA, hosting a 32 bit, 96MHz soft core processor - that runs one of the simplest interpreted languages on the planet. Is all a bit bass-ackwards, but it's fun.
The sketch is here as a Github Gist. You will need a Papilio Duo and perhaps a LogicStart Shield - or just run it, native on an Arduino if you want a quick play.
https://gist.github.com/monsonite/97730b0456762da20a98
I'm currently trying to condense all my Txtzyme and SIMPL experimentation into a single, easy to read, Quick Start Guide. please bear with me on this - it might take a little time.
SIMPL and BLE
A meeting with an old work colleague over a pub lunch, rekindled my active interest in SIMPL. As such I have compiled the various blog posts from 2013 and 2014, into a single document, and I am working out the best way to present it as a useful document describing SIMPL and how it can best be used.
We discussed the idea of passing SIMPL programs via a Bluetooth Low Energy (BLE) connection between a Smartphone and a BLE device. SIMPL programs are very compact and ideally suited to the short packet format of a BLE communication packet.
Lithium Battery Developments
I have also been doing some work developing hardware that runs on a single Lithium Ion cell. This has involved the use of the MCP1640 boost converter and also the MCP73832 battery charger IC. This development work has gone very well and I am confident that I can make an economical battery powered design based around these ICs. The MCP1640 at just 30p in volume, is a fraction of the cost of the LTC3525 boost converter. Combined with a small inductor - such as this one from Farnell - you have a very compact boost regulator for about 50p.
FPGAs - The Democratisation of Programmable Logic
Meanwhile, a couple of Kickstarters that I backed last summer have come to fruition - I have now entered the exciting world of FPGAs and soft-core processors. The great thing is that now an Arduino can be emulated by a 32bit 100MHz soft core processor on an FPGA, and as such SIMPL can be ported to the FPGA ecosystem. Here's an update on FPGA developments:
Field Programmable Gate Arrays (FPGAs) are definitely the future for digital electronic design.
They are a "blank canvas" of logic gates and registers, onto which you can paint your own digital design.
However, the FPGA manufacturers tool chains are certainly not intended for easy access to this wonderful technology, and to be thrown in at the deep-end of the various hardware design languages - Verilog and VHDL will appear daunting to most.
Fortunately, some forward thinking individuals have succeeded in providing an abstraction later to these tool chains in the form of an Integrated Design Environment (IDE) and with this easier entry level, have managed to make FPGA technology open to a much wider market of hobbyists and enthusiasts.
Background
There are two competing FPGA manufacturers - who between them each hold about 45% of the world market. With this combined 90% world market domination - there is very little space for their competitors.
Altera - known for their Stratix and Cyclone families of FPGAs.
Xilinx - known for their range of Spartan FPGAs.
Recently, two crowd funded FPGA dev-boards have come available via Kickstarter. Whilst subtley different - they share the same Xilinx Spartan 6 FPGA.
Scarab Hardware MIniSpartan 6+
This is a professional dev-board with two HDMI sockets, 3.5mm audio jack, 8 channels ADC, miniSD card socket and 2MB of SRAM. The Spartan 6 is a BGA package - and most of the I/O is brought out to a pair of dual row headers. There is a miniB USB connection via the ubiquitous FTDI chip. The board is white in colour with great care taken in matching track lengths for maximum performance.
Gadget Factory Papilio Duo
The Papilio DUO - whilst sharing the Spartan 6 FPGA offers a different approach in familiarising the hardware. It has the footprint of an Arduino MEGA, and additional hardware may be attached in the form of shields or "Wings". The FPGA is in a LQFP pagkage as opposed to BGA. There is also the same FTDI USB interface IC, but on the bottom of the pcb is an Atmel ATmega32U4 which can be programmed as an Arduino (Leonardo).
Whilst not providing on board video, Audio or microSD connectors - these can be added in the form of a "LogicStart" Shield or Gaming shield.
The unique selling point of the Papilio DUO, is that it is supplied with a soft-core processor - the "ZPUino" - which emulates an Arduino, but at 100MHz on 32bit hardware. Once the hardware is loaded with the logic design for the ZPUino, it will then accept and run a normal Arduino sketch - but at many times the speed performance.
Arduino users can port their sketches almost directly across to the DUO board and run them on the soft-core. They can also progress to designing their own hardware designs to accompany the Z- core on the FPGA.
In my opinion - this allows the Arduino user a smooth transition into the world of FPGAs.