PDA

View Full Version : Moving menu down in LCD



rikaine
- 21st August 2015, 16:32
Hello,

I am trying to build a menu that is moving upwards and downwards with buttons on a 20x4 LCD.

I have 6 variables in this scenario and menu looks like this:
[display area]
============ (1)
[V1>15]
[V2=25]
[V3=30]
[V4=40]
V5=55
V6=60
============
Then when I keep pressing down it should move like this:
============ (2)
[V1=15]
[V2>25]
[V3=30]
[V4=40]
V5=55
V6=60
============ (3)
[V1=15]
[V2=25]
[V3>30]
[V4=40]
V5=55
V6=60
============ (4)
V1=15
[V2=25]
[V3=30]
[V4>40]
[V5=55]
V6=60
============ (5)
V1=15
V2=25
[V3=30]
[V4=40]
[V5>55]
[V6=60]
============ (6)
V1=15
V2=25
[V3=30]
[V4=40]
[V5=55]
[V6>60]
============

Here is my code:



rak VAR WORD
ss VAR BYTE 'current line of selection in the menu
qq VAR BYTE 'number of the first line displayed in the LCD
ssmax VAR BYTE 'maximum number of variables
ss1 VAR BYTE 'where to write first variable in the LCD
ss2 VAR BYTE 'where to write second variable in the LCD
ss3 VAR BYTE
ss4 VAR BYTE
ss5 VAR BYTE
ss6 VAR BYTE

advanced:
ssmax=6
ss=1
gosub show_text
advanced_1:
if but=15 then 'up
ss=ss-1
if ss<1 then ss=6
gosub advanced_2
gosub show_text
gosub menu_arrow
endif

if but=16 then 'down
ss=ss+1
if ss>6 then ss=1
gosub ayarlar_advanced_2
gosub show_text
gosub menu_arrow
endif

IF but=17 Then 'enter
' for saving variables modified here
EndIF

gosub type_in

if rak>999 then
for k=0 to 9:p(k)=0:next k:k=0:rak=0
endif

goto advanced_1
advanced_2:
if ss=1 then rak=v1
if ss=2 then rak=v2
if ss=3 then rak=v3
if ss=4 then rak=v4
if ss=5 then rak=v5
if ss=6 then rak=v6
return
show_text:
lcdout$fe,1
qq=ss-2
if (ss-2<=0) then qq=1
if (ss=ssmax) then qq=ss-3

Select Case qq
Case 1:ss1=128:ss2=192:ss3=148:ss4=212:gosub y1:gosub y2:gosub y3:gosub y4
Case 2:ss2=128:ss3=192:ss4=148:ss5=212:gosub y2:gosub y3:gosub y4:gosub y5
Case 3:ss3=128:ss4=192:ss5=148:ss6=212:gosub y3:gosub y4:gosub y5:gosub y6
End Select
return
y1:
lcdout$fe,ss1,"VARIABLE1=",#v1
return
y2:
lcdout$fe,ss2,"VARIABLE2=",#v2
return
y3:
lcdout$fe,ss3,"VARIABLE3=",#v3
return
y4:
lcdout$fe,ss4,"VARIABLE4=",#v4
return
y5:
lcdout$fe,ss5,"VARIABLE5=",#v5
return
y6:
lcdout$fe,ss6,"VARIABLE6=",#v6
return
menu_arrow:
gosub menu_arrow_delete
lcdout$fe,159,">"
if (ss=1) then
gosub menu_arrow_delete
lcdout$fe,139,">"
endif
if (ss=2) then
gosub menu_arrow_delete
lcdout$fe,203,">"
endif
if (ss=ssmax) then
gosub menu_arrow_delete
lcdout$fe,223,">"
endif

' if ss=1 then lcdout$fe,$8b,">" 'I still need to work on this for modifying selected variable
' if ss=2 then lcdout$fe,$cb,">"
' if ss=3 then lcdout$fe,$9f,">"
' if ss=4 then lcdout$fe,$df,">"
return
menu_arrow_delete:
lcdout$fe,$8b,":":lcdout$fe,$cb,":":lcdout$fe,$9f,":":lcdout$fe,$df,":"
return
type_in:
p(k)=but
if but=10 then p(k)=0
k=k+1
if k>3 then
for k=0 to 9:p(k)=0:next k
p(0)=but:LCDOut$fe,155," ":k=1
rak=0

if ss=1 then lcdout$fe,$8c,#rak," "
if ss=2 then lcdout$fe,$cc,#rak," "
if ss=3 then lcdout$fe,$a0,#rak," "
if ss=4 then lcdout$fe,$e0,#rak," "
endif

