Jeremy Leach

Senior Member

I've got an interesting problem forming, which I'll let you get your teeth into ;-)

I've got one PicAxe dedicated to handling button pushes to control a AXE033 LCD. It's displaying all sorts of sensor readings. I've just worked out that there's ideally 29 different 'screens' of information I want to display. I've worked out a table in Excel of all the attributes relating to each screen, such as screen name, value to be displayed, units of measurement, etc etc.

I think the elegant solution to control the LCD display would be to contain a representation of this table in the PicAxe. With generic routines to extract the data from the table and display the appropriate screen.

The other option would be to have horrendously messy code covering each screen and what it contains.

I'm really talking about arrays of data. What is a good method on a PicAxe of implementing an array?

Also, parts of the table contain little information, so I need to think of efficiently packing the information in memory somehow. What comes to mind is a storage system using marker bytes to indicate field data boundaries and locating table fields by scanning from the start. Not very efficient in execution speed, but I'm hoping that as it's only for LCD screens the PicAxe will be more than capable of doing this fast enough.

I'd be interested in any tips or views here and what other people have done when using arrays.

Edited by - jeremy leach on 3/31/2005 9:24:57 PM
Hi, you can store the screens in a eeprom memmory, and use different offsets for different screens.

lets say you use 20 bytes for each screen you access the right display data by multiplying the screen number by the amount of bytes used (20 in this example).

I can't give you any example code because i never played with eeproms yet but i remember reading something about this in the picaxe manual.

good luck !


Technical Support
Staff member
The easiest way to do arrays is using SFR or EEPROM, both 'PEEK i,var' and 'READ i,var' can be thought of as 'var=SFR(i)' and 'var=EEPROM(i)' respectively.

External I2C EEPROM can also be used if you have larger arrays, but if you were repeatedly using the data to update an LCD, it would be wise to copy data from I2C EEPROM to SFR and then use that - 'caching'.

Your 'database', a description of what's on each screen is a good one which I've used on other systems. Starting with the first entries in the array being pointers to start locations of 'screens' in it elsewhere gives a very easy way of accessing screens from a single 'screen number'; avoiding having to know absolute offsets outside of the database is a major benefit.

The screen definitions themselves can then be 'mini programs' which you interpret; for example -

if a byte has value $20..$7E, it's a printable character, display it.

$00..$0D can mean display value of b0..b13.

$10..$16 display value of w0..w6.

'Escape codes' can be used to indicate where the next character or number should be put, what format the following number(s) should have when printed etc.

It's usually worthwhile splitting each 'screen' into two parts, one which specifies the 'fixed text', user defined chars, number formats etc which only needs to get 'executed' when the screen is first displayed, and a 'variable data' part which allows numbers to be re-drawn whenever the display is changed.

'Macro escape codes' can be used to programmatically point to two or more 'screens' so the the display can be changed dependant upon the data - ideal if you want to display "1", "2,", "3" and "OFF".

Additionally, more escape codes can be used to determine which new screen to go to when menu navigation buttons are pushed, and codes can be used to indicate 'which number action' to take when a button is pushed to change a data value. The codes can specify defaults, min, max, step and sequenced values of data.

A good tip : Always separate number edit handling from the number display routines.

Basically, what you are doing is creating a 'menu programming language' and implementing the 'interpreter' for it. The easiest way to maintain the database is through having the data generated through a purpose written PC program, so the menu definitions can be done using a convenient text format. Hand adjusting numerous pointers can rapidly become a nightmare.

Packing, which can be equally hard by hand, can also be done by the PC program. The choice for packing depends on what your data is and what facilities you need. Text can often be compacted into 7 or 6-bit characters with byte alignment thrown away, or left as 7-bit characters within a byte with the msb indicating a space should be printed before the character. It's best to start without packing and add that later if needed. Although you may require a major re-design at that point, the 'prototyping' will have still been very useful and make that easier, whereas guessing the ideal packing at the outset can be hard.

