Move from waveshare e-ink display to pimoroni's inkyphat
(run install_inkyphat_lib.sh to install dependencies)
This commit is contained in:
parent
ac55131ac5
commit
c65b4d3c44
@ -1,271 +0,0 @@
|
||||
##
|
||||
# @filename : epd2in13.py
|
||||
# @brief : Implements for e-paper library
|
||||
# @author : Yehui from Waveshare
|
||||
#
|
||||
# Copyright (C) Waveshare September 9 2017
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
import epdif
|
||||
from PIL import Image
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
# Display resolution
|
||||
EPD_WIDTH = 128
|
||||
EPD_HEIGHT = 250
|
||||
|
||||
# EPD2IN13 commands
|
||||
DRIVER_OUTPUT_CONTROL = 0x01
|
||||
BOOSTER_SOFT_START_CONTROL = 0x0C
|
||||
GATE_SCAN_START_POSITION = 0x0F
|
||||
DEEP_SLEEP_MODE = 0x10
|
||||
DATA_ENTRY_MODE_SETTING = 0x11
|
||||
SW_RESET = 0x12
|
||||
TEMPERATURE_SENSOR_CONTROL = 0x1A
|
||||
MASTER_ACTIVATION = 0x20
|
||||
DISPLAY_UPDATE_CONTROL_1 = 0x21
|
||||
DISPLAY_UPDATE_CONTROL_2 = 0x22
|
||||
WRITE_RAM = 0x24
|
||||
WRITE_VCOM_REGISTER = 0x2C
|
||||
WRITE_LUT_REGISTER = 0x32
|
||||
SET_DUMMY_LINE_PERIOD = 0x3A
|
||||
SET_GATE_TIME = 0x3B
|
||||
BORDER_WAVEFORM_CONTROL = 0x3C
|
||||
SET_RAM_X_ADDRESS_START_END_POSITION = 0x44
|
||||
SET_RAM_Y_ADDRESS_START_END_POSITION = 0x45
|
||||
SET_RAM_X_ADDRESS_COUNTER = 0x4E
|
||||
SET_RAM_Y_ADDRESS_COUNTER = 0x4F
|
||||
TERMINATE_FRAME_READ_WRITE = 0xFF
|
||||
|
||||
class EPD:
|
||||
def __init__(self):
|
||||
self.reset_pin = epdif.RST_PIN
|
||||
self.dc_pin = epdif.DC_PIN
|
||||
self.busy_pin = epdif.BUSY_PIN
|
||||
self.width = EPD_WIDTH
|
||||
self.height = EPD_HEIGHT
|
||||
self.lut = self.lut_full_update
|
||||
|
||||
lut_full_update = [
|
||||
0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
]
|
||||
|
||||
lut_partial_update = [
|
||||
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
]
|
||||
|
||||
def digital_write(self, pin, value):
|
||||
epdif.epd_digital_write(pin, value)
|
||||
|
||||
def digital_read(self, pin):
|
||||
return epdif.epd_digital_read(pin)
|
||||
|
||||
def delay_ms(self, delaytime):
|
||||
epdif.epd_delay_ms(delaytime)
|
||||
|
||||
def send_command(self, command):
|
||||
self.digital_write(self.dc_pin, GPIO.LOW)
|
||||
# the parameter type is list but not int
|
||||
# so use [command] instead of command
|
||||
epdif.spi_transfer([command])
|
||||
|
||||
def send_data(self, data):
|
||||
self.digital_write(self.dc_pin, GPIO.HIGH)
|
||||
# the parameter type is list but not int
|
||||
# so use [data] instead of data
|
||||
epdif.spi_transfer([data])
|
||||
|
||||
def init(self, lut):
|
||||
if (epdif.epd_init() != 0):
|
||||
return -1
|
||||
# EPD hardware init start
|
||||
self.lut = lut
|
||||
self.reset()
|
||||
self.send_command(DRIVER_OUTPUT_CONTROL)
|
||||
self.send_data((EPD_HEIGHT - 1) & 0xFF)
|
||||
self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF)
|
||||
self.send_data(0x00) # GD = 0 SM = 0 TB = 0
|
||||
self.send_command(BOOSTER_SOFT_START_CONTROL)
|
||||
self.send_data(0xD7)
|
||||
self.send_data(0xD6)
|
||||
self.send_data(0x9D)
|
||||
self.send_command(WRITE_VCOM_REGISTER)
|
||||
self.send_data(0xA8) # VCOM 7C
|
||||
self.send_command(SET_DUMMY_LINE_PERIOD)
|
||||
self.send_data(0x1A) # 4 dummy lines per gate
|
||||
self.send_command(SET_GATE_TIME)
|
||||
self.send_data(0x08) # 2us per line
|
||||
self.send_command(DATA_ENTRY_MODE_SETTING)
|
||||
self.send_data(0x03) # X increment Y increment
|
||||
self.set_lut(self.lut)
|
||||
# EPD hardware init end
|
||||
return 0
|
||||
|
||||
def wait_until_idle(self):
|
||||
while(self.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
|
||||
self.delay_ms(20)
|
||||
##
|
||||
# @brief: module reset.
|
||||
# often used to awaken the module in deep sleep,
|
||||
##
|
||||
def reset(self):
|
||||
self.digital_write(self.reset_pin, GPIO.LOW) # module reset
|
||||
self.delay_ms(200)
|
||||
self.digital_write(self.reset_pin, GPIO.HIGH)
|
||||
self.delay_ms(200)
|
||||
|
||||
##
|
||||
# @brief: set the look-up table register
|
||||
##
|
||||
def set_lut(self, lut):
|
||||
self.lut = lut
|
||||
self.send_command(WRITE_LUT_REGISTER)
|
||||
# the length of look-up table is 30 bytes
|
||||
for i in range(0, len(lut)):
|
||||
self.send_data(self.lut[i])
|
||||
|
||||
##
|
||||
# @brief: convert an image to a buffer
|
||||
##
|
||||
def get_frame_buffer(self, image):
|
||||
buf = [0x00] * (self.width * self.height / 8)
|
||||
# Set buffer to value of Python Imaging Library image.
|
||||
# Image must be in mode 1.
|
||||
image_monocolor = image.convert('1')
|
||||
imwidth, imheight = image_monocolor.size
|
||||
if imwidth != self.width or imheight != self.height:
|
||||
raise ValueError('Image must be same dimensions as display \
|
||||
({0}x{1}).' .format(self.width, self.height))
|
||||
|
||||
pixels = image_monocolor.load()
|
||||
for y in range(self.height):
|
||||
for x in range(self.width):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if pixels[x, y] != 0:
|
||||
buf[(x + y * self.width) / 8] |= 0x80 >> (x % 8)
|
||||
return buf
|
||||
|
||||
##
|
||||
# @brief: put an image to the frame memory.
|
||||
# this won't update the display.
|
||||
##
|
||||
def set_frame_memory(self, image, x, y):
|
||||
if (image == None or x < 0 or y < 0):
|
||||
return
|
||||
image_monocolor = image.convert('1')
|
||||
image_width, image_height = image_monocolor.size
|
||||
# x point must be the multiple of 8 or the last 3 bits will be ignored
|
||||
x = x & 0xF8
|
||||
image_width = image_width & 0xF8
|
||||
if (x + image_width >= self.width):
|
||||
x_end = self.width - 1
|
||||
else:
|
||||
x_end = x + image_width - 1
|
||||
if (y + image_height >= self.height):
|
||||
y_end = self.height - 1
|
||||
else:
|
||||
y_end = y + image_height - 1
|
||||
self.set_memory_area(x, y, x_end, y_end)
|
||||
# send the image data
|
||||
pixels = image_monocolor.load()
|
||||
byte_to_send = 0x00
|
||||
for j in range(y, y_end + 1):
|
||||
self.set_memory_pointer(x, j)
|
||||
self.send_command(WRITE_RAM)
|
||||
# 1 byte = 8 pixels, steps of i = 8
|
||||
for i in range(x, x_end + 1):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if pixels[i - x, j - y] != 0:
|
||||
byte_to_send |= 0x80 >> (i % 8)
|
||||
if (i % 8 == 7):
|
||||
self.send_data(byte_to_send)
|
||||
byte_to_send = 0x00
|
||||
|
||||
##
|
||||
# @brief: clear the frame memory with the specified color.
|
||||
# this won't update the display.
|
||||
##
|
||||
def clear_frame_memory(self, color):
|
||||
self.set_memory_area(0, 0, self.width - 1, self.height - 1)
|
||||
self.set_memory_pointer(0, 0)
|
||||
self.send_command(WRITE_RAM)
|
||||
# send the color data
|
||||
for i in range(0, int(self.width / 8 * self.height)):
|
||||
self.send_data(color)
|
||||
|
||||
##
|
||||
# @brief: update the display
|
||||
# there are 2 memory areas embedded in the e-paper display
|
||||
# but once this function is called,
|
||||
# the the next action of SetFrameMemory or ClearFrame will
|
||||
# set the other memory area.
|
||||
##
|
||||
def display_frame(self):
|
||||
self.send_command(DISPLAY_UPDATE_CONTROL_2)
|
||||
self.send_data(0xC4)
|
||||
self.send_command(MASTER_ACTIVATION)
|
||||
self.send_command(TERMINATE_FRAME_READ_WRITE)
|
||||
self.wait_until_idle()
|
||||
|
||||
##
|
||||
# @brief: specify the memory area for data R/W
|
||||
##
|
||||
def set_memory_area(self, x_start, y_start, x_end, y_end):
|
||||
self.send_command(SET_RAM_X_ADDRESS_START_END_POSITION)
|
||||
# x point must be the multiple of 8 or the last 3 bits will be ignored
|
||||
self.send_data((x_start >> 3) & 0xFF)
|
||||
self.send_data((x_end >> 3) & 0xFF)
|
||||
self.send_command(SET_RAM_Y_ADDRESS_START_END_POSITION)
|
||||
self.send_data(y_start & 0xFF)
|
||||
self.send_data((y_start >> 8) & 0xFF)
|
||||
self.send_data(y_end & 0xFF)
|
||||
self.send_data((y_end >> 8) & 0xFF)
|
||||
|
||||
##
|
||||
# @brief: specify the start point for data R/W
|
||||
##
|
||||
def set_memory_pointer(self, x, y):
|
||||
self.send_command(SET_RAM_X_ADDRESS_COUNTER)
|
||||
# x point must be the multiple of 8 or the last 3 bits will be ignored
|
||||
self.send_data((x >> 3) & 0xFF)
|
||||
self.send_command(SET_RAM_Y_ADDRESS_COUNTER)
|
||||
self.send_data(y & 0xFF)
|
||||
self.send_data((y >> 8) & 0xFF)
|
||||
self.wait_until_idle()
|
||||
|
||||
##
|
||||
# @brief: After this command is transmitted, the chip would enter the
|
||||
# deep-sleep mode to save power.
|
||||
# The deep sleep mode would return to standby by hardware reset.
|
||||
# You can use reset() to awaken or init() to initialize
|
||||
##
|
||||
def sleep(self):
|
||||
self.send_command(DEEP_SLEEP_MODE)
|
||||
self.wait_until_idle()
|
||||
|
||||
### END OF FILE ###
|
||||
|
@ -1,63 +0,0 @@
|
||||
##
|
||||
# @filename : epdif.py
|
||||
# @brief : EPD hardware interface implements (GPIO, SPI)
|
||||
# @author : Yehui from Waveshare
|
||||
#
|
||||
# Copyright (C) Waveshare July 10 2017
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
#
|
||||
|
||||
import spidev
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
# Pin definition
|
||||
RST_PIN = 17
|
||||
DC_PIN = 25
|
||||
CS_PIN = 8
|
||||
BUSY_PIN = 24
|
||||
|
||||
# SPI device, bus = 0, device = 0
|
||||
SPI = spidev.SpiDev(0, 0)
|
||||
|
||||
def epd_digital_write(pin, value):
|
||||
GPIO.output(pin, value)
|
||||
|
||||
def epd_digital_read(pin):
|
||||
return GPIO.input(BUSY_PIN)
|
||||
|
||||
def epd_delay_ms(delaytime):
|
||||
time.sleep(delaytime / 1000.0)
|
||||
|
||||
def spi_transfer(data):
|
||||
SPI.writebytes(data)
|
||||
|
||||
def epd_init():
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setup(RST_PIN, GPIO.OUT)
|
||||
GPIO.setup(DC_PIN, GPIO.OUT)
|
||||
GPIO.setup(CS_PIN, GPIO.OUT)
|
||||
GPIO.setup(BUSY_PIN, GPIO.IN)
|
||||
SPI.max_speed_hz = 2000000
|
||||
SPI.mode = 0b00
|
||||
return 0;
|
||||
|
||||
### END OF FILE ###
|
1118
raspberry/python/install_inkyphat_lib.sh
Normal file
1118
raspberry/python/install_inkyphat_lib.sh
Normal file
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@ Display data from MQTT broker on ePaper screen
|
||||
|
||||
@author: arofarn
|
||||
"""
|
||||
__version__ = 0.2
|
||||
__version__ = 0.3
|
||||
|
||||
###########
|
||||
# IMPORTS #
|
||||
@ -30,29 +30,20 @@ import paho.mqtt.client as mqtt
|
||||
import time
|
||||
import json
|
||||
import netifaces, socket
|
||||
import epd2in13
|
||||
import inkyphat
|
||||
from PIL import Image
|
||||
from PIL import ImageDraw
|
||||
from PIL import ImageFont
|
||||
|
||||
##########
|
||||
# Config #
|
||||
##########
|
||||
mqtt_client_id = "epaper_display"
|
||||
|
||||
# Colors codes
|
||||
white = 255
|
||||
black = 0
|
||||
|
||||
def update_epd():
|
||||
"""
|
||||
Update ePaper Display
|
||||
"""
|
||||
# 90° rotation + 180° if parameter epd_rotate different of 0
|
||||
# The small translation corrects an offset after rotation of 270°
|
||||
screen = image.rotate(90 + (epd_rotate * 180),
|
||||
expand=True,
|
||||
translate=(-6*epd_rotate, 0))
|
||||
# Put the picture to display in frame memory and display the new frame
|
||||
epd.set_frame_memory(screen, 0, 0)
|
||||
epd.display_frame()
|
||||
white = inkyphat.WHITE
|
||||
black = inkyphat.BLACK
|
||||
grey = inkyphat.RED
|
||||
|
||||
#############
|
||||
# CALLBACKS #
|
||||
@ -92,21 +83,23 @@ def on_message(client, userdata, msg):
|
||||
val['unit'] = val['unit'].replace('deg', '°')
|
||||
|
||||
#List of 'displayable' data types and their coordinate on screen
|
||||
coord_type = { 'AT' : (12, 50),
|
||||
'RH' : (137, 50),
|
||||
'AP' : (12, 72),
|
||||
'ALTI' : (137, 72),
|
||||
coord_type = { 'AT' : (1, data1_line),
|
||||
'RH' : (inkyphat.WIDTH / 2 + 12, data1_line),
|
||||
'AP' : (1, data2_line),
|
||||
'ALTI' : (inkyphat.WIDTH / 2 + 12, data2_line),
|
||||
}
|
||||
print(val)
|
||||
if val['type'] in coord_type:
|
||||
#Erase old data
|
||||
draw.rectangle(coord_type[val['type']] + (coord_type[val['type']][0] + 112, coord_type[val['type']][1] + 20), fill=white)
|
||||
inkyphat.rectangle(coord_type[val['type']] + (coord_type[val['type']][0] + inkyphat.WIDTH / 2 - 2,
|
||||
coord_type[val['type']][1] + 16),
|
||||
fill=white)
|
||||
#Draw new values
|
||||
draw.text(coord_type[val['type']],
|
||||
"{:6.1f}{} ".format(val['value'], val['unit']),
|
||||
font=font20_bold,
|
||||
fill=black)
|
||||
update_epd()
|
||||
inkyphat.text(coord_type[val['type']],
|
||||
"{:6.1f}{} ".format(val['value'], val['unit']),
|
||||
font=data_font,
|
||||
fill=black)
|
||||
inkyphat.show()
|
||||
|
||||
# Print feather's date and time on epaper display
|
||||
elif subtopics[0] == "SYS":
|
||||
@ -121,11 +114,11 @@ def on_message(client, userdata, msg):
|
||||
dt_texte = payload
|
||||
print(dt_texte)
|
||||
# First erase old text
|
||||
draw.rectangle((0, 34, epd2in13.EPD_HEIGHT, 48), fill=white)
|
||||
inkyphat.rectangle((0, 31, inkyphat.WIDTH, 45), fill=white)
|
||||
# and draw the new date
|
||||
draw.text((0, 34), dt_texte, font=font14, fill=black)
|
||||
inkyphat.text((0, 31), dt_texte, font=font12, fill=black)
|
||||
|
||||
update_epd()
|
||||
inkyphat.show()
|
||||
|
||||
def on_message_camera(client, userdata, msg):
|
||||
"""Update display with info from camera (camera shooting new picture or name
|
||||
@ -136,15 +129,15 @@ def on_message_camera(client, userdata, msg):
|
||||
|
||||
# If a picture is been taken
|
||||
if pl == "1" and msg.topic == camera_mqtt_topic + "/shooting" :
|
||||
draw.rectangle((0, 106, epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), fill=white)
|
||||
draw.text((0, 106), "Shooting photo... ", font=font14, fill=black)
|
||||
update_epd()
|
||||
inkyphat.rectangle((0, inkyphat.HEIGHT - 13, inkyphat.WIDTH, inkyphat.HEIGHT), fill=white)
|
||||
inkyphat.text((0, inkyphat.HEIGHT - 13), "Shooting photo... ", font=font12, fill=black)
|
||||
inkyphat.show()
|
||||
|
||||
#Last picture name (with date/time)
|
||||
if msg.topic == camera_mqtt_topic + "/last_photo":
|
||||
draw.rectangle((0, 106, epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), fill=white)
|
||||
draw.text((0, 106), "Last: " + pl, font=font14, fill=black)
|
||||
update_epd()
|
||||
inkyphat.rectangle((0, inkyphat.HEIGHT - 12, inkyphat.WIDTH, inkyphat.HEIGHT), fill=white)
|
||||
inkyphat.text((0, inkyphat.HEIGHT - 12), "Last: " + pl, font=font12, fill=black)
|
||||
inkyphat.show()
|
||||
|
||||
|
||||
def on_disconnect(client, userdata, msg):
|
||||
@ -158,51 +151,52 @@ def on_disconnect(client, userdata, msg):
|
||||
########
|
||||
|
||||
#Screen init.
|
||||
epd = epd2in13.EPD()
|
||||
epd.init(epd.lut_full_update)
|
||||
inkyphat.set_colour("black")
|
||||
|
||||
#List of TrueType fonts
|
||||
font12 = ImageFont.truetype(epd_font_file, 12)
|
||||
font14 = ImageFont.truetype(epd_font_file, 14)
|
||||
font16 = ImageFont.truetype(epd_font_file, 16)
|
||||
font20 = ImageFont.truetype(epd_font_file, 20)
|
||||
font12_bold = ImageFont.truetype(epd_bold_font_file, 12)
|
||||
font14_bold = ImageFont.truetype(epd_bold_font_file, 14)
|
||||
font16_bold = ImageFont.truetype(epd_bold_font_file, 16)
|
||||
font20_bold = ImageFont.truetype(epd_bold_font_file, 20)
|
||||
#font12_obl = ImageFont.truetype(epd_italic_font_file, 12)
|
||||
#font14_obl = ImageFont.truetype(epd_italic_font_file, 14)
|
||||
#font16_obl = ImageFont.truetype(epd_italic_font_file, 16)
|
||||
font10 = inkyphat.ImageFont.truetype(epd_font_file, 10)
|
||||
font11 = inkyphat.ImageFont.truetype(epd_font_file, 11)
|
||||
font12 = inkyphat.ImageFont.truetype(epd_font_file, 12)
|
||||
font14 = inkyphat.ImageFont.truetype(epd_font_file, 14)
|
||||
font16 = inkyphat.ImageFont.truetype(epd_font_file, 16)
|
||||
font20 = inkyphat.ImageFont.truetype(epd_font_file, 20)
|
||||
font12_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 12)
|
||||
font14_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 14)
|
||||
font16_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 16)
|
||||
font20_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 20)
|
||||
#font12_obl = inkyphat.ImageFont.truetype(epd_italic_font_file, 12)
|
||||
#font14_obl = inkyphat.ImageFont.truetype(epd_italic_font_file, 14)
|
||||
#font16_obl = inkyphat.ImageFont.truetype(epd_italic_font_file, 16)
|
||||
|
||||
#New image buffer
|
||||
# Memo : 0=black, 255= white/blank
|
||||
image = Image.new('1', (epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), 255)
|
||||
draw = ImageDraw.Draw(image)
|
||||
# Lines and fonts
|
||||
title_line = 1
|
||||
title_font = font14_bold
|
||||
hostname_line = 19
|
||||
hostname_font = font11
|
||||
date_line = 31
|
||||
date_font = font12
|
||||
data1_line = 44
|
||||
data2_line = 62
|
||||
data_font = font16_bold
|
||||
data_table_bottom_line = data2_line + 17
|
||||
|
||||
#Draw title in white on black
|
||||
draw.rectangle((0, 0, epd2in13.EPD_HEIGHT, 18), fill=black)
|
||||
draw.text((60, 1),
|
||||
"Projet Camétéo",
|
||||
font=font16_bold,
|
||||
fill=white)
|
||||
inkyphat.rectangle((0, 0, inkyphat.WIDTH, 17), fill=grey)
|
||||
inkyphat.text((60, 1), "Projet Camétéo", font=title_font, fill=white)
|
||||
|
||||
#Write hostname and IP address
|
||||
draw.text((0, 19),
|
||||
"{} : IP= {}".format(socket.gethostname(),
|
||||
netifaces.ifaddresses('wlan0')[2][0]['addr']),
|
||||
font = font12,
|
||||
fill=black )
|
||||
inkyphat.text((0, 19),
|
||||
"{} : {}".format(socket.gethostname(),
|
||||
netifaces.ifaddresses('wlan0')[2][0]['addr']),
|
||||
font = hostname_font,
|
||||
fill = black )
|
||||
# Draw the black lines for data table
|
||||
draw.line((0,49,epd2in13.EPD_HEIGHT, 49), fill=black)
|
||||
draw.line((0,71,epd2in13.EPD_HEIGHT, 71), fill=black)
|
||||
draw.line((0,93,epd2in13.EPD_HEIGHT, 93), fill=black)
|
||||
draw.line((125, 49, 125, 93), fill=black)
|
||||
inkyphat.line((0, data1_line - 1, inkyphat.WIDTH, data1_line - 1), fill=black)
|
||||
inkyphat.line((0, data2_line - 1, inkyphat.WIDTH, data2_line - 1), fill=black)
|
||||
inkyphat.line((0, data_table_bottom_line, inkyphat.WIDTH, data_table_bottom_line), fill=black)
|
||||
inkyphat.line((inkyphat.WIDTH / 2, data1_line - 1, inkyphat.WIDTH / 2, data_table_bottom_line), fill=black)
|
||||
|
||||
#Display on ePaper screen
|
||||
epd.clear_frame_memory(0xFF)
|
||||
update_epd()
|
||||
|
||||
#Toggle to partial refresh
|
||||
epd.init(epd.lut_partial_update)
|
||||
inkyphat.show()
|
||||
|
||||
#Connect to MQTT broker and loop...
|
||||
mqtt_client = mqtt.Client(mqtt_client_id, clean_session=True)
|
||||
|
Loading…
Reference in New Issue
Block a user