Повышение скорости вывода графики
Медлительные изделия никому не нравятся, а то, как вы работаете с дисплеем, сильно влияет на воспринимаемую производительность изделия. Мы говорим «воспринимаемую», потому что очень часто она никак не связана с реальной скоростью, с которой устройство выполняет нужные операции.
Группируйте операции с дисплеем
Самое важное в производительности приложения (применительно к дисплею) - как быстро данные на дисплее кажутся изменившимися. Интересно, что важнее всего не общее время подготовки и показа новых данных, а то, насколько «одновременно» все новые элементы появляются на экране.
Покажем это на примере. Вот два фрагмента кода, которые делают одно и то же и выполняются примерно за одинаковое время. Вычисляются и печатаются два значения. В первом примере вычисляется и печатается значение 1, затем вычисляется и печатается значение 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)
Во втором примере сначала вычисляются значения 1 и 2, а затем они печатаются вместе:
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)
Проверка обоих примеров показывает, что воспринимаемая скорость второго фрагмента заметно выше, хотя общее время работы процессора примерно одинаково. Откуда разница? Оттого, что во втором примере вывод двух значений разделён меньшим промежутком!
Вывод: держите весь вывод на дисплей как можно ближе друг к другу. Сначала заранее вычислите всё, затем показывайте все элементы «разом».
Используйте блокировку дисплея
Сколько ни группируй вывод на дисплей, последовательное выполнение методов объекта lcd. всё равно может занять немало времени. Воспринимаемую скорость можно улучшить на дисплеях, которые позволяют «заблокировать» картинку, изменить данные дисплея и снова разблокировать его. При таком подходе пользователь увидит все изменения мгновенно! Подходят не все дисплеи. Обычно это хорошо работает с TFT-панелями, которые продолжают показывать изображение несколько секунд после отключения «обновления». Другие типы дисплеев для блокировки не подходят. Сведения о блокировке приведены для каждого поддерживаемого контроллера/панели.
Дисплей блокируется и разблокируется методами lcd.lock и lcd.unlock. Можно поставить lcd.lock перед блоком кода, меняющим данные дисплея, а lcd.unlock - в конце этого блока:
...
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
...
Код для работы с дисплеем часто бывает вложенным: одна процедура вызывает другую и так далее. При использовании блокировки дисплея блокировку и разблокировку лучше ставить в каждую связанную процедуру. Возникает сложность с тем, когда разблокировать дисплей. Например, пусть есть две процедуры: lcd_sub1 и 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 выполняется, когда её вызывает непосредственно основной код, а также при вызове lcd_sub1. Во втором случае дисплей не нужно разблокировать в конце lcd_sub2, потому что вывод продолжится в lcd_sub1! И знаете что? Дисплей не будет разблокирован, ведь объект lcd. допускает вложенные блокировки и разблокировки! В следующем примере выполняются три блокировки подряд, и дисплей блокируется уже по первой. Затем выполняются три разблокировки подряд, и дисплей разблокируется только после третьей:
...
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
...
Механизм блокировки и разблокировки ведёт счётчик, который можно прочитать через свойство только для чтения lcd.lockcount. Каждый вызов lcd.lock увеличивает счётчик на 1, а каждый lcd.unlock уменьшает на 1. Дисплей разблокирован, только когда счётчик равен 0, и заблокирован, когда счётчик > 0. Это позволяет вкладывать процедуры работы с дисплеем друг в друга и спокойно ставить блокировку и разблокировку в каждую из них!