3232 from time import clock as now
3333else :
3434 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
3836
3937LCDConfig = namedtuple ('LCDConfig' , 'rows cols dotsize' )
4038
@@ -45,7 +43,8 @@ class BaseCharLCD(object):
4543
4644 # Init, setup, teardown
4745
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 ):
4948 """
5049 Character LCD controller. Base class only, you should use a subclass.
5150
@@ -63,10 +62,21 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
6362 auto_linebreaks:
6463 Whether or not to automatically insert line breaks.
6564 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.
6772 """
6873 assert dotsize in [8 , 10 ], 'The ``dotsize`` argument should be either 8 or 10.'
6974
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+
7080 # Initialize codec
7181 if charmap == 'A00' :
7282 self .codec = codecs .A00Codec ()
@@ -124,8 +134,6 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
124134 else :
125135 raise ValueError ('Invalid data bus mode: {}' .format (self .data_bus_mode ))
126136
127-
128-
129137 # Write configuration to display
130138 self .command (c .LCD_FUNCTIONSET | displayfunction )
131139 c .usleep (50 )
@@ -146,11 +154,6 @@ def __init__(self, cols=20, rows=4, dotsize=8, charmap='A02', auto_linebreaks=Tr
146154 self .command (c .LCD_ENTRYMODESET | self ._text_align_mode | self ._display_shift_mode )
147155 c .usleep (50 )
148156
149- # Configure compatibility mode
150- self .compat_mode = compat_mode
151- if compat_mode :
152- self .last_send_event = now ()
153-
154157 def close (self , clear = False ):
155158 if clear :
156159 self .clear ()
@@ -253,12 +256,6 @@ def _set_cursor_mode(self, value):
253256 cursor_mode = property (_get_cursor_mode , _set_cursor_mode ,
254257 doc = 'How the cursor should behave (``hide``, ``line`` or ``blink``).' )
255258
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-
262259 # High level commands
263260
264261 def write_string (self , value ):
@@ -467,3 +464,19 @@ def crlf(self): # type: () -> None
467464 """Write a line feed and a carriage return (``\\ r\\ n``) character to the LCD."""
468465 self .write_string ('\r \n ' )
469466
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