Initial import

This commit is contained in:
Markus Birth 2015-10-14 22:56:34 +02:00
commit 876909e6db
6 changed files with 378 additions and 0 deletions

31
README.md Normal file
View File

@ -0,0 +1,31 @@
Font library for MicroPython
============================
The [LCD32MKv1.0](https://micropython.org/store/#/products/LCD32MKv1_0) features
a 4-line graphical LCD with 128x32 pixels. I wanted to fit a bit more on the
small screen so I looked for a smaller font.
I found [Four Pixel Caps](http://www.dafont.com/four-pixel-caps.font) and
converted it into an array of bits. And since you can't just set a font with the
LCD module, I had to write my own writing routines to have virtual lines,
line breaks, etc..
This library is `FontLCD`. Just use it like you would `pyb.LCD`.
Example
-------
```
import fontlcd
lcd = fontlcd.FontLCD('X')
lcd.light(True)
lcd.loadFont('fourpx')
lcd.write('Hello world!\n')
```
Also see the included `main.py`.
(The mpr121.py is a copy from the example file mentioned in the
[LCD/touch skin documentation](http://docs.micropython.org/en/latest/pyboard/tutorial/lcd_skin.html#using-the-touch-sensor).)

7
boot.py Normal file
View File

@ -0,0 +1,7 @@
# boot.py -- run on boot-up
# can run arbitrary Python, but best to keep it minimal
import pyb
#pyb.main('main.py') # main script to run after this one
#pyb.usb_mode('CDC+MSC') # act as a serial and a storage device
#pyb.usb_mode('CDC+HID') # act as a serial device and a mouse

94
lib/fontlcd.py Normal file
View File

@ -0,0 +1,94 @@
"""
LCD class with font support
CC-BY-SA 2014, Markus Birth <markus@birth-online.de>
"""
from pyb import LCD
class FontLCD(LCD):
def __init__(self, skin_position):
super().__init__()
self.isFontLoaded = False
self.cursorX = 0
self.cursorY = 0
self.cursorLine = 0
self.font = []
self.fontWidth = 3
self.fontHeight = 4
self.calculateLines()
def calculateLines(self, lineSpacing = 1):
self.displayWidth = 128
self.displayHeight = 32
self.lineSpacing = lineSpacing
self.maxLines = self.displayHeight // ( self.fontHeight + self.lineSpacing )
self.lines = [""] * self.maxLines
def loadFont(self, fontname):
fontfile = __import__(fontname)
self.font = fontfile.fontdata
self.isFontLoaded = True
self.write("FONT LOADED.")
for i in range(1,6):
self.write("\nThis is line %i" % i)
def redraw(self):
self.fill(0)
self.cursorX = 0
self.cursorY = 0
line_temp = list(self.lines)
for l in range(0, self.maxLines):
self.lines[l] = ""
for l in range(0, self.maxLines-1):
self.cursorX = 0
self.cursorY = l * (self.fontHeight + self.lineSpacing)
self.cursorLine = l
self.write(line_temp[l])
self.show()
def newline(self):
self.cursorX = 0
self.cursorY = self.cursorY + self.fontHeight + self.lineSpacing
self.cursorLine = self.cursorLine + 1
if self.cursorLine >= self.maxLines:
for i in range(0, self.maxLines - 1):
self.lines[i] = self.lines[i+1]
self.lines[self.maxLines - 1] = ""
self.redraw()
self.cursorLine = self.maxLines - 1
def writeLetter(self, charcode, x0, y0):
letter = self.font[charcode]
for x in range(0, self.fontWidth):
for y in range(0, self.fontHeight):
bit = letter[x] & 2**y
self.pixel(x0 + x, y0 + y, bit)
def text(self, text, x, y, colour):
if not self.isFontLoaded:
super().text(text, x, y, colour)
else:
for i in range(0, len(text)):
charcode = ord(text[i])
if charcode >= 32 and charcode <= 127:
self.writeLetter(charcode, x, y)
x = x + self.fontWidth + 1
self.show()
def write(self, text):
if not self.isFontLoaded:
# no font loaded - use built-in function
super().write(text)
else:
for i in range(0, len(text)):
charcode = ord(text[i])
if charcode >= 32 and charcode <= 127:
self.writeLetter(charcode, self.cursorX, self.cursorY)
self.cursorX = self.cursorX + self.fontWidth + 1
self.lines[self.cursorLine] += chr(charcode)
if self.cursorX > self.displayWidth:
self.newline()
elif charcode == 10:
self.newline()
self.show()

109
lib/fourpx.py Normal file
View File

@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# GLCD FontName : FourPx3x4
# GLCD FontSize : 3 x 4
# Based on http://www.dafont.com/four-pixel-caps.font
fontdata = [
[], [], [], [], [], [], [], [],
[], [], [], [], [], [], [], [],
[], [], [], [], [], [], [], [],
[], [], [], [], [], [], [], [],
[ 0x00, 0x00, 0x00 ], # Code for char
[ 0x00, 0x0B, 0x00 ], # Code for char !
[ 0x03, 0x00, 0x03 ], # Code for char "
[ 0x00, 0x00, 0x00 ], # Code for char #
[ 0x0A, 0x0F, 0x05 ], # Code for char $
[ 0x0D, 0x00, 0x0B ], # Code for char %
[ 0x00, 0x00, 0x00 ], # Code for char &
[ 0x00, 0x03, 0x00 ], # Code for char '
[ 0x00, 0x06, 0x09 ], # Code for char (
[ 0x09, 0x06, 0x00 ], # Code for char )
[ 0x0A, 0x04, 0x0A ], # Code for char *
[ 0x04, 0x0E, 0x04 ], # Code for char +
[ 0x08, 0x0C, 0x00 ], # Code for char ,
[ 0x04, 0x04, 0x04 ], # Code for char -
[ 0x00, 0x08, 0x00 ], # Code for char .
[ 0x08, 0x06, 0x01 ], # Code for char /
[ 0x0F, 0x09, 0x0F ], # Code for char 0
[ 0x02, 0x0F, 0x00 ], # Code for char 1
[ 0x0D, 0x0F, 0x0B ], # Code for char 2
[ 0x09, 0x0B, 0x0C ], # Code for char 3
[ 0x07, 0x04, 0x0F ], # Code for char 4
[ 0x0B, 0x0D, 0x01 ], # Code for char 5
[ 0x07, 0x0A, 0x04 ], # Code for char 6
[ 0x01, 0x0D, 0x03 ], # Code for char 7
[ 0x0F, 0x0A, 0x0F ], # Code for char 8
[ 0x02, 0x05, 0x0E ], # Code for char 9
[ 0x00, 0x0A, 0x00 ], # Code for char :
[ 0x08, 0x0A, 0x00 ], # Code for char ;
[ 0x00, 0x04, 0x0A ], # Code for char <
[ 0x0A, 0x0A, 0x0A ], # Code for char =
[ 0x0A, 0x04, 0x00 ], # Code for char >
[ 0x01, 0x0D, 0x02 ], # Code for char ?
[ 0x00, 0x00, 0x00 ], # Code for char @
[ 0x0E, 0x05, 0x0F ], # Code for char A
[ 0x0F, 0x0B, 0x0E ], # Code for char B
[ 0x0E, 0x09, 0x09 ], # Code for char C
[ 0x0F, 0x09, 0x06 ], # Code for char D
[ 0x0C, 0x0B, 0x09 ], # Code for char E
[ 0x0E, 0x05, 0x01 ], # Code for char F
[ 0x07, 0x09, 0x0D ], # Code for char G
[ 0x0F, 0x02, 0x0F ], # Code for char H
[ 0x00, 0x0F, 0x00 ], # Code for char I
[ 0x08, 0x09, 0x07 ], # Code for char J
[ 0x0F, 0x04, 0x0A ], # Code for char K
[ 0x07, 0x08, 0x08 ], # Code for char L
[ 0x0F, 0x07, 0x0E ], # Code for char M
[ 0x0F, 0x01, 0x0E ], # Code for char N
[ 0x07, 0x09, 0x0E ], # Code for char O
[ 0x0F, 0x05, 0x06 ], # Code for char P
[ 0x07, 0x0D, 0x07 ], # Code for char Q
[ 0x0E, 0x05, 0x0B ], # Code for char R
[ 0x0B, 0x0B, 0x0D ], # Code for char S
[ 0x01, 0x0F, 0x01 ], # Code for char T
[ 0x07, 0x08, 0x0F ], # Code for char U
[ 0x0F, 0x04, 0x03 ], # Code for char V
[ 0x0F, 0x0E, 0x07 ], # Code for char W
[ 0x0D, 0x06, 0x0B ], # Code for char X
[ 0x03, 0x0C, 0x03 ], # Code for char Y
[ 0x0D, 0x0B, 0x09 ], # Code for char Z
[ 0x00, 0x0F, 0x09 ], # Code for char [
[ 0x01, 0x06, 0x08 ], # Code for char BackSlash
[ 0x09, 0x0F, 0x00 ], # Code for char ]
[ 0x02, 0x01, 0x02 ], # Code for char ^
[ 0x08, 0x08, 0x08 ], # Code for char _
[ 0x00, 0x01, 0x02 ], # Code for char `
[ 0x0C, 0x06, 0x0C ], # Code for char a
[ 0x0F, 0x0A, 0x04 ], # Code for char b
[ 0x04, 0x0A, 0x0A ], # Code for char c
[ 0x04, 0x0A, 0x0F ], # Code for char d
[ 0x0C, 0x0E, 0x0A ], # Code for char e
[ 0x04, 0x0F, 0x05 ], # Code for char f
[ 0x0A, 0x0D, 0x0E ], # Code for char g
[ 0x0E, 0x04, 0x08 ], # Code for char h
[ 0x00, 0x0D, 0x00 ], # Code for char i
[ 0x08, 0x0A, 0x06 ], # Code for char j
[ 0x0E, 0x04, 0x0A ], # Code for char k
[ 0x00, 0x0E, 0x08 ], # Code for char l
[ 0x0E, 0x06, 0x0C ], # Code for char m
[ 0x0E, 0x02, 0x0C ], # Code for char n
[ 0x04, 0x0A, 0x04 ], # Code for char o
[ 0x0E, 0x05, 0x02 ], # Code for char p
[ 0x06, 0x05, 0x0E ], # Code for char q
[ 0x00, 0x0C, 0x02 ], # Code for char r
[ 0x08, 0x0E, 0x02 ], # Code for char s
[ 0x02, 0x07, 0x0A ], # Code for char t
[ 0x06, 0x08, 0x0E ], # Code for char u
[ 0x0E, 0x04, 0x02 ], # Code for char v
[ 0x0E, 0x0C, 0x06 ], # Code for char w
[ 0x0A, 0x04, 0x0A ], # Code for char x
[ 0x06, 0x0C, 0x06 ], # Code for char y
[ 0x02, 0x0E, 0x08 ], # Code for char z
[ 0x04, 0x06, 0x09 ], # Code for char {
[ 0x00, 0x0F, 0x00 ], # Code for char |
[ 0x09, 0x06, 0x04 ], # Code for char }
[ 0x04, 0x06, 0x02 ], # Code for char ~
[ 0x0E, 0x0A, 0x0E ] # Code for char
]

55
lib/mpr121.py Normal file
View File

@ -0,0 +1,55 @@
"""
Driver for the MPR121 capacitive touch sensor.
This chip is on the LCD32MKv1 skin.
Downloaded from: http://micropython.org/resources/examples/mpr121.py
"""
import pyb
# register definitions
TOUCH_STATUS = const(0x00)
ELE0_FILT_DATA = const(0x04)
ELE0_TOUCH_THRESH = const(0x41)
DEBOUNCE = const(0x5b)
ELEC_CONFIG = const(0x5e)
class MPR121:
def __init__(self, i2c):
self.i2c = i2c
self.addr = 90 # I2C address of the MPR121
# enable ELE0 - ELE3
self.enable_elec(4)
def enable_elec(self, n):
"""Enable the first n electrodes."""
self.i2c.mem_write(n & 0xf, self.addr, ELEC_CONFIG)
def threshold(self, elec, touch, release):
"""
Set touch/release threshold for an electrode.
Eg threshold(0, 12, 6).
"""
buf = bytearray((touch, release))
self.i2c.mem_write(buf, self.addr, ELE0_TOUCH_THRESH + 2 * elec)
def debounce(self, touch, release):
"""
Set touch/release debounce count for all electrodes.
Eg debounce(3, 3).
"""
self.i2c.mem_write((touch & 7) | (release & 7) << 4, self.addr, DEBOUNCE)
def touch_status(self, elec=None):
"""Get the touch status of an electrode (or all electrodes)."""
status = self.i2c.mem_read(2, self.addr, TOUCH_STATUS)
status = status[0] | status[1] << 8
if elec is None:
return status
else:
return status & (1 << elec) != 0
def elec_voltage(self, elec):
"""Get the voltage on an electrode."""
data = self.i2c.mem_read(2, self.addr, ELE0_FILT_DATA + 2 * elec)
return data[0] | data[1] << 8

82
main.py Normal file
View File

@ -0,0 +1,82 @@
# main.py -- put your code here!
import fontlcd
import mpr121
LED_RED = 0
LED_GREEN = 1
LED_YELLOW = 2
LED_BLUE = 3
BTN_Y = 0
BTN_X = 1
BTN_B = 2
BTN_A = 3
leds = [pyb.LED(i) for i in range(1, 5)]
for l in leds:
l.off()
lcd = fontlcd.FontLCD('X')
lcd.light(True)
lcd.loadFont('fourpx')
#lcd.write('Hello Master!\n')
m = mpr121.MPR121(pyb.I2C(1, pyb.I2C.MASTER))
def blob(x, y, w, h, fill):
for i in range(w):
for j in range(h):
if pyb.rng() & 0xff < fill:
lcd.pixel(x+i, y+j, 1)
btn_down = [False]*4
try:
while True:
t = m.touch_status()
# lcd.write("%4.2f -- %s\n" % (float(m.elec_voltage(3))/100, t))
# lcd.fill(0)
# for y in range(32):
# lcd.pixel(64, y, 1)
# for x in range(128):
# lcd.pixel(x, 16, 1)
# Button "Y"
if t & (2**BTN_Y):
if not btn_down[BTN_Y]:
leds[LED_RED].toggle()
lcd.write("You pressed Y!\n")
# blob(90, 20, 10, 10, 316 - m.elec_voltage(BTN_Y))
btn_down[BTN_Y] = True
else:
btn_down[BTN_Y] = False
# Button "X"
if t & (2**BTN_X):
if not btn_down[BTN_X]:
leds[LED_YELLOW].toggle()
lcd.write("You pressed X!\n")
# blob(30, 20, 10, 10, 316 - m.elec_voltage(BTN_X))
btn_down[BTN_X] = True
else:
btn_down[BTN_X] = False
# Button "B"
if t & (2**BTN_B):
if not btn_down[BTN_B]:
leds[LED_GREEN].toggle()
lcd.write("You pressed B!\n")
# blob(90, 5, 10, 10, 316 - m.elec_voltage(BTN_B))
btn_down[BTN_B] = True
else:
btn_down[BTN_B] = False
# Button "A"
# if t & 8:
# blob(30, 5, 10, 10, 316 - m.elec_voltage(BTN_A))
# lcd.show()
leds[LED_BLUE].intensity(345 - m.elec_voltage(BTN_A))
pyb.delay(20)
finally:
for l in leds:
l.off()