32
32
from time import clock as now
33
33
else :
34
34
from time import perf_counter as now
35
-
36
- # Duration to rate-limit calls to _send
37
- COMPAT_MODE_WAIT_TIME = 0.001
35
+ from time import sleep
38
36
39
37
LCDConfig = namedtuple ('LCDConfig' , 'rows cols dotsize' )
40
38
@@ -45,7 +43,8 @@ class BaseCharLCD(object):
45
43
46
44
# Init, setup, teardown
47
45
48
- def __init__ (self , cols = 20 , rows = 4 , dotsize = 8 , charmap = 'A02' , auto_linebreaks = True , compat_mode = False ):
46
+ def __init__ (self , cols = 20 , rows = 4 , dotsize = 8 , charmap = 'A02' , auto_linebreaks = True , compat_mode = False ,
47
+ compat_mode_wait_time = 0.001 ):
49
48
"""
50
49
Character LCD controller. Base class only, you should use a subclass.
51
50
@@ -63,10 +62,21 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
63
62
auto_linebreaks:
64
63
Whether or not to automatically insert line breaks.
65
64
Default: True.
66
-
65
+ compat_mode:
66
+ Whether to run additional checks to support older LCDs
67
+ that may not run at the reference clock (or keep up with it).
68
+ Default: False
69
+ compat_mode_wait_time: Minimum time to pass between sends.
70
+ if zero, turns off compat_mode
71
+ Default: ``0.001`` seconds.
67
72
"""
68
73
assert dotsize in [8 , 10 ], 'The ``dotsize`` argument should be either 8 or 10.'
69
74
75
+ # Configure compatibility mode
76
+ self .compat_mode = compat_mode and compat_mode_wait_time > 0
77
+ self .compat_mode_wait_time = compat_mode_wait_time
78
+ self ._compat_mode_record_send_event ()
79
+
70
80
# Initialize codec
71
81
if charmap == 'A00' :
72
82
self .codec = codecs .A00Codec ()
@@ -124,8 +134,6 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
124
134
else :
125
135
raise ValueError ('Invalid data bus mode: {}' .format (self .data_bus_mode ))
126
136
127
-
128
-
129
137
# Write configuration to display
130
138
self .command (c .LCD_FUNCTIONSET | displayfunction )
131
139
c .usleep (50 )
@@ -146,11 +154,6 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
146
154
self .command (c .LCD_ENTRYMODESET | self ._text_align_mode | self ._display_shift_mode )
147
155
c .usleep (50 )
148
156
149
- # Configure compatibility mode
150
- self .compat_mode = compat_mode
151
- if compat_mode :
152
- self .last_send_event = now ()
153
-
154
157
def close (self , clear = False ):
155
158
if clear :
156
159
self .clear ()
@@ -253,12 +256,6 @@ def _set_cursor_mode(self, value):
253
256
cursor_mode = property (_get_cursor_mode , _set_cursor_mode ,
254
257
doc = 'How the cursor should behave (``hide``, ``line`` or ``blink``).' )
255
258
256
- def _wait (self ):
257
- """Rate limit the number of send events."""
258
- end = self .last_send_event + COMPAT_MODE_WAIT_TIME
259
- while now () < end :
260
- pass
261
-
262
259
# High level commands
263
260
264
261
def write_string (self , value ):
@@ -467,3 +464,19 @@ def crlf(self): # type: () -> None
467
464
"""Write a line feed and a carriage return (``\\ r\\ n``) character to the LCD."""
468
465
self .write_string ('\r \n ' )
469
466
467
+ def _is_compat_mode_on (self ):
468
+ """Compat mode is on, when it's enabled and the wait time is > 0"""
469
+ return self .compat_mode and self .compat_mode_wait_time > 0
470
+
471
+ def _compat_mode_wait (self ):
472
+ """Wait the specified amount, if the compat mode is on, to rate limit the data transmission"""
473
+ if self ._is_compat_mode_on ():
474
+ end = self .last_send_event + self .compat_mode_wait_time
475
+ sleep_duration = end - now ()
476
+ if sleep_duration > 0 :
477
+ sleep (sleep_duration )
478
+
479
+ def _compat_mode_record_send_event (self ):
480
+ """Record when did the last send take place, so the rate limiting adapts to any slowdowns."""
481
+ self .last_send_event = now ()
482
+
0 commit comments