Skip to content

Commit 538f12c

Browse files
committed
Removing wiringpi Python lib dependency
1 parent 34e1885 commit 538f12c

File tree

6 files changed

+144
-118
lines changed

6 files changed

+144
-118
lines changed

install-deps.sh

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env bash
22

3+
# We need to be in the gpio group (but this won't take effect until we log out and back in)
4+
sudo usermod -a -G gpio $USER
5+
36
# Installs the system-wide dependencies for the project
47
sudo apt install python3-dev
58

6-
# TODO: wiringPi
9+
# TODO: wiringPi C library

lego_lcd/lcd.pyx

+104-98
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
#cython: language_level=3
2-
# requires: Cython, wiringpi
32

43
from cpython.bytes cimport PyBytes_FromStringAndSize
4+
cimport wiringpi as wp
5+
6+
7+
# Wiring-PI Wrapper Functions
8+
# The official Wiring-PI python library is abandoned and mixing it with a separate wiring pi library
9+
# causes issues.
10+
INPUT = wp.INPUT
11+
OUTPUT = wp.OUTPUT
12+
PWM_OUTPUT = wp.PWM_OUTPUT
13+
def wiringPiSetup(): return wp.wiringPiSetup()
14+
def wiringPiSetupGpio(): return wp.wiringPiSetupGpio()
15+
def wiringPiSetupPhys(): return wp.wiringPiSetupPhys()
16+
def wiringPiSetupSys(): return wp.wiringPiSetupSys()
17+
def pinMode(int pin, int mode): wp.pinMode(pin, mode)
18+
def digitalWrite(int pin, int value): wp.digitalWrite(pin, value)
19+
def pwmWrite(int pin, int value): wp.pwmWrite(pin, value)
20+
def digitalRead(int pin): return wp.digitalWrite(pin)
21+
def millis(): return wp.millis()
22+
def micros(): return wp.micros()
23+
def delay(unsigned int howLong): wp.delay(howLong)
24+
def delayMicroseconds(unsigned int howLong): wp.delayMicroseconds(howLong)
525

6-
cdef extern from "wiringPi.h":
7-
cdef enum:
8-
INPUT = 0
9-
OUTPUT = 1
10-
PWM_OUTPUT = 2
11-
void pinMode(int pin, int mode) nogil
12-
void digitalWrite(int pin, int value) nogil
13-
void pwmWrite(int pin, int value) nogil
14-
int digitalRead(int pin) nogil
15-
16-
unsigned int millis() nogil
17-
unsigned int micros() nogil
18-
void delay(unsigned int howLong) nogil
19-
void delayMicroseconds(unsigned int howLong) nogil
2026

