Im not doing the serial writes inside an ISR, they take place inside of a while loop in main.py. I have experimented with timeout values all the way up to 1000ms and I always get the error. Here is the complete serial LCD class in its current rough state:
Code: Select all
'''This is a simple class for interfacing an Adafruit serial LCD with a pyboard.'''
import pyb
#define our LCD commands
LCD_COMMAND = 0xFE
DISPLAY_ON = 0x42
DISPLAY_OFF = 0x46
SET_BRIGHTNESS = 0x99
SET_SAVE_BRIGHTNESS = 0x98
SET_CONTRAST = 0x50
SET_SAVE_CONTRAST = 0x91
AUTOSCROLL_ON = 0x51
AUTOSCROLL_OFF = 0x52
CLEAR_DISPLAY = 0x58
SET_SPLASH_SCREEN = 0x40
SET_CURSOR_POS = 0x47
GO_HOME = 0x48
CURSOR_BACK = 0x4C
CURSOR_FORWARD = 0x4D
UNDERLINE_CURSOR_ON = 0x4A
UNDERLINE_CURSOR_OFF = 0x54
BLOCK_CURSOR_ON = 0x53
BLOCK_CURSOR_OFF = 0x54
SET_BACKLIGHT_COLOR = 0xD0
SET_LCD_SIZE = 0xD1
CREATE_CUSTOM_CHAR = 0x4E
SAVE_CUSTOM_CHAR = 0XC1
LOAD_CUSTOM_CHAR = 0XC0
SET_GPO_OFF = 0x56
SET_GPO_ON = 0X57
class AfSerialLCD:
def __init__(self, uartNum, timeout=1000, timeout_char=1000, baud=9600 ):
if uartNum == 5 or uartNum < 1 or uartNum > 6:
raise ValueError
self.uart = pyb.UART( uartNum, baud)
def sendCommand(self, command):
try:
self.uart.writechar(LCD_COMMAND)
self.uart.writechar(command)
except:
print ("timeout error!")
def writeString(self,string):
self.uart.write(string)
def clearScreen(self):
self.sendCommand(CLEAR_DISPLAY)
def setContrast(self,contrast, save=False):
if save == False:
self.sendCommand(SET_CONTRAST)
else:
self.sendCommand(SET_SAVE_CONTRAST)
self.uart.writechar(contrast)
def setBrightness(self,brightness, save=False):
if save == False:
self.sendCommand(SET_BRIGHTNESS)
else:
self.sendCommand(SET_SAVE_BRIGHTNESS)
self.uart.writechar(brightness)
def setSaveBrigthness(self, brightness):
self.sendCommand(SET_SAVE_BRIGHTNESS)
self.uart.writechar(brightness)
def displayOn(self):
self.sendCommand(DISPLAY_ON)
def displayOff(self):
self.sendCommand(DISPLAY_OFF)
def home(self):
self.sendCommand(GO_HOME)
def setCursorPosition(self, row,col):
self.sendCommand(SET_CURSOR_POS)
self.uart.writechar(col)
self.uart.writechar(row)
def setBacklightColor(self,r,g,b):
try:
self.sendCommand(SET_BACKLIGHT_COLOR)
self.uart.writechar(r)
self.uart.writechar(g)
self.uart.writechar(b)
except:
print ("timeout error!")
def setAutoscroll(self, scrollState):
if scrollState == True:
self.sendCommand(AUTOSCROLL_ON)
else:
self.sendCommand(AUTOSCROLL_OFF)
def setSplashScreen(self, splashMsg):
self.sendCommand(SET_SPLASH_SCREEN)
self.uart.write(splashMsg)
def cursorBack(self):
self.sendCommand(CURSOR_BACK )
def cursorForward(self):
self.sendCommand(CURSOR_FORWARD)
def setUnderlineCursor(self, state=True):
if state == True:
self.sendCommand(UNDERLINE_CURSOR_ON)
else:
self.sendCommand(UNDERLINE_CURSOR_OFF)
def setBlockCursor(self, state=True):
if state == True:
self.sendCommand(BLOCK_CURSOR_ON)
else:
self.sendCommand(BLOCK_CURSOR_OFF)
def setLCDSize(self, rows=2, cols=16):
self.sendCommand(SET_LCD_SIZE)
self.uart.writechar(rows)
self.uart.writechar(cols)
def setGPOState(self, gpoNum, state=False):
if gpoNum < 1 or gpoNum > 4:
print("ERROR: gpoNum must be 1-4 in setGPOState")
return
if state == False:
self.sendCommand(SET_GPO_OFF)
self.uart.writechar(gpoNum)
return
elif state == True:
self.sendCommand(SET_GPO_ON)
self.uart.writechar(gpoNum)
return
else:
print("ERROR: Unknown state for setGPOState.")
def createCustomChar(self, charNum, byteList):
if charNum < 0 or chatNum > 7:
print("ERROR: charnum must be 0-7 in createCustomChar.")
return
if len(byteList) > 8:
print("ERROR: byteList must be list of 8 buyes in createCustomChar.")
return
self.sendCommand(CREATE_CUSTOM_CHAR)
for char in byteList:
self.uart.writechar(char)
Inside of main.py I create an AfSerialLCD object:
I have a bunch of stuff to test out various capabilities of the Pyboard:
1. The serial LCD of course.
2. A LDR hooked up to one of the ADC lines
3. An LED hooked up to a PWM output. I read the LDR and feed its scaled output inte the LED.
4. An Omrom EE-SB5 hooked into another ADC pin. Its a simple IR reflectance sensor.
5. The leaf switch which is hooked into my ISR.
6. A 10K pot. The reading of the pot gets scaled and sent to the serial LCD as the red value of the backlight.
7. Finally another LED which is on when the leaf switch is pressed, off otherwise.
The main while loop looks like the following:
Code: Select all
#start our ISR
leafInt = pyb.ExtInt(leafPin, pyb.ExtInt.IRQ_RISING_FALLING, pyb.Pin.PULL_DOWN, leafCallback)
try:
while(True):
photoVal = photoResistor.read()
topHatVal = topHat.read()
potVal = pot.read()
lcd.setBacklightColor( int(remap(potVal, 0,4095,0,255)),0,0)
pwmPercent = int( remap(photoVal, photoLow, photoHigh, 0, 100) )
leds [randRange(0,4)].toggle()
pyb.delay( randRange(low, high) )
y3LED.value(leafPin.value())
if sw() == True:
print ( "Photo:",photoVal,"\tTop Hat:",topHatVal,"\tPot:",potVal,"\tPWM:",pwmPercent )
ch.pulse_width_percent( pwmPercent )
finally:
for led in leds:
led.off()
y3LED.value(False)
leafInt.disable()
ch.pulse_width_percent(0)
The "lcd.setBacklightColor( int(remap(potVal, 0,4095,0,255)),0,0)" is where the serial write will occur.
And finally, the (cleaned up) ISR for the leaf switch looks like this:
Code: Select all
#=======================================================================
# Callback for our leaf switch
#=======================================================================
def leafCallback(line):
global leafCounter
pyb.delay(3) #delay for debounce
if leafPin.value() == 1:
leafCounter += 1
#print ("Leaf count: ",leafCounter)
I can write to the serial LCD all day long and it works as long as the ISR is not both active and triggered. However, once I put the serial write inside of the while loop if the ISR triggers it has a chance of throwing the timeout error.