Improving Graphical Performance
Nobody likes sluggish products, and the way you work with your display can greatly influence the perceived performance of your product. We say "perceived" because very often this has nothing to do with the actual speed at which your device completes required operations.
Group Display-Related Operations Together
The most important aspect of your application's performance (related to the display) is how fast the data on the display appears to have changed. Interestingly, what matters most is not the total time it takes to prepare and show the new data, but the "togetherness" at which all new displayed items pop up on the screen.
Let's illustrate this point. Here are two code examples that do the same and take roughly the same time to execute. We calculate and print two values. In the first example, we calculate and print value 1, then calculate and print value 2:
Dim dw1,dw2 As dword
...
'Note so good! The user will see a noticeable delay between the first and the second print.
lcd.print(str(dw1*100/200),0,0)
lcd.print(str(dw2*100/200),0,10)
In the second example, we calculate values 1 and 2 first, then print them together:
Dim dw1,dw2 As dword
Dim s1,s2 As String
...
'Much better. The user will have a feeling that both values were calculated and printed instantly!
s1=str(dw1*100/200)
s2=str(dw2*100/200)
lcd.print(s1,0,0)
lcd.print(s2,0,10)
Testing both examples shows that the perceived performance of the second code snippet is much better, while, in fact, the total working time of the processor was roughly the same. Why is there a difference? Because the output of the two values in the second example was spaced closer!
Bottom line: keep all display output as close together as possible. Pre-calculate everything first, then display all your items "at once."
Use Display Locking
No matter how hard you try to group all display-related output together, executing the lcd. object's methods one after another may still take considerable time. Perceived performance can be improved on displays that allow you to "lock" the display picture, change display data, and then unlock the display again. With this approach, the user will see all changes appear instantly! Not all displays are suitable for this. Typically, this works well for TFT panels that continue to display the image for several seconds after the "refresh" was disabled. Other display types are not suitable for locking. We have provided locking-related info for each supported controller/panel.
The display is locked/unlocked using the lcd.lock and lcd.unlock methods. You can place lcd.lock before the block of code that changes display data and put lcd.unlock at the end of this code block:
...
s1=str(dw1*100/200)
s2=str(dw2*100/200)
lcd.lock 'lock the display
lcd.print(s1,0,0)
lcd.print(s2,0,10)
lcd.unlock 'unlock the display
...
Display-related code is often nested, with one procedure calling another, and so on. If you are using display locking, you should ideally place locks/unlocks in each related routine. A complication arises with regards to when to unlock the display. For example, suppose you have two subs: lcd_sub1 and lcd_sub2:
'some main routine that invokes lcd_sub1 and lcd_sub2
....
....
lcd_sub1
...
...
lcd_sub2
...
End Sub
'-----------------------------------------
Sub lcd_sub1 'calls sub2 too
lcd.lock
...
lcd_sub2
...
lcd.unlock
End Sub
'-----------------------------------------
Sub lcd_sub2 'called by sub1
lcd.lock
...
lcd.unlock
End Sub
Lcd_sub2 gets executed when invoked directly by the main code, and also when the lcd_sub1 is called. In the second case, the display should not be unlocked at the end of lcd_sub2, because the output is to be continued in lcd_sub1! And you know what? The display won't be unlocked, because with the lcd. object it is possible to nest locks/unlocks! In the following example, we do three consecutive locks and the display is locked right on the first one. We then do three consecutive unlocks, and the display is not unlocked until after the third one is executed:
...
lcd.lock 'lcd.lockcount=1, display is now locked
lcd.lock 'lcd.lockcount=2
lcd.lock 'lcd.lockcount=3
lcd.unlock 'lcd.lockcount=2
lcd.unlock 'lcd.lockcount=1
lcd.unlock 'lcd.lockcount=0, display is now unlocked
...
The lock/unlock mechanism maintains a counter, which can actually be read through the lcd.lockcount read-only property. Each invocation of lcd.lock increments the counter by 1 and each lcd.unlock decrements it by 1. The display is only unlocked when the counter is at 0 and locked when the counter is > 0. This allows you to nest display-related procedures and safely have lock/unlock in each one of them!