2127
# Simple utility that should be in C code to be accurate and uses the above Wiring-PI definitions
2228
def beep(int pin, double freq=1000, double dur=0.1):
@@ -27,13 +33,13 @@ def beep(int pin, double freq=1000, double dur=0.1):
2733
"""
2834
cdef unsigned int delay, niter, i
2935
with nogil:
30-
pinMode(pin, OUTPUT)
36+
wp.pinMode(pin, OUTPUT)
3137
delay = <unsigned int>(1000000 // (2 * freq)) # Hz -> microseconds (halfed)
3238
niter = <unsigned int>(2*dur*freq + 0.5)
3339
for i in xrange(niter):
34-
digitalWrite(pin, i & 1)
35-
delayMicroseconds(delay)
36-
digitalWrite(pin, 0)
40+
wp.digitalWrite(pin, i & 1)
41+
wp.delayMicroseconds(delay)
42+
wp.digitalWrite(pin, 0)
3743

3844
cdef int[4] LCD_row_offs = [ 0x00, 0x40, 0x14, 0x54 ]
3945

@@ -66,25 +72,25 @@ cdef class LCD:
6672

6773
# We don't need the GIL from here to the end and there is a lot of waiting
6874
# Function Set Command - 001(DL)NF00
69-
cdef int por = 40 - millis()
75+
cdef int por = 40 - wp.millis()
7076
with nogil:
7177

7278
# All pins start as outputs and low
73-
digitalWrite(EN, 0); pinMode(EN, OUTPUT)
74-
digitalWrite(RS, 0); pinMode(RS, OUTPUT)
75-
pinMode(RW, OUTPUT)
79+
wp.digitalWrite(EN, 0); wp.pinMode(EN, wp.OUTPUT)
80+
wp.digitalWrite(RS, 0); wp.pinMode(RS, wp.OUTPUT)
81+
wp.pinMode(RW, wp.OUTPUT)
7682

7783
if bits == 4:
7884
self._read = self.read4; self._read_data = self.readData4
7985
self._write = self.write4; self._write_data = self.writeData4
8086

81-
# Need to wait 40 ms since the LCD recieved power
87+
# Need to wait 40 ms since the LCD received power
8288
self.writing4()
8389
self.set4(0)
84-
if por > 0: delay(por)
85-
self.set4(0x3); self.clock(); delayMicroseconds(4100)
86-
self.set4(0x3); self.clock(); delayMicroseconds(100)
87-
self.set4(0x3); self.clock(); delayMicroseconds(100)
90+
if por > 0: wp.delay(por)
91+
self.set4(0x3); self.clock(); wp.delayMicroseconds(4100)
92+
self.set4(0x3); self.clock(); wp.delayMicroseconds(100)
93+
self.set4(0x3); self.clock(); wp.delayMicroseconds(100)
8894
self.set4(0x2); self.clock()
8995

9096
# Set default state to reading and send "Function Set Command"
@@ -105,9 +111,9 @@ cdef class LCD:
105111
# Need to wait 40 ms since the LCD recieved power
106112
self.writing8()
107113
self.set8(0)
108-
if por > 0: delay(por)
109-
self.set8(0x30); self.clock(); delayMicroseconds(4100)
110-
self.set8(0x30); self.clock(); delayMicroseconds(100)
114+
if por > 0: wp.delay(por)
115+
self.set8(0x30); self.clock(); wp.delayMicroseconds(4100)
116+
self.set8(0x30); self.clock(); wp.delayMicroseconds(100)
111117
self.set8(0x30); self.clock()
112118

113119
# Set default state to reading and send "Function Set Command"
@@ -134,68 +140,68 @@ cdef class LCD:
134140

135141
cdef inline void clock(self) noexcept nogil:
136142
"""Clocks a command in (EN pin high then low)"""
137-
digitalWrite(self.EN, 1); delayMicroseconds(1); digitalWrite(self.EN, 0)
143+
wp.digitalWrite(self.EN, 1); wp.delayMicroseconds(1); wp.digitalWrite(self.EN, 0)
138144
cdef inline void set8(self, unsigned char x) noexcept nogil:
139145
"""Sets 8 bits to the DB pins"""
140-
digitalWrite(self.DB[7], x&0x80)
141-
digitalWrite(self.DB[6], x&0x40)
142-
digitalWrite(self.DB[5], x&0x20)
143-
digitalWrite(self.DB[4], x&0x10)
144-
digitalWrite(self.DB[3], x&0x08)
145-
digitalWrite(self.DB[2], x&0x04)
146-
digitalWrite(self.DB[1], x&0x02)
147-
digitalWrite(self.DB[0], x&0x01)
146+
wp.digitalWrite(self.DB[7], x&0x80)
147+
wp.digitalWrite(self.DB[6], x&0x40)
148+
wp.digitalWrite(self.DB[5], x&0x20)
149+
wp.digitalWrite(self.DB[4], x&0x10)
150+
wp.digitalWrite(self.DB[3], x&0x08)
151+
wp.digitalWrite(self.DB[2], x&0x04)
152+
wp.digitalWrite(self.DB[1], x&0x02)
153+
wp.digitalWrite(self.DB[0], x&0x01)
148154
cdef inline void set4(self, unsigned char x) noexcept nogil:
149155
"""Sets 4 bits to the DB pins"""
150-
digitalWrite(self.DB[3], x&0x08)
151-
digitalWrite(self.DB[2], x&0x04)
152-
digitalWrite(self.DB[1], x&0x02)
153-
digitalWrite(self.DB[0], x&0x01)
156+
wp.digitalWrite(self.DB[3], x&0x08)
157+
wp.digitalWrite(self.DB[2], x&0x04)
158+
wp.digitalWrite(self.DB[1], x&0x02)
159+
wp.digitalWrite(self.DB[0], x&0x01)
154160

155161

156162
cdef inline void writing8(self) noexcept nogil:
157163
"""Set the interface into writing mode (RW=0 and all DBs as outputs) (8-bit interface)"""
158-
digitalWrite(self.RW, 0)
159-
pinMode(self.DB[0], OUTPUT); pinMode(self.DB[1], OUTPUT)
160-
pinMode(self.DB[2], OUTPUT); pinMode(self.DB[3], OUTPUT)
161-
pinMode(self.DB[4], OUTPUT); pinMode(self.DB[5], OUTPUT)
162-
pinMode(self.DB[6], OUTPUT); pinMode(self.DB[7], OUTPUT)
164+
wp.digitalWrite(self.RW, 0)
165+
wp.pinMode(self.DB[0], wp.OUTPUT); wp.pinMode(self.DB[1], wp.OUTPUT)
166+
wp.pinMode(self.DB[2], wp.OUTPUT); wp.pinMode(self.DB[3], wp.OUTPUT)
167+
wp.pinMode(self.DB[4], wp.OUTPUT); wp.pinMode(self.DB[5], wp.OUTPUT)
168+
wp.pinMode(self.DB[6], wp.OUTPUT); wp.pinMode(self.DB[7], wp.OUTPUT)
163169
cdef inline void writing4(self) noexcept nogil:
164170
"""Set the interface into writing mode (RW=0 and all DBs as outputs) (4-bit interface)"""
165-
digitalWrite(self.RW, 0)
166-
pinMode(self.DB[0], OUTPUT); pinMode(self.DB[1], OUTPUT)
167-
pinMode(self.DB[2], OUTPUT); pinMode(self.DB[3], OUTPUT)
171+
wp.digitalWrite(self.RW, 0)
172+
wp.pinMode(self.DB[0], wp.OUTPUT); wp.pinMode(self.DB[1], wp.OUTPUT)
173+
wp.pinMode(self.DB[2], wp.OUTPUT); wp.pinMode(self.DB[3], wp.OUTPUT)
168174

169175
cdef inline void reading8(self) noexcept nogil:
170176
"""Set the interface into reading mode (RW=1 and all DBs as inputs) (8-bit interface)"""
171-
digitalWrite(self.RW, 1)
172-
pinMode(self.DB[0], INPUT); pinMode(self.DB[1], INPUT)
173-
pinMode(self.DB[2], INPUT); pinMode(self.DB[3], INPUT)
174-
pinMode(self.DB[4], INPUT); pinMode(self.DB[5], INPUT)
175-
pinMode(self.DB[6], INPUT); pinMode(self.DB[7], INPUT)
177+
wp.digitalWrite(self.RW, 1)
178+
wp.pinMode(self.DB[0], wp.INPUT); wp.pinMode(self.DB[1], wp.INPUT)
179+
wp.pinMode(self.DB[2], wp.INPUT); wp.pinMode(self.DB[3], wp.INPUT)
180+
wp.pinMode(self.DB[4], wp.INPUT); wp.pinMode(self.DB[5], wp.INPUT)
181+
wp.pinMode(self.DB[6], wp.INPUT); wp.pinMode(self.DB[7], wp.INPUT)
176182
cdef inline void reading4(self) noexcept nogil:
177183
"""Set the interface into reading mode (RW=1 and all DBs as inputs) (4-bit interface)"""
178-
digitalWrite(self.RW, 1)
179-
pinMode(self.DB[0], INPUT); pinMode(self.DB[1], INPUT)
180-
pinMode(self.DB[2], INPUT); pinMode(self.DB[3], INPUT)
184+
wp.digitalWrite(self.RW, 1)
185+
wp.pinMode(self.DB[0], wp.INPUT); wp.pinMode(self.DB[1], wp.INPUT)
186+
wp.pinMode(self.DB[2], wp.INPUT); wp.pinMode(self.DB[3], wp.INPUT)
181187

182188
cdef inline bint busy8(self) noexcept nogil:
183189
"""Checks if the LCD is busy or not (8-bit interface)"""
184190
# RS, RW = 0, 1
185-
digitalWrite(self.EN, 1)
186-
delayMicroseconds(1)
187-
cdef bint busy = digitalRead(self.DB[7])
188-
digitalWrite(self.EN, 0)
191+
wp.digitalWrite(self.EN, 1)
192+
wp.delayMicroseconds(1)
193+
cdef bint busy = wp.digitalRead(self.DB[7])
194+
wp.digitalWrite(self.EN, 0)
189195
return busy
190196
cdef inline bint busy4(self) noexcept nogil:
191197
"""Checks if the LCD is busy or not (4-bit interface)"""
192198
# RS, RW = 0, 1
193-
digitalWrite(self.EN, 1)
194-
delayMicroseconds(1)
195-
cdef bint busy = digitalRead(self.DB[3])
196-
digitalWrite(self.EN, 0)
197-
digitalWrite(self.EN, 1)
198-
digitalWrite(self.EN, 0)
199+
wp.digitalWrite(self.EN, 1)
200+
wp.delayMicroseconds(1)
201+
cdef bint busy = wp.digitalRead(self.DB[3])
202+
wp.digitalWrite(self.EN, 0)
203+
wp.digitalWrite(self.EN, 1)
204+
wp.digitalWrite(self.EN, 0)
199205
return busy
200206
@property
201207
def busy(self): return self.busy8() if self.bits == 8 else self.busy4()
@@ -206,42 +212,42 @@ cdef class LCD:
206212
cdef int EN = self.EN, DB = self.DB[7]
207213
cdef bint busy = True
208214
while busy:
209-
delayMicroseconds(1); digitalWrite(EN, 1)
210-
delayMicroseconds(1); busy = digitalRead(DB); digitalWrite(EN, 0)
215+
wp.delayMicroseconds(1); wp.digitalWrite(EN, 1)
216+
wp.delayMicroseconds(1); busy = wp.digitalRead(DB); wp.digitalWrite(EN, 0)
211217
cdef inline void wait4(self) noexcept nogil:
212218
"""Waits for the LCD to not be busy (4-bit interface)"""
213219
# RS, RW = 0, 1
214220
cdef int EN = self.EN, DB = self.DB[3]
215221
cdef bint busy = True
216222
while busy:
217-
delayMicroseconds(1); digitalWrite(EN, 1)
218-
delayMicroseconds(1); busy = digitalRead(DB); digitalWrite(EN, 0)
219-
delayMicroseconds(1); digitalWrite(EN, 1)
220-
delayMicroseconds(1); digitalWrite(EN, 0)
223+
wp.delayMicroseconds(1); wp.digitalWrite(EN, 1)
224+
wp.delayMicroseconds(1); busy = wp.digitalRead(DB); wp.digitalWrite(EN, 0)
225+
wp.delayMicroseconds(1); wp.digitalWrite(EN, 1)
226+
wp.delayMicroseconds(1); wp.digitalWrite(EN, 0)
221227

222228
cdef inline int __read8(self) noexcept nogil:
223229
"""Read a single byte from the LCD, which must not be busy and RS set properly (8-bit interface)"""
224230
# RW = 1
225-
delayMicroseconds(1); digitalWrite(self.EN, 1); delayMicroseconds(1)
231+
wp.delayMicroseconds(1); wp.digitalWrite(self.EN, 1); wp.delayMicroseconds(1)
226232
cdef int out = (
227-
digitalRead(self.DB[7]) << 7 | digitalRead(self.DB[6]) << 6 |
228-
digitalRead(self.DB[5]) << 5 | digitalRead(self.DB[4]) << 4 |
229-
digitalRead(self.DB[3]) << 3 | digitalRead(self.DB[2]) << 2 |
230-
digitalRead(self.DB[1]) << 1 | digitalRead(self.DB[0]) << 0)
231-
digitalWrite(self.EN, 0)
233+
wp.digitalRead(self.DB[7]) << 7 | wp.digitalRead(self.DB[6]) << 6 |
234+
wp.digitalRead(self.DB[5]) << 5 | wp.digitalRead(self.DB[4]) << 4 |
235+
wp.digitalRead(self.DB[3]) << 3 | wp.digitalRead(self.DB[2]) << 2 |
236+
wp.digitalRead(self.DB[1]) << 1 | wp.digitalRead(self.DB[0]) << 0)
237+
wp.digitalWrite(self.EN, 0)
232238
return out
233239
cdef inline int __read4(self) noexcept nogil:
234240
"""Read a single byte from the LCD, which must not be busy and RS set properly (4-bit interface)"""
235241
# RW = 1
236-
delayMicroseconds(1); digitalWrite(self.EN, 1); delayMicroseconds(1)
242+
wp.delayMicroseconds(1); wp.digitalWrite(self.EN, 1); wp.delayMicroseconds(1)
237243
cdef int out = (
238-
digitalRead(self.DB[3]) << 7 | digitalRead(self.DB[2]) << 6 |
239-
digitalRead(self.DB[1]) << 5 | digitalRead(self.DB[0]) << 4)
240-
digitalWrite(self.EN, 0)
241-
delayMicroseconds(1); digitalWrite(self.EN, 1); delayMicroseconds(1)
242-
out |= (digitalRead(self.DB[3]) << 3 | digitalRead(self.DB[2]) << 2 |
243-
digitalRead(self.DB[1]) << 1 | digitalRead(self.DB[0]) << 0)
244-
digitalWrite(self.EN, 0)
244+
wp.digitalRead(self.DB[3]) << 7 | wp.digitalRead(self.DB[2]) << 6 |
245+
wp.digitalRead(self.DB[1]) << 5 | wp.digitalRead(self.DB[0]) << 4)
246+
wp.digitalWrite(self.EN, 0)
247+
wp.delayMicroseconds(1); wp.digitalWrite(self.EN, 1); wp.delayMicroseconds(1)
248+
out |= (digitalRead(self.DB[3]) << 3 | wp.digitalRead(self.DB[2]) << 2 |
249+
wp.digitalRead(self.DB[1]) << 1 | wp.digitalRead(self.DB[0]) << 0)
250+
wp.digitalWrite(self.EN, 0)
245251
return out
246252
cdef int read8(self) noexcept nogil:
247253
"""Read a single byte from the LCD, the character address (8-bit interface)"""
@@ -257,17 +263,17 @@ cdef class LCD:
257263
"""Read a single byte from the LCD, the data (8-bit interface)"""
258264
# RW = 1
259265
self.wait8()
260-
digitalWrite(self.RS, 1)
266+
wp.digitalWrite(self.RS, 1)
261267
cdef int x = self.__read8()
262-
digitalWrite(self.RS, 0)
268+
wp.digitalWrite(self.RS, 0)
263269
return x
264270
cdef int readData4(self) noexcept nogil:
265271
"""Read a single byte from the LCD, the data (4-bit interface)"""
266272
# RW = 1
267273
self.wait4()
268-
digitalWrite(self.RS, 1)
274+
wp.digitalWrite(self.RS, 1)
269275
cdef int x = self.__read4()
270-
digitalWrite(self.RS, 0)
276+
wp.digitalWrite(self.RS, 0)
271277
return x
272278

273279
cdef inline void __write8(self, unsigned char x) noexcept nogil:
@@ -301,16 +307,16 @@ cdef class LCD:
301307
"""Writes a single byte to the LCD either as data (8-bit interface)"""
302308
#assert(0 <= x <= 0xFF)
303309
self.wait8()
304-
digitalWrite(self.RS, 1)
310+
wp.digitalWrite(self.RS, 1)
305311
self.__write8(x)
306-
digitalWrite(self.RS, 0)
312+
wp.digitalWrite(self.RS, 0)
307313
cdef void writeData4(self, unsigned char x) noexcept nogil:
308314
"""Writes a single byte to the LCD either as data (4-bit interface)"""
309315
#assert(0 <= x <= 0xFF)
310316
self.wait4()
311-
digitalWrite(self.RS, 1)
317+
wp.digitalWrite(self.RS, 1)
312318
self.__write4(x)
313-
digitalWrite(self.RS, 0)
319+
wp.digitalWrite(self.RS, 0)
314320

315321
########## COMMANDS ##########
316322
def clear(self):

lego_lcd/lcd_helper.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
Helpers for useing the LCD library. In general these are all specific to my setup and devices.
44
"""
55

