In a proposed project for an intelligent battery charger/ discharger, I require a menu and number input.
To avoid the extra expense and space required by a keypad I wrote the code below, which requires the 2x16 LCD module connected to an output pin – to one of the Darlington outputs here – and three switches connected to three of the input pins.
The menu sub displays the menu options on the second line and the cursor on the top line. The cursor can be moved left and right with the push switches. Using OK selects the cursor option.
The maximum number of options is determined by optCount*optLength <= 16 ,remembering to count the option delimiter as a character, eg Op1 Op2 Op3 Op4 with optLength=4 and optCount=4
You must set optLength and optCount constants in the code and
the menu string in the menu sub – it would better in EEPROM at the start of the program.
The getNumber sub displays the digits 012..9 on the second line with a ‘control’ symbol after the 9
The sub works in a similar way to the menu one with two additions:
The compiled integer is shown at the right of line1;
The ‘control’ character after 9 allows for last digit deletion or final OK.
In this position <- moves left as usual, OK confirms the number but -> deletes the last digit entered.
The symbol helps to remind what buttons to use – you get used to it after a time!
The number is checked for maximum length but not magnitude.
To avoid the extra expense and space required by a keypad I wrote the code below, which requires the 2x16 LCD module connected to an output pin – to one of the Darlington outputs here – and three switches connected to three of the input pins.
The menu sub displays the menu options on the second line and the cursor on the top line. The cursor can be moved left and right with the push switches. Using OK selects the cursor option.
The maximum number of options is determined by optCount*optLength <= 16 ,remembering to count the option delimiter as a character, eg Op1 Op2 Op3 Op4 with optLength=4 and optCount=4
You must set optLength and optCount constants in the code and
the menu string in the menu sub – it would better in EEPROM at the start of the program.
The getNumber sub displays the digits 012..9 on the second line with a ‘control’ symbol after the 9
The sub works in a similar way to the menu one with two additions:
The compiled integer is shown at the right of line1;
The ‘control’ character after 9 allows for last digit deletion or final OK.
In this position <- moves left as usual, OK confirms the number but -> deletes the last digit entered.
The symbol helps to remind what buttons to use – you get used to it after a time!
The number is checked for maximum length but not magnitude.
Code:
'Menu chooser and number input by using three pins
'skeldro – Oct 2011. Use at your own risk.
'Menu of optCount optLength char options
'LCD routines for 8MHz -----
'In xtick box (after the 9)
' left moves the cursor left
' right deletes the last digit of the number
' OK exits the procedure with num
'--------- sub-routines ----------------
'init - the lcd
'menu - displays menu and returns option
'getNumber - allows word number input and returns num
'------ constants and variables--------
'address 0 of the scratchpad is used by getNumber
symbol optLength = 3 'Character length of each option-set to suit *****************
symbol optCount = 4 'Number of options -set to suit ******************************
symbol lcdPort = 6 'reserved for LCD serial link
symbol serPort = 7 'reserved for serial link to PC but not used here
symbol leftPin = pin0 'the cursor switches, set to suit
symbol rightPin = pin1
symbol OKpin = pin2
'w0 to w8 available for user - use reserved ones with care
symbol wCal = w9
symbol num = w10
'b22 spare
symbol tmp = b23
symbol dCur = b24 '1-9 for left and 11-19 for right
symbol cur = b25 'reserved for cur logical position, 0,1,2 etc
symbol option = b26 'reserved for cur LCD position, eg 0,3,6
symbol cal = b27 'reserved for calculations
'-------------------------
setFreq m8
gosub initLCD
serout LCDport,T2400_8, (254,64,36,36,36,36,36,53,46,36) 'preload cursor
' use serout LCDport,T2400_8,(8) to display
serout LCDport, T2400_8, (254,72,35,35,40,63,40,33,42,36) 'preload xtick
' use ...(9)
'========================main loop==========
do
gosub menu
on option gosub number,other,quit 'sample subs
loop until option = 2
end
'========= Sub-routines go here =============
'--------------Sample Option----------------
number:
gosub getNumber
serout lcdPort,T2400_8,(254,192) 'Start of line 2
serout lcdPort,T2400_8,(#num," Press OK...")
gosub waitForOK
return
'----------------Sample Option----------------
other:
serout lcdPort,T2400_8,("Other..Press OK...")
gosub waitForOK
return
'--------------------------------------------
quit:
serout lcdPort,T2400_8,("Finished")
return
'======================================================
menu:
gosub clearr
cur = 0
serout LCDport,T2400_8,(8) 'the cursor
serout lcdPort,T2400_8,(254,192) 'line 2, pos 1
serout lcdPort,T2400_8,("Vo Ch Di Qu ") 'the menu
option = 0 'none chosen
do
if leftPin=1 then 'go left
if cur >= optLength then
dCur = optLength
gosub moveCursor
end if
do loop until leftPin=0
else if rightPin=1 then 'go right
cal = optCount-1
cal = optLength*cal
if cur < cal then
dCur = optLength+10
gosub moveCursor
end if
do loop until rightPin=0
elseif OKpin=1 then 'select option
cal = cur/optLength
option = cal + 1
do loop until OKpin=0
end if
loop until option <> 0
gosub clearr
option = option - 1 'for on gosub
return
'----------------------------------------
getNumber:
gosub clearr
serout LCDport,T2400_8,(8) 'the cursor
serout lcdPort,T2400_8,(254,192) 'line 2, pos 1
serout lcdPort,T2400_8,("O123456789") '012...9
serout lcdPort,T2400_8,(9) 'xtick symbol
cur = 11
gosub moveTo
serout lcdPort,T2400_8,("0") 'the number
num = 0
cur = 0
put 0,0 'number digits
do
if leftPin=1 then 'go lleft
if cur > 0 then
dCur = 1
gosub moveCursor
end if
do loop until leftPin=0
elseif rightPin=1 then 'go right
if cur < 10 then 'go right
dCur = 11
gosub moveCursor
else 'delete digit
get 0,cal 'number digits from scratchpad
if cal>0 then 'something to delete
num = num/10
cal=cal-1
put 0,cal 'store new length
cur = 11 'update display and
gosub moveTo
serout lcdPort,T2400_8,(" ")
cur = 11 'update display and
gosub moveTo
serout lcdPort,T2400_8,(#num)
cur=10
dCur = 1 'move cursor out off xtick
gosub moveCursor
end if
end if
do loop until rightPin=0
elseif OKpin=1 then
if cur <> 10 then
get 0,cal 'number digits
if cal < 5 then
num = 10*num
num = num+cur
cal = cal+1
put 0,cal
tmp=cur 'save it
cur = 11
gosub moveTo
cur=tmp 'restore cursor
serout lcdPort,T2400_8,(#num)
end if
else
option = 1 'set exit flag
end if
do loop until OKpin=0
end if
loop until option <> 0
gosub clearr
return
'-----------------------------------------
waitForOK:
do loop until OKpin=1
do loop until OKpin=0
return
'------------------------------------------
moveTo: 'cur position on line 1
cal = 128+cur
serout LCDport,T2400_8,(254,cal)
return
'-----------------------------------------
moveCursor: 'from cur by dCur
gosub moveTo
serout lcdPort,T2400_8,(" ") 'delete cursor
if dCur < 10 then 'move left
cur = cur-dCur
else 'move right
cal = dCur-10
cur = cur+cal
end if
gosub moveTo 'cursor placed
serout lcdPort,T2400_8,(8)
return
'------------------------------------------
clearr:
serout lcdPort,T2400_8,(254,1)
pause 30
return
'-------------------------------------------
initLCD:
pause 500 'to let LCD settle
serout lcdPort,T2400_8,(254,14) 'cursor on
pause 30
serout lcdPort,T2400_8,(254,1) 'clear
pause 30
return