Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
testbed-software
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Robert Hartung
testbed-software
Commits
cca3c5c6
Commit
cca3c5c6
authored
6 years ago
by
Torben Petersen
Browse files
Options
Downloads
Patches
Plain Diff
Adds Module for OLED Display
parent
f1d70428
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
modules/oleddisplay.py
+202
-0
202 additions, 0 deletions
modules/oleddisplay.py
with
202 additions
and
0 deletions
modules/oleddisplay.py
0 → 100644
+
202
−
0
View file @
cca3c5c6
from
.
import
Module
import
time
import
Adafruit_GPIO.SPI
as
SPI
import
Adafruit_GPIO.GPIO
as
GPIO
import
Adafruit_SSD1306
import
RPi.GPIO
from
PIL
import
Image
from
PIL
import
ImageDraw
from
PIL
import
ImageFont
import
sys
import
socket
gpio
=
GPIO
.
RPiGPIOAdapter
(
RPi
.
GPIO
,
RPi
.
GPIO
.
BOARD
)
class
OLEDDisplay
(
Module
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
OLEDDisplay
,
self
).
__init__
(
*
args
,
**
kwargs
)
setup_display
()
def
on_message
(
self
,
client
,
userdata
,
msg
):
#react to recieved messages
logger
.
debug
(
"
on_message {} {}
"
.
format
(
msg
.
topic
,
msg
.
payload
))
def
on_connect
(
self
,
client
,
userdata
,
flags
,
rc
):
#subscribe to topics and do other stuff
def
run
(
self
):
self
.
running
=
True
while
self
.
running
:
#do stuff. What stuff?
time
.
sleep
(
50
)
def
setup_display
(
self
):
# Create display
self
.
display
=
LCTCDisplay
(
gpio
)
self
.
display
.
clear
()
# Create menu entries
# TODO(rh): If no network is attached, this fails -> catch error here
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
s
.
connect
((
"
8.8.8.8
"
,
80
))
myip
=
s
.
getsockname
()[
0
]
s
.
close
()
# ENDTODO(rh)
mainmenu
=
Menu
()
controlentry
=
mainmenu
.
add
(
"
Control
"
)
controlmenu
=
controlentry
.
submenu
()
networkentry
=
mainmenu
.
add
(
"
Network
"
)
networkmenu
=
networkentry
.
submenu
()
networkmenu
.
add
(
"
IP:
"
+
str
(
myip
)
)
networkmenu
.
add
(
"
Hostname:
"
+
str
(
socket
.
gethostname
()
)
)
# button control
buttons
=
LCTCButtonControl
(
gpio
,
self
.
display
,
mainmenu
)
# TODO(rh): Update thread for Menu required...
class
LCTCDisplay
:
OLED_RST
=
26
OLED_DC
=
22
SPI_PORT
=
0
SPI_DEVICE
=
0
LINE_OFFSET
=
8
def
__init__
(
self
,
gpio
):
self
.
spi
=
SPI
.
SpiDev
(
self
.
SPI_PORT
,
self
.
SPI_DEVICE
,
max_speed_hz
=
8000000
)
# initialize display object
self
.
disp
=
Adafruit_SSD1306
.
SSD1306_128_64
(
gpio
=
gpio
,
rst
=
self
.
OLED_RST
,
dc
=
self
.
OLED_DC
,
spi
=
self
.
spi
)
self
.
disp
.
begin
()
# Clear display.
self
.
disp
.
clear
()
self
.
disp
.
display
()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
self
.
width
=
self
.
disp
.
width
self
.
height
=
self
.
disp
.
height
self
.
image_buffer
=
Image
.
new
(
'
1
'
,
(
self
.
width
,
self
.
height
))
self
.
font
=
ImageFont
.
load_default
()
# Get drawing object to draw on image.
self
.
draw
=
ImageDraw
.
Draw
(
self
.
image_buffer
)
def
clear
(
self
):
# Draw a black filled box to clear the image.
self
.
draw
.
rectangle
((
0
,
0
,
self
.
width
,
self
.
height
),
outline
=
0
,
fill
=
0
)
def
render
(
self
,
menu
):
menu
.
render
(
self
.
draw
,
self
.
font
,
self
.
LINE_OFFSET
,
self
.
width
,
self
.
height
)
self
.
disp
.
image
(
self
.
image_buffer
)
self
.
disp
.
display
()
class
LCTCButtonControl
:
BUTTONS
=
{
12
:
'
left
'
,
16
:
'
right
'
,
11
:
'
down
'
,
13
:
'
up
'
}
def
__init__
(
self
,
gpio
,
display
,
menu
):
self
.
state
=
dict
()
self
.
display
=
display
# Set default menu and render it
self
.
menu
=
menu
for
button
in
self
.
BUTTONS
:
gpio
.
setup
(
button
,
GPIO
.
IN
)
self
.
state
[
button
]
=
gpio
.
is_low
(
button
)
gpio
.
add_event_detect
(
button
,
GPIO
.
BOTH
,
callback
=
self
.
button_changed
)
self
.
display
.
render
(
self
.
menu
)
def
button_changed
(
self
,
button
):
state
=
not
self
.
state
[
button
]
self
.
state
[
button
]
=
state
dir
=
self
.
BUTTONS
[
button
]
if
state
:
if
dir
==
'
down
'
:
if
self
.
menu
.
active
is
None
:
self
.
menu
.
active
=
0
elif
self
.
menu
.
active
<
(
len
(
self
.
menu
.
entries
)
-
1
):
self
.
menu
.
active
+=
1
elif
dir
==
'
up
'
:
if
self
.
menu
.
active
is
not
None
and
self
.
menu
.
active
>
0
:
self
.
menu
.
active
-=
1
elif
dir
==
'
right
'
:
# Check if active menu entry exists
if
self
.
menu
.
active
is
not
None
:
# get entry from list
entry
=
self
.
menu
.
entries
[
self
.
menu
.
active
]
# if the MenuEntry has a child
if
entry
.
child
is
not
None
:
# display child
self
.
menu
=
entry
.
child
else
:
logger
.
log
(
"
Action on {}
"
.
format
(
entry
.
label
)
)
elif
dir
==
'
left
'
:
if
self
.
menu
.
parent
is
not
None
:
self
.
menu
=
self
.
menu
.
parent
self
.
display
.
render
(
self
.
menu
)
class
Menu
:
def
__init__
(
self
,
parent
=
None
):
self
.
entries
=
list
()
self
.
active
=
None
self
.
parent
=
parent
def
add
(
self
,
label
):
entry
=
MenuEntry
(
label
,
self
)
self
.
entries
.
append
(
entry
)
return
entry
def
render
(
self
,
draw
,
font
,
line_height
,
width
,
height
):
INDICATOR_OFFSET
=
120
draw
.
rectangle
((
0
,
0
,
width
,
height
),
outline
=
0
,
fill
=
0
)
x
=
2
y
=
-
2
+
2
*
line_height
for
i
,
entry
in
enumerate
(
self
.
entries
):
fill
=
255
if
self
.
active
is
not
None
and
i
==
self
.
active
:
draw
.
rectangle
((
x
,
y
+
1
,
width
,
y
+
line_height
+
2
),
outline
=
0
,
fill
=
255
)
fill
=
0
draw
.
text
((
x
,
y
),
entry
.
label
,
font
=
font
,
fill
=
fill
)
# if submenu available -> draw small rectangle
if
entry
.
child
is
not
None
:
draw
.
line
([(
x
+
INDICATOR_OFFSET
,
y
+
4
),
(
x
+
INDICATOR_OFFSET
+
2
,
y
+
4
+
2
),
(
x
+
INDICATOR_OFFSET
,
y
+
8
),
(
x
+
INDICATOR_OFFSET
,
y
+
4
)],
fill
=
fill
,
width
=
1
)
y
+=
line_height
class
MenuEntry
:
def
__init__
(
self
,
label
,
parent
):
self
.
label
=
label
self
.
parent
=
parent
self
.
child
=
None
def
submenu
(
self
):
self
.
child
=
Menu
(
self
.
parent
)
return
self
.
child
if
__name__
==
'
__main__
'
:
# Raspberry Pi pin configuration:
gpio
=
GPIO
.
RPiGPIOAdapter
(
RPi
.
GPIO
,
RPi
.
GPIO
.
BOARD
)
# Create display
display
=
LCTCDisplay
(
gpio
)
display
.
clear
()
# Create menu entries
s
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_DGRAM
)
s
.
connect
((
"
8.8.8.8
"
,
80
))
myip
=
s
.
getsockname
()[
0
]
s
.
close
()
mainmenu
=
Menu
()
controlentry
=
mainmenu
.
add
(
"
Control
"
)
controlmenu
=
controlentry
.
submenu
()
networkentry
=
mainmenu
.
add
(
"
Network
"
)
networkmenu
=
networkentry
.
submenu
()
networkmenu
.
add
(
"
IP:
"
+
str
(
myip
)
)
networkmenu
.
add
(
"
Hostname:
"
+
str
(
socket
.
gethostname
()
)
)
# button control
buttons
=
LCTCButtonControl
(
gpio
,
display
,
mainmenu
)
while
True
:
time
.
sleep
(
100
)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment