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
|
@author: arofarn
|
||||||
"""
|
"""
|
||||||
__version__ = 0.2
|
__version__ = 0.3
|
||||||
|
|
||||||
###########
|
###########
|
||||||
# IMPORTS #
|
# IMPORTS #
|
||||||
@ -30,29 +30,20 @@ import paho.mqtt.client as mqtt
|
|||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
import netifaces, socket
|
import netifaces, socket
|
||||||
import epd2in13
|
import inkyphat
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL import ImageDraw
|
from PIL import ImageDraw
|
||||||
from PIL import ImageFont
|
from PIL import ImageFont
|
||||||
|
|
||||||
|
##########
|
||||||
|
# Config #
|
||||||
|
##########
|
||||||
mqtt_client_id = "epaper_display"
|
mqtt_client_id = "epaper_display"
|
||||||
|
|
||||||
# Colors codes
|
# Colors codes
|
||||||
white = 255
|
white = inkyphat.WHITE
|
||||||
black = 0
|
black = inkyphat.BLACK
|
||||||
|
grey = inkyphat.RED
|
||||||
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()
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# CALLBACKS #
|
# CALLBACKS #
|
||||||
@ -92,21 +83,23 @@ def on_message(client, userdata, msg):
|
|||||||
val['unit'] = val['unit'].replace('deg', '°')
|
val['unit'] = val['unit'].replace('deg', '°')
|
||||||
|
|
||||||
#List of 'displayable' data types and their coordinate on screen
|
#List of 'displayable' data types and their coordinate on screen
|
||||||
coord_type = { 'AT' : (12, 50),
|
coord_type = { 'AT' : (1, data1_line),
|
||||||
'RH' : (137, 50),
|
'RH' : (inkyphat.WIDTH / 2 + 12, data1_line),
|
||||||
'AP' : (12, 72),
|
'AP' : (1, data2_line),
|
||||||
'ALTI' : (137, 72),
|
'ALTI' : (inkyphat.WIDTH / 2 + 12, data2_line),
|
||||||
}
|
}
|
||||||
print(val)
|
print(val)
|
||||||
if val['type'] in coord_type:
|
if val['type'] in coord_type:
|
||||||
#Erase old data
|
#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 new values
|
||||||
draw.text(coord_type[val['type']],
|
inkyphat.text(coord_type[val['type']],
|
||||||
"{:6.1f}{} ".format(val['value'], val['unit']),
|
"{:6.1f}{} ".format(val['value'], val['unit']),
|
||||||
font=font20_bold,
|
font=data_font,
|
||||||
fill=black)
|
fill=black)
|
||||||
update_epd()
|
inkyphat.show()
|
||||||
|
|
||||||
# Print feather's date and time on epaper display
|
# Print feather's date and time on epaper display
|
||||||
elif subtopics[0] == "SYS":
|
elif subtopics[0] == "SYS":
|
||||||
@ -121,11 +114,11 @@ def on_message(client, userdata, msg):
|
|||||||
dt_texte = payload
|
dt_texte = payload
|
||||||
print(dt_texte)
|
print(dt_texte)
|
||||||
# First erase old text
|
# 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
|
# 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):
|
def on_message_camera(client, userdata, msg):
|
||||||
"""Update display with info from camera (camera shooting new picture or name
|
"""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 a picture is been taken
|
||||||
if pl == "1" and msg.topic == camera_mqtt_topic + "/shooting" :
|
if pl == "1" and msg.topic == camera_mqtt_topic + "/shooting" :
|
||||||
draw.rectangle((0, 106, epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), fill=white)
|
inkyphat.rectangle((0, inkyphat.HEIGHT - 13, inkyphat.WIDTH, inkyphat.HEIGHT), fill=white)
|
||||||
draw.text((0, 106), "Shooting photo... ", font=font14, fill=black)
|
inkyphat.text((0, inkyphat.HEIGHT - 13), "Shooting photo... ", font=font12, fill=black)
|
||||||
update_epd()
|
inkyphat.show()
|
||||||
|
|
||||||
#Last picture name (with date/time)
|
#Last picture name (with date/time)
|
||||||
if msg.topic == camera_mqtt_topic + "/last_photo":
|
if msg.topic == camera_mqtt_topic + "/last_photo":
|
||||||
draw.rectangle((0, 106, epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), fill=white)
|
inkyphat.rectangle((0, inkyphat.HEIGHT - 12, inkyphat.WIDTH, inkyphat.HEIGHT), fill=white)
|
||||||
draw.text((0, 106), "Last: " + pl, font=font14, fill=black)
|
inkyphat.text((0, inkyphat.HEIGHT - 12), "Last: " + pl, font=font12, fill=black)
|
||||||
update_epd()
|
inkyphat.show()
|
||||||
|
|
||||||
|
|
||||||
def on_disconnect(client, userdata, msg):
|
def on_disconnect(client, userdata, msg):
|
||||||
@ -158,51 +151,52 @@ def on_disconnect(client, userdata, msg):
|
|||||||
########
|
########
|
||||||
|
|
||||||
#Screen init.
|
#Screen init.
|
||||||
epd = epd2in13.EPD()
|
inkyphat.set_colour("black")
|
||||||
epd.init(epd.lut_full_update)
|
|
||||||
|
|
||||||
#List of TrueType fonts
|
#List of TrueType fonts
|
||||||
font12 = ImageFont.truetype(epd_font_file, 12)
|
font10 = inkyphat.ImageFont.truetype(epd_font_file, 10)
|
||||||
font14 = ImageFont.truetype(epd_font_file, 14)
|
font11 = inkyphat.ImageFont.truetype(epd_font_file, 11)
|
||||||
font16 = ImageFont.truetype(epd_font_file, 16)
|
font12 = inkyphat.ImageFont.truetype(epd_font_file, 12)
|
||||||
font20 = ImageFont.truetype(epd_font_file, 20)
|
font14 = inkyphat.ImageFont.truetype(epd_font_file, 14)
|
||||||
font12_bold = ImageFont.truetype(epd_bold_font_file, 12)
|
font16 = inkyphat.ImageFont.truetype(epd_font_file, 16)
|
||||||
font14_bold = ImageFont.truetype(epd_bold_font_file, 14)
|
font20 = inkyphat.ImageFont.truetype(epd_font_file, 20)
|
||||||
font16_bold = ImageFont.truetype(epd_bold_font_file, 16)
|
font12_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 12)
|
||||||
font20_bold = ImageFont.truetype(epd_bold_font_file, 20)
|
font14_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 14)
|
||||||
#font12_obl = ImageFont.truetype(epd_italic_font_file, 12)
|
font16_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 16)
|
||||||
#font14_obl = ImageFont.truetype(epd_italic_font_file, 14)
|
font20_bold = inkyphat.ImageFont.truetype(epd_bold_font_file, 20)
|
||||||
#font16_obl = ImageFont.truetype(epd_italic_font_file, 16)
|
#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
|
# Lines and fonts
|
||||||
# Memo : 0=black, 255= white/blank
|
title_line = 1
|
||||||
image = Image.new('1', (epd2in13.EPD_HEIGHT, epd2in13.EPD_WIDTH), 255)
|
title_font = font14_bold
|
||||||
draw = ImageDraw.Draw(image)
|
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 title in white on black
|
||||||
draw.rectangle((0, 0, epd2in13.EPD_HEIGHT, 18), fill=black)
|
inkyphat.rectangle((0, 0, inkyphat.WIDTH, 17), fill=grey)
|
||||||
draw.text((60, 1),
|
inkyphat.text((60, 1), "Projet Camétéo", font=title_font, fill=white)
|
||||||
"Projet Camétéo",
|
|
||||||
font=font16_bold,
|
|
||||||
fill=white)
|
|
||||||
#Write hostname and IP address
|
#Write hostname and IP address
|
||||||
draw.text((0, 19),
|
inkyphat.text((0, 19),
|
||||||
"{} : IP= {}".format(socket.gethostname(),
|
"{} : {}".format(socket.gethostname(),
|
||||||
netifaces.ifaddresses('wlan0')[2][0]['addr']),
|
netifaces.ifaddresses('wlan0')[2][0]['addr']),
|
||||||
font = font12,
|
font = hostname_font,
|
||||||
fill = black )
|
fill = black )
|
||||||
# Draw the black lines for data table
|
# Draw the black lines for data table
|
||||||
draw.line((0,49,epd2in13.EPD_HEIGHT, 49), fill=black)
|
inkyphat.line((0, data1_line - 1, inkyphat.WIDTH, data1_line - 1), fill=black)
|
||||||
draw.line((0,71,epd2in13.EPD_HEIGHT, 71), fill=black)
|
inkyphat.line((0, data2_line - 1, inkyphat.WIDTH, data2_line - 1), fill=black)
|
||||||
draw.line((0,93,epd2in13.EPD_HEIGHT, 93), fill=black)
|
inkyphat.line((0, data_table_bottom_line, inkyphat.WIDTH, data_table_bottom_line), fill=black)
|
||||||
draw.line((125, 49, 125, 93), fill=black)
|
inkyphat.line((inkyphat.WIDTH / 2, data1_line - 1, inkyphat.WIDTH / 2, data_table_bottom_line), fill=black)
|
||||||
|
|
||||||
#Display on ePaper screen
|
inkyphat.show()
|
||||||
epd.clear_frame_memory(0xFF)
|
|
||||||
update_epd()
|
|
||||||
|
|
||||||
#Toggle to partial refresh
|
|
||||||
epd.init(epd.lut_partial_update)
|
|
||||||
|
|
||||||
#Connect to MQTT broker and loop...
|
#Connect to MQTT broker and loop...
|
||||||
mqtt_client = mqtt.Client(mqtt_client_id, clean_session=True)
|
mqtt_client = mqtt.Client(mqtt_client_id, clean_session=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user