Select Case k
Case 1:rak=p(0)
Case 2:rak=p(0)*10+p(1)
Case 3:rak=p(0)*100+p(1)*10+p(2)
End Select
return


So the main idea is to shift the menu downwards when last line is reached, or likewise to the upward direction.
As you can see from my code, my knowledge and experience is very limited. I have 3 questions:
1. I somehow managed to make it work with the code above but as you can see it is very inefficient. Is there an easier way to do this? Since string variables are not supported, I am having serious problems with writing a decent function that covers where to write in the LCD.
2. Is there a better way to handle a type_in function? I need to press ESC to clear the number otherwise it becomes messed up.
3. And the most important question: How can I turn this function into a generic one where I can use it for more or less variables?

Thanks in advance.

Art
- 22nd August 2015, 16:33
In very rough syntax:




VV var byte[6] ‘ number of values in VV byte array
work var byte ‘ work variable
index var byte ‘ first counter
indexb var byte ‘ second counter
selected var byte ‘ selected array index
lcdline var byte ‘ lcd line address

selected = 0 ‘ reset selection for startup

‘ reset and init lcd here

cycle:

‘write lcd display
for index = 0 to 3 ‘ one less than the number of lcd lines

gosub get line ‘ get lcd line address
work = VV[index]
LCDOUT $FE,lcdline,[“V”,#selected,” “,”value = “,#work]

if index = 1 then
LCDOUT “<-“ ‘ print arrow on second line
endif

next index

‘ check button here somehow
if buttonpressed = 1 then
gosub rotatearray
endif


goto cycle


getline:
lookup index,[$80,$C0,$94,$D4],lcdline
return

rotatearray: ' bitwise rotate array right eight times
for indexb = 0 to 5
@ rrf _VV+7 ,F ;
@ rrf _VV+6 ,F ;
@ rrf _VV+5 ,F ;
@ rrf _VV+4 ,F ;
@ rrf _VV+3 ,F ;
@ rrf _VV+2 ,F ;
@ rrf _VV+1 ,F ;
@ rrf _VV+0 ,F ;
@ bcf _VV+7 ,7 ;clear MSB
next indexb
return

rikaine
- 22nd August 2015, 20:03
Thank you Art, I will try and report back on Monday.

Art
- 25th August 2015, 01:51
I see errors (late at night). In the last asm routine bitwise rotate
should be index = 0 to 7 (not 0 to 5),
and I did not increment the “selected” value.


IF button presses = 1 then
‘should also include
selected = selected + 1
if selected > 5 then
selected = 0
endif
gosub rotatearray
endif


The selected value tells you what sensor you’re looking at while you’re pointed at zero.

The first thing you should do is learn to start counting from zero like all computers and programming languages do.
Then only when it comes to displaying something like “sensor 0 is reading 32 degrees” to the Humans,
is the point you increment everything by 1 to make it readable to the outside world of Humans.

rikaine
- 25th August 2015, 12:44
Thank you Art, but rotatearray is not working for me.

To simplify the question, I used text on the left side as: V1, V2, V3 but actually they are different strings, that is what creates the problem.

1.MY FIRST VARIABLE=20
================
2.SECOND VALUE =25
3.THIRD ONE =30
4.DIFFERENT >40
5.FIFTH VAR =50
================
6.SIXTH VAR =60

Since I can only show 4 lines on the LCD, when the user presses DOWN button I need to know the following:
selected_variable: Which variable is the user currently on (in the above example: 4)
first_line_displayed: Which lines should be displayed OR which line should be on the top (in the above example: 2)

Here is a table I created:
7981
Dark grey is the currently selected variable
Light grey are displayed in the LCD

Based on this table:
first_line_displayed = selected_variable - 2
IF (selected_variable - 2 <= 0) THEN first_line_displayed = 1
IF (selected_variable = max_number_of_variables) THEN first_line_displayed = selected_variable - 3

This very simple method works for display purposes. However, the problem is I cannot form a loop to go through all 8 (or less/more) variables and display only the ones that should be played based on the table above (and on the correct place). Can you help me form such a loop?

Amoque
- 26th August 2015, 13:51
I think that Select and Case will work:

DG=Dark Grey number
LSD = Line Start Display
MNV = Max Number of Variables

Select case DG
Case is < 4
LSD = 1 : GOSUB Display
Case is 4 to MNV - 1 'MNV calculated or hard coded. Only first 3 and last one are special cases.
LSD = DG - 2 : GOSUB Display
Case = MNV
LSD = MNV - 3: GOSUB Display
End select




Display:
For LP = LSD to LSD + 3
DIPLAY LINE LP
NEXT LP
Return