Basic menu programming with AXE133 and display

I'm trying to think of the best way to make a basic menu system with: a PICAXE 14M2, 3 tactile switches(little buttons) and an OLED display controlled by the AXE133 firmware on a separate 18M2
The 3 buttons being set, plus and minus.
I would start by setting an interrupt for the set button to enter the menu "setint %00000100,%00000100,C"
then use the plus and minus buttons to flick through the options
then modify the option on the second line with the plus and minus buttons
and a final press of the set button to save the setting and return to displaying the main volume level

It's for a 7.1 amplifier with 2x 4 channel volume control chips daisy chained and controlled by the 14M2
so the menu options will be things like: LFE Gain (in dB) and Display Brightness

Any tips or suggestions for programming this in basic are greatly appreciated.
 
Last edited:

nick12ab

Senior Member
I don't think there really is a 'best' way of doing it but some different ways include using nested IFs/do:loops, using gotos, or using gosub/returns.

But there are some things you can do better. Scrap the idea of using a serial display - your menu will feel sluggish if you use one. After upgrading my GCSE project to use a parallel LCD I reassembled the old circuit on breadboard (with AXE033IC) and I couldn't believe I tolerated the sluggishness caused by the serial LCD. I did, however, use a larger LCD on the breadboard so that makes it feel worse.

If you really don't want to use a parallel display, then a serial display won't be much of an irritation as long as you don't use the menus often. Beware that the serial LCD will momentarily prevent the PICAXE from responding to things like interrupts, the timer, PWM etc.
 