With a good menu programming environment, your PICAXE program needs to do very little than say which screen is to be displayed and handlers to display, navigate and update data are all that is additionally required.

Edited by - hippy on 3/31/2005 11:33:11 PM

Jeremy Leach

Senior Member
That's excellent advice Hippy - thanks. You've managed to describe what was starting to emmerge in my head !

I was starting to think about a PC program to formulate the database data - I'm used to writing in VBA so will do it in that. Also I agree that packing can come later (I hadn't really envisaged doing this at a bit level though!).

It's nice to think I seem on the right lines here. I hadn't fully grasped what was needed until I started to think about all the menues I need and a common way to display the 'screens'. This menu prgramming language approach will be great once I've cracked it and a nice elegant solution - hopefully.

Thanks again, although I'm sure it'll raise further questions later. ;-)


Technical Support
Staff member
Another tip is, that as you probably have to write one PC program anyway, write another which can emulate an LCD and allows the menu programming language to be executed on a PC.

It's usually far easier and quicker to debug a PC program than a PICAXE one, and if you code 'PICAXE style' it should then be a simple task to port over to a PICAXE with a program you can be pretty confident will work once the hardware related isues are dealt with.

Jeremy Leach

Senior Member
Thanks again Hippy.

I've been doing some sums on the data storage I need. I've designed my 'user interface' PicAxe 18X without any external memory, so things are quite tight. There's 255 bytes of data memory and 47+47 bytes of Storage memory. This isn't a lot for 29 'screens' of data.

One data-hungry element is the screen names and other words. I've decided to have a separate 'word-table' so I can use short-hand numerical references to repeated words rather than the words themselves. This saves a lot.

However another avenue I'm considering is how to use the program memory for data storage. My scenario is a need for data storage and less for program storage. The LOOKUP command seems to be a useful way to use Program storage - albeit a bit of a cryptic way!

LOOKUP offset,(data0,data1...dataN),variable

For instance I can write a PC program to generate a series of LOOKUP commands and contain them in a subprocedure GetScreenData that gets a record for the relevant 'screen'. The 'screen table' will have a sort of virtual existence in the actual sub routine Offset commands data parameters, and therefore in Program memory. The offset variable in the Lookup commands will be the record number I want to retrieve. Each offset command in the sub procedure will return a different field value for the screen table and probably load it into RAM.

I'll see how I get on, but it seems to open up the possibility of coding 'virtual tables' within subroutines.

All interesting stuff.

Jeremy Leach

Senior Member

I've managed to develop VBA in Excel to auto-generate PicAxe code to control LCD 'screens'. Still in development but just in case anyone is interested:

Here's an example of using the Lookup command to return a 'record' from a 'Variable_Table'. The subroutine contains the data for the 'Variable_Table' within the Lookup command data parameters. In this example I'm just using the variable table to identify the type, storage location and measurement units for variables.

I must confess I've not got as far as running it on the PicAxe yet (!) but am pretty sure it'll work. This little exercise has highlighted how auto-generation of code isn't that hard and that there's probably a lot of interesting things you can do in terms of inventing a high-level language VBA environment that auto-generates (compiles) PicAxe code.

'NOTE: Assumes record index is supplied in b0 and field values loaded into b1,b2,b3 etc
' FieldName = Variable Type Ref
Lookup b0,(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,1),b1
' FieldName = Store Where Ref
Lookup b0,(2,2,2,2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1),b2
' FieldName = Variable Address
Lookup b0,(0,1,2,3,0,1,2,3,4,4,5,7,9,11,13,15,17,19,21,23,25,27,5,6),b3
' FieldName = Measurement Units Ref
Lookup b0,(13,23,30,0,23,0,0,0,0,0,45,45,46,47,45,48,49,49,50,51,49,52,0,0),b4

Another nice thing about auto-generating code is that you can make it neat and tidy.

Edited by - jeremy leach on 4/5/2005 12:52:08 PM