6-
import RPi.GPIO, wiringpi
7-
# requires: <lcd>
6+
import RPi.GPIO, lcd
87

98
__all__ = ["lcd_setup", "set_contrast", "set_backlight", "beep", "as_bytes"]
109

@@ -127,27 +126,25 @@
127126

128127
def lcd_setup(ct=None, bl=None):
129128
"""Setup the LCD and other GPIO items. Returns the LCD object."""
130-
from .lcd import LCD
131-
wiringpi.wiringPiSetupGpio()
132-
RPi.GPIO.setmode(RPi.GPIO.BCM)
133-
wiringpi.pinMode(CT_PIN, wiringpi.PWM_OUTPUT)
129+
lcd.wiringPiSetupGpio()
130+
RPi.GPIO.setmode(RPi.GPIO.BCM) # TODO: remove
131+
lcd.pinMode(CT_PIN, lcd.PWM_OUTPUT)
134132
if ct is not None: set_contrast(ct)
135-
wiringpi.pinMode(BL_PIN, wiringpi.PWM_OUTPUT)
133+
lcd.pinMode(BL_PIN, lcd.PWM_OUTPUT)
136134
if bl is not None: set_backlight(bl)
137-
return LCD(RS_PIN, RW_PIN, EN_PIN, DB_PINS, LCD_DIM)
135+
return lcd.LCD(RS_PIN, RW_PIN, EN_PIN, DB_PINS, LCD_DIM)
138136

139137
def set_contrast(ct):
140138
"""Sets the LCD contrast amount, ct is a value from 0.0 to 1.0"""
141-
wiringpi.pwmWrite(CT_PIN, int(max(min(ct, 1.0), 0.0)*512))
139+
lcd.pwmWrite(CT_PIN, int(max(min(ct, 1.0), 0.0)*512))
142140

143141
def set_backlight(bl):
144142
"""Sets the LCD backlight amount, bl is a value from 0.0 to 1.0"""
145-
wiringpi.pwmWrite(BL_PIN, int(max(min(bl, 1.0), 0.0)*1024))
143+
lcd.pwmWrite(BL_PIN, int(max(min(bl, 1.0), 0.0)*1024))
146144

147145
def beep(freq=1000, dur=0.1):
148146
"""Emit a beep"""
149-
from .lcd import beep
150-
beep(BEEP_PIN, freq, dur)
147+
lcd.beep(BEEP_PIN, freq, dur)
151148

152149
def as_bytes(s, trans=None):
153150
"""

0 commit comments

Comments
 (0)