Approximately how long is the delay for a serial display?
It probably wouldn't make a difference but I'm using an OLED display and the display itself is parallel but controlled by an 18M2 with the AXE133 firmware(I assume that's what you mean by serial display) this makes the programming simpler on the 14M2 and I dont really have the space on my project for the size of PICAXE I would need for connecting a parallel display directly.

You say a serial display will interrupt other things the PIXAXE is doing, does this affect tasks being run in parallel?
 

nick12ab

Senior Member
You say a serial display will interrupt other things the PIXAXE is doing, does this affect tasks being run in parallel?
Yes it does, because the parallel tasks share a single processor core so all other tasks are suspended during the serial transmission.

Approximately how long is the delay for a serial display?
About 0.1-0.2s, which is slow compared to a parallel display.

A parallel display connected to another microcontroller which forwards serial commands to the parallel display counts as a serial display - most serial displays work this way.
 

nick12ab

Senior Member
Would increasing the baud rate improve it much?
With the PICAXE-18M2 it is possible to increase the baud rate to 4800 and possibly 9600 and this might be enough to eliminate the sluggishness but it won't prevent use of the serial display interfering with parallel tasks/background serial/servos/timers.
 

srnet

Senior Member
Would increasing the baud rate improve it much?
Not really, the AXE133 will run at 4800baud, increase the 18M2 processor clock to 32Mhz, but it tends not to be reliable at 9600baud.

You need to try it, the delays that Nick mentions might not be acceptable to you, which is why he mentions a parallel driven display.
 

hippy

Technical Support
Staff member
I've never noticed anything particularly sluggish in serial LCD/OLED updates but the best thing to do is to prototype things, and before that decide and detail exactly what the complete system will be doing.

The advice I can give on menu display is -

Make sure you have the full menu system designed on paper first.

Split the selection of menu and display of data into one section of code and handle the updating of data in another. Consider separating display of menu titles and data display into separate parts, then it's easier not to update menu titles when you don't have to.

Have the button push handler as a separate routine which converts button pushes into 'action values' which are then handled by the above routines. For example the same button may be NEXT MENU or INCREMENT DATA depending on mode or where you are in menu selection. The menu routine will handle NEXT MENU but ignore INCREMENT DATA and the opposite when editing data. That also allows things like holding UP and DOWN buttons to provide SET TO DEFAULT option which is easily handled ...

Code:
UpdateData:
  Select Case dataDisplayed
    Case SHOWING_BALANCE
      Select Case actonValue
        Case INC_DATA : balance = balance + 1 Max 10
        Case SET_DFLT : balance = 5
        Case DEC_DATA : balance = balance Min 1 - 1
      End Select
    Case SHOWING_VOLUME
    :
  End Select
  Return
Get it right and you can create a well structured, easily modifiable, menu system which has fairly simple coding and is reasonably easily understood. Probably most effort goes into designing the framework which holds things together; after that it's easy to drop new menus in and alter things as needed.

Always use SYMBOL commands to define values for things so you aren't dealing with 'magic numbers' throughout the code. That makes it easier to understand the code later but more importantly easier to change things, add more buttons, new actions, new menus, or simply change the order of menus, without having to alter a lot of code with the risk of something not getting altered correctly which becomes a nightmare to debug.

It's a hard slog designing a good menu system from first principles and it can get complicated very quickly if you don't approach it methodically. Know where you are heading, have a decent framework, and it becomes rather straight forward.
 

SAborn

Senior Member
Remember with 3 buttons you have 7 different functions, A, B, C, AB, BC, AC, ABC. you can use, this can be handy to enter into things like calibration menus where on average the general user would not need, to enter into these functions i use 2 buttons (AB, BC, AC) then that gives me 3 single buttons to work with in the function loop.

Then for functions you want to make harder to access like clear all memory etc, then i use all 3 buttons (ABC) pressed together as its not so easy to press 3 button at a time, this makes it somewhat idiot proof from little fingers pressing buttons and changing set values.
 

hippy

Technical Support
Staff member
You can also get additional functions per button by detecting if they are short pushes or push-and-hold pushes.

You can actually produce an entirely workable menu system using just one button that way. Short pushes step around the options, a long push enters the 'set the value' mode. Short pushes alter the value, a long push either stores the value and returns to the menu, or goes to a confirm option where a short push is yes, a long push cancels the change.

Timed button pushes will also give you auto-repeat abilities.

A trick with timed button pushes is to do the short button push action when the button is released rather than pushed, and a long push action when the hold period expires. Acting on button release is also advised if you have INC and DEC and both together gives DEFAULT; saves the increment or decrement before it then defaults. It also makes auto-repeat easier.
 

SAborn

Senior Member
A trick with timed button pushes is to do the short button push action when the button is released rather than pushed, and a long push action when the hold period expires. Acting on button release is also advised if you have INC and DEC and both together gives DEFAULT; saves the increment or decrement before it then defaults. It also makes auto-repeat easier.
I agree, except for the fact its nice to hold a button down and the count increases/decreases, no drama if you over shoot the setting as you have +/- keys to adjust it.

Personally i would use 3 buttons compared to using one button for many functions, its so easy to work with a 3 button format if you have the input pins to spare.
 

oracacle

Senior Member
dunno if this will be any help, it was designed to be use with axe134 (20x4 display), never tested in real world but may give you an idea, it works fine in simulation, with both the 20m2 it was writen for and a 14m2

Code:
#picaxe 20m2

symbol Slct	=	b0				;selection
symbol nPos	=	b1				;new position
symbol oPos =	b2				;old position

symbol Down	=	pinc.0
symbol Up	=	pinc.1
symbol btnS	=	pinc.2

'20x4 OLED Display
init:
	let oPos = 147
	let nPos = 127
	serout b.0,n2400, (254,1)		;clear display in case of reset
	pause 30
	serout b.0,n2400, (254,133,"Welcome",254,196,"Menu Project")	;show welecome message
	Pause 2000
	serout b.0,n2400, (254,1)		;clear display after wlecome messafe
	pause 30
	serout b.0,n2400, (254,129,"menu 0",254,193,"menu 1",254,149,"menu 2",254,213,"menu 3",254,138,"menu 4",254,202,"menu 5",254,158,"menu 6 ",254,222,"menu 7")	;show menus
	gosub position
	
	
	
main:
	if down = 1 then
		let Slct = Slct + 1
			if Slct > 7 then
			let Slct = 0
			end if
		gosub position
	end if
	
	if up = 1 then
		let Slct = Slct - 1
			if Slct > 7 then
			let Slct = 7
			end if
		gosub position
	end if
	if btnS = 1 then
		on Slct goto menu0, menu1, menu2, menu3, menu4, menu5, menu6, menu7
	end if
	goto main

menu0:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,133,"menu 0")
	pause 1000
	'run programe
	reset
	
menu1:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 1")
	'run setup menu
	pause 1000
	reset
	
menu2:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,133,"menu 2")
	'run distance menu
	pause 1000
	reset
	
menu3:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 3")
	'run distance menu
	pause 1000
	reset
	
menu4:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 4")
	'run distance menu
	pause 1000
	reset
	
menu5:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 5")
	'run distance menu
	pause 1000
	reset
	
menu6:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 6")
	'run distance menu
	pause 1000
	reset
	
menu7:
	serout b.0,n2400, (254,1)
	serout b.0,n2400, (254,135,"menu 7")
	'run distance menu
	pause 1000
	reset
	
position:

	lookup Slct, (128,192,148,212,137,201,157,221),nPos
	serout b.0,n2400, (254,oPos,32,254,nPos,62)
	let oPos = nPos
	pause 1000
	
	return
 
Thanks so much everyone and oracacle, that code sample really helps!
I just found the Simulate Serial LCD option under the Simulation tab in Options on the PICAXE Programming Editor, that helps massively!
 
Top