Problems with menu code

NXTreme

Senior Member
I've been working on a basic menu system the past few weeks. Since my programming skills don't really exist, I've spent more time reading the manuals (especially #2) than coding and have learned lots! However, I've finally run into a problem I just can't debug myself. First, an explanation of my setup. I have a 20X2 plugged into a 08M proto board with firmware version C.1 and four AAs that have been run down to about 4.8 volts. I'm using a SparkFun SerLCD V2.5 connected to port A.0 and three push buttons for menu navigation attached to C.6, C.7 and B.0 (with 10K pulldowns and a 1K in series like suggested in manual #3, page 25).

The code is part of the backlight settings menu, which will eventually let you change the backlight's brightness and whether it is on or off. The actual code is supposed to display the backlight settings menu and sub menus (see diagram for details). The problem I'm having is that it won't respond to any button presses. I have pinC.6 as up, C.7 as down and B.0 as enter. I use the "<" symbol to show what point the menu is at at the "+" and "-" signs to show if there are more options farther down or up the menu.

When I power up the setup, I get the SF splash-screen for a short while and then it goes blank. If I press the down button I can get the screen to display the top section of the menu with the pointer at "Brightness". I have working code that lets me navigate the "Brightness" sub menu so my wiring isn't the problem.

This is the code I'm having problems with right now.
Code:
symbol Up=pinC.6 'define symbols
	symbol Down=pinC.7
	symbol Enter=pinB.0
	symbol BLMenu=b3
	symbol MMenu=b2
	high A.0
	pause 850
	
	read 0,b0 'reads saved backlight value
	
	if b0<128 then let b0=128 'code checks value is out of range
	elseif b0>157 then let b0=157 'if it is, it will bring it back to the correct value
	endif
	
	let b1=b0-128 'does some math to scale brightness from 29 to 100
	let b1=b1*1000/289
		
blint:	read 1,b4
	
	if b4=0 then 
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("Off<            Brightness     -")

	elseif	b4=1 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("On<             Brightness     -")
	
	elseif b4>1 then
	write 1,0
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("Off<            Brightness     -")
	
	endif
	

blsub:	if Up=1 and BLMenu=1 and b4=0 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("Off<            Brightness     -")
	let BLMenu=0
	
	elseif Up=1 and BLMenu=1 and b4=1 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("On<             Brightness     -")
	let BLMenu=0
	 
	elseif Up=1 and BLMenu=2 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("Brightness<    +Return...      +")
	let BLMenu=1
	endif
	
	if Down=1 and BLMenu=0 and b4=0 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("Off            +Brightness<    -")	
	
	elseif Down=1 and BLMenu=1 and b4=1 then
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 5
	serout A.0,T9600_8,("On             +Brightness<    -")
	endif
	
	if Enter=1 and BLMenu=0 then
	elseif Enter=1 and BLMenu=1 then
	elseif Enter=1 and BLMenu=2 then
	endif
	
	goto blsub
I am using EEPROM location 0 to store backlight values when turned off and location 1 for remembering on/off condition. I'm using byte "BLMenu" to store the current location of the pointer on the menu. I'm sure there are more elegant ways of doing this but this is what I came up with. The last 'if' statement section still hasn't been filled in but I figured I could leave it empty till I made sure everything was working; am I wrong in doing so? I'm not quite sure what else you would need to know to point me in the right direction but I'm willing to supply any details neccesary.

BLMenu.png
Diagram of what I'm trying to achieve. The return part will eventually take you back to the main menu.
 
Last edited:

John West

Senior Member
Sorry I haven't read the spec on your LCD yet, but device control commands typically require a substantially longer pause after they've been sent than you have listed. You might want to double check that.

I'm far from a good coder as yet, but the "if Enter=1 and BLMenu=0 then" followed by "else", doesn't look at all right. If then what?

Hopefully some of the more expert folks will be about soon and can help set you straight.
 
Last edited:

westaust55

Moderator
You indicate 08M and. Later pins such as C.6 which suggests a larger chip
Ah I see 20x2 mentioned as well
The sparkfun LCD also boots into a higher default baudrate for serial comma. Have you taken this into account.

Seems some clarification may be in order as to how 20 pin chip used with 8 pin board
 
Last edited:

westaust55

Moderator
Okay now I can see more . . .

For some reason I could only see the first about 10 lines of code.

Now have looked at the datasheet as well

For backlight control you must first send the value $7C (decimal 124) followed by a number from 128 (off) to 158 (full on)

You have the command code $FE (decimal 254) followed by the $7C (128) and after a pause the backlight control value but no backlight control command.
I believe that you need a program line akin to:

serout A.0,T9600_8,(124, b1) ; where b1 is your backlight intensity value​
 

NXTreme

Senior Member
Sorry, I should have explained in more detail. My problem isn't with the LCD, I'm pretty sure it's with my code. I already have working code that will let me modify certain settings and such. However, I haven't been able to get this one piece of code working.

Sorry I haven't read the spec on your LCD yet, but device control commands typically require a substantially longer pause after they've been sent than you have listed. You might want to double check that.

I'm far from a good coder as yet, but the "if Enter=1 and BLMenu=0 then" followed by "else", doesn't look at all right. If then what?
Yes, the last 'if' section should be commented out, sorry. I hadn't completely finished it but I wanted to see if it worked before I spent any more time on it. And I have a piece of code that works just fine with the 5 ms pauses (see bottom of post).

You indicate 08M and. Later pins such as C.6 which suggests a larger chip
Ah I see 20x2 mentioned as well
The sparkfun LCD also boots into a higher default baudrate for serial comma. Have you taken this into account.

Seems some clarification may be in order as to how 20 pin chip used with 8 pin board
I have the 20X2 chip plugged into the 08M board with the leftover 12 pins just sticking out. I should have gotten a board intended for the 20 pin Picaxe but I'm trying to finish this soon and shipping can take a couple weeks, if not months, with customs and all. I don't quite understand "The sparkfun LCD also boots into a higher default baudrate for serial comma"... are you saying that when I send a comma it will boot into a higher baudrate? Sorry, not enough coffee!

Okay now I can see more . . .

For some reason I could only see the first about 10 lines of code.

Now have looked at the datasheet as well

For backlight control you must first send the value $7C (decimal 124) followed by a number from 128 (off) to 158 (full on)

You have the command code $FE (decimal 254) followed by the $7C (128) and after a pause the backlight control value but no backlight control command.
I believe that you need a program line akin to:

serout A.0,T9600_8,(124, b1) ; where b1 is your backlight intensity value​
I do have working code to change the backlight value. I just want a piece of code that goes "between" the main menu and the backlight value menu. See the code below. It's a real mess of 'gotos' and other such things but it works and I want to get this project finished soon, with as little time spent rewriting the whole thing as possible.

Code:
	symbol Up=pinC.6 'define symbols
	symbol Down=pinC.7
	symbol Enter=pinB.0
	symbol BLMenu=b3
	symbol MMenu=b2
	high A.0
	pause 850
	
	
inita: pause 150
	'serout A.0,T9600_8,(254,128)
	
	if MMenu=0 then
	pause 5
	serout A.0,T9600_8,("Sensors<        Backlight      -") 'ends configuring initial screen here
	pause 5
	serout A.0,T9600_8,(254,128)
	
	
	elseif MMenu=1 then
	pause 5
	serout A.0,T9600_8,("Sensors        +Backlight<      ")
	pause 5
	serout A.0,T9600_8,(254,128)
	
	elseif MMenu>1 then
	let MMenu=0
	goto inita
	
	endif

ckpin: if Up=1 and MMenu=1 then
	let MMenu=0
	pause 5
	serout A.0,T9600_8,("Sensors<        Backlight      -") 'sets screen on 'up' position
	pause 5
	serout A.0,T9600_8,(254,128)

	
	elseif enter=1 and MMenu=1 then
	do
	loop until Enter=0
	goto initb

	elseif enter=1 and MMenu=0 then
	'put 'goto' here. Goto goes to sensor value display sub-menu
	pause 5
	serout A.0,T9600_8,("Put sensor valu-es here         ")
	pause 5
	serout A.0,T9600_8,(254,128)
	do
	loop until Enter=0
	do
	loop until Enter=1
	do
	loop until Enter=0	
	goto inita
	
	
	elseif Down=1 and MMenu=0 then
	let MMenu=1
	pause 5
	serout A.0,T9600_8,("Sensors        +Backlight<      ") 'sets screen on 'down' position
	pause 5
	serout A.0,T9600_8,(254,128)
	endif
	
	goto ckpin
	
	
	
initb: read 0,b0 'reads saved backlight value

	let b1=b0-128 'does some math to scale brightness from 29 to 100
	let b1=b1*1000/289
	
	pause 5
	serout A.0,T9600_8,(254,1) 'clears screen
	pause 5
	'serout A.0,T9600_8,(254,128) 'sets LCD pointer to first space
	'pause 5
	'serout A.0,T9600_8,("Backlight ",#b1,"% ") 'starts setting up brightness adjustment panel
	'pause 5 'section commented out because the 'goto' at the end of 'init' will do the same thing as this 	section
	serout A.0,T9600_8,(254,143) 'sets LCD pointer to last space availible on first line
	pause 5
	serout A.0,T9600_8,("+") 'continues setting up the brightness adjustment panel
	pause 5
	serout A.0,T9600_8,(254,207) 'sets LCD pointer to last space availible on second line
	pause 5
	serout A.0,T9600_8,("-") 'continues setting up the brightness adjustment panel
	pause 5
	goto value
	
	
burn:	pause 50
	if Up=1 then 'check if the "Up" or "+" button is pressed.
	let b0=b0+1 'if so, increments brightness by one or about 3.45%
	goto value	'then, goes to 'value', the code that adjust the actual brightness
	
	elseif Down=1 then 'same as above, just checks for the "Down" or "-" button to be pressed
	let b0=b0-1 'decreases value, code similar to above
	goto value
	
	elseif Enter=1 then
	do
	loop until Enter=0
	
	write 0,b0 'saves backlight value to EEPROM so that the backlight value stays the same when turned off
		 'the LCD saves the value to its EEPROM but this way the Picaxe also remembers
	goto inita
	endif

	goto burn 'if neither button is pressed, returns to "burn" to repeat cycle
	
	
	
value:	if b0<128 then let b0=128 'code checks value is out of range
	elseif b0>157 then let b0=157 'if it is, it will bring it back to the correct value
	endif

	let b1=b0-128 'does some math to scale brightness from 29 to 100
	let b1=b1*1000/289
	
	pause 5
	serout A.0,T9600_8,(254,128) 'sets LCD pointer to first character
	pause 5
	serout A.0,T9600_8,(124,b0) 'sets brightness
	pause 5
	serout A.0,T9600_8,("Backlight ", #b1,"% ") 'displays actual brightness on screen
	pause 5
	serout A.0,T9600_8,(254,128)
	pause 80
	goto burn 'returns to "burn" to repeat process all over again
 
Last edited:

NXTreme

Senior Member
Ahh, I knew that I was missing something... :)

Anyways, I still wouldn't mind some help. It's a problem with my program flow and/or logic. It just isn't responding to any button presses. If anyone has a slight idea on what could be wrong I'd love some help.
 

BeanieBots

Moderator
Try replacing your serout commands with sertxd commands (plus suitable text) to debug your code.
Alternatively, test it in the simulator to see what/where it goes/does.
 

NXTreme

Senior Member
An excellent idea! I have the LCD attached to the sertxd pin (using serout instead of sertxd for more compatability) and it will only work with True levels (AFAIK) but if I debug to the computer instead of to the LCD, I can use the sertxd command instead. Of course, I could just leave the code the way it is and try it that way.

I have tested it in the sim and it performed as it should, leading me to believe something was wrong with the LCD. However, when I load the main piece of code back on, it works just fine. Will test debugging on the computer.
 
Top