diff --git a/.gitignore b/.gitignore index 0d0aa43..5dff84f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ EXPORT-red.bmp *.cache/* settings.py info.log -eInk_env/* \ No newline at end of file +eInk_env/* +venv/* + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a2e8f72 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "submodules/waveshare_e-paper"] + path = submodules/waveshare_e-paper + url = https://github.com/waveshareteam/e-Paper + fetchrecursesubmodules = true diff --git a/README.md b/README.md index fd71907..9199979 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,11 @@
- A small desk-calendar with the theme of a portal chamber info.
+ A small battery powered desk-calenda with the theme of a portal chamber info.
- It displays the current date, the next few events in your calendar and whether a person in your contact list has a birthday (inc. their name).
+ It displays the current date, the next few events from one or more calendars, the current weather, a rotating quote and whether a person in your contact list has a birthday (inc. their name).
+
+
@@ -170,6 +279,13 @@ The raspi is held in place by threaded heat set inserts.
## Questions
+### The battery was dead and now the screen doesn't refresh, what can I do?
+The clock is out of sync. Run the `wittyPi.sh`script, Synchronize with network time`, and `Write RTC time to system`.
+
+### It doens't boot?
+Witty Pi sometimes can crash on shutdown, especially after a RTC reset. You must try to disconnect it from its power sources: the USB cable and the battery. Then try to restart the pi.
+
+
Stuck somewhere? \
You can contact me, or create a [issue](https://github.com/13Bytes/eInkCalendar/issues).
@@ -180,9 +296,12 @@ You can contact me, or create a [issue](https://github.co
## Contact
-
+Original Idea and Design:
Louis - [@Louis_D_](https://twitter.com/Louis_D_) - coding@13bytes.de
+Original Idea and Design:
+João - @joao - coding@colaco.me
+
diff --git a/dataHelper.py b/dataHelper.py
index 97b835b..7ee9c84 100644
--- a/dataHelper.py
+++ b/dataHelper.py
@@ -18,78 +18,99 @@
def sort_by_date(e: Event):
- return e.start.astimezone()
+ return e.start.astimezone()
def get_events(max_number: int) -> List[Event]:
- logger.info("Retrieving calendar infos")
- utc_timezone = tz.tzutc()
- current_timezone = tz.tzlocal()
-
- try:
- event_list = events(WEBDAV_CALENDAR_URL, fix_apple=WEBDAV_IS_APPLE)
- event_list.sort(key=sort_by_date)
-
- start_count = 0
- for event in event_list:
- event.start.replace(tzinfo=utc_timezone)
- event.start = event.start.astimezone(current_timezone)
-
- # remove events from previous day (problem based on time-zones)
- day_number = time.localtime().tm_mday
- event_date = event.start.date()
- if (day_number == 1 and event_date.month < time.localtime().tm_mon):
- start_count += 1
- max_number += 1
- elif (event_date.day < day_number):
- start_count += 1
- max_number += 1
-
- logger.info("Got {} calendar-entries (capped to {})".format(
- len(event_list), max_number-start_count))
- return event_list[start_count:max_number]
-
- except Exception as e:
- logger.critical(e)
- return []
+ logger.info("Retrieving calendar infos")
+ utc_timezone = tz.tzutc()
+ current_timezone = tz.tzlocal()
+
+ #Current date used to filter events
+ current_UTC_date = datetime.now(timezone.utc)
+
+ #Will store all the events
+ event_list = []
+
+ #Get all the events of the provided calendars, after the current date
+ for calendar_settings in WEBDAV_CALENDAR_URLS:
+ try:
+ calendar_events_list = events(
+ url=calendar_settings["url"],
+ start=current_UTC_date,
+ fix_apple=calendar_settings["is_apple"]
+ )
+ except Exception as e:
+ logger.critical(e)
+ continue
+
+ for event in calendar_events_list:
+ #Add a property called "calendar_name" to the event with the calendar name
+ #Will be used to identify the owner of the event
+ setattr(event, "calendar_name", calendar_settings["calendar_name"])
+ #Will add two attributes for the calendar so it can be drawn with different patterns
+ #If they are not available will fill a default value
+ try:
+ setattr(event, "pattern_fill", calendar_settings["pattern_fill"])
+ except:
+ setattr(event, "pattern_fill", "BLACK")
+ try:
+ setattr(event, "pattern_red_stripes", calendar_settings["pattern_red_stripes"])
+ except:
+ setattr(event, "pattern_red_stripes", False)
+
+
+
+ #Filter out the events that are before the current time (icalevents only filter by day and not hour and minute)
+ calendar_events_list = [event for event in calendar_events_list if event.end.astimezone(timezone.utc) >= current_UTC_date]
+ #Add the new events to the list
+ event_list = event_list + calendar_events_list
+
+ #Sort the list by date
+ event_list.sort(key=sort_by_date)
+
+ logger.info("Got {} calendar-entries (capped to {})".format(
+ len(event_list), max_number))
+ return event_list[0:max_number]
+
def get_birthdays() -> List[str]:
- logger.info("Retrieving contact (birthday) infos")
- try:
- auth = HTTPBasicAuth(CALDAV_CONTACT_USER, CALDAV_CONTACT_PWD)
- baseurl = urlparse(CALDAV_CONTACT_URL).scheme + \
- '://' + urlparse(CALDAV_CONTACT_URL).netloc
-
- r = requests.request('PROPFIND', CALDAV_CONTACT_URL, auth=auth, headers={
- 'content-type': 'text/xml', 'Depth': '1'})
- if r.status_code != 207:
- raise RuntimeError('error in response from %s: %r' %
- (CALDAV_CONTACT_URL, r))
-
- vcardUrlList = []
- root = etree.XML(r.text.encode())
- for link in root.xpath('./d:response/d:propstat/d:prop/d:getcontenttype[starts-with(.,"text/vcard")]/../../../d:href', namespaces={"d": "DAV:"}):
- vcardUrlList.append(baseurl + link.text)
-
- today = datetime.today()
- birthday_names: List[str] = []
- for vurl in vcardUrlList:
- r = requests.request("GET", vurl, auth=auth)
- vcard = vobject.readOne(r.text)
- if 'bday' in vcard.contents.keys():
- birthday = vcard.contents['bday'][0]
- try:
- birthday_date = datetime.strptime(
- birthday.value, "%Y-%m-%d")
- except ValueError:
- # necessary, because multipe formats are used...
- birthday_date = datetime.strptime(birthday.value, "%Y%m%d")
-
- if (birthday_date.day == today.day) and (birthday_date.month == today.month):
- name = vcard.contents['fn'][0].value
- birthday_names.append(name)
- return birthday_names
- except Exception as e:
- logger.critical(e)
- return []
+ logger.info("Retrieving contact (birthday) infos")
+ try:
+ auth = HTTPBasicAuth(CALDAV_CONTACT_USER, CALDAV_CONTACT_PWD)
+ baseurl = urlparse(CALDAV_CONTACT_URL).scheme + \
+ '://' + urlparse(CALDAV_CONTACT_URL).netloc
+
+ r = requests.request('PROPFIND', CALDAV_CONTACT_URL, auth=auth, headers={
+ 'content-type': 'text/xml', 'Depth': '1'})
+ if r.status_code != 207:
+ raise RuntimeError('error in response from %s: %r' %
+ (CALDAV_CONTACT_URL, r))
+
+ vcardUrlList = []
+ root = etree.XML(r.text.encode())
+ for link in root.xpath('./d:response/d:propstat/d:prop/d:getcontenttype[starts-with(.,"text/vcard")]/../../../d:href', namespaces={"d": "DAV:"}):
+ vcardUrlList.append(baseurl + link.text)
+
+ today = datetime.today()
+ birthday_names: List[str] = []
+ for vurl in vcardUrlList:
+ r = requests.request("GET", vurl, auth=auth)
+ vcard = vobject.readOne(r.text)
+ if 'bday' in vcard.contents.keys():
+ birthday = vcard.contents['bday'][0]
+ try:
+ birthday_date = datetime.strptime(
+ birthday.value, "%Y-%m-%d")
+ except ValueError:
+ # necessary, because multipe formats are used...
+ birthday_date = datetime.strptime(birthday.value, "%Y%m%d")
+
+ if (birthday_date.day == today.day) and (birthday_date.month == today.month):
+ name = vcard.contents['fn'][0].value
+ birthday_names.append(name)
+ return birthday_names
+ except Exception as e:
+ logger.critical(e)
+ return []
diff --git a/displayHelpers.py b/displayHelpers.py
index b5cff4f..4d8853d 100644
--- a/displayHelpers.py
+++ b/displayHelpers.py
@@ -1,7 +1,11 @@
import logging
import os
+import random
from typing import List, Tuple
+from enum import Enum
+from enum import auto
+
import numpy as np
from PIL import Image, ImageDraw, ImageFont
from PIL.Image import Image as TImage
@@ -15,77 +19,344 @@
def init_display(epd: eInk.EPD):
- logger.info("Init display")
- epd.init()
+ logger.info("Init display")
+ epd.init()
def clear_display(epd: eInk.EPD):
- logger.info("Clear display")
- epd.Clear()
+ logger.info("Clear display")
+ epd.Clear()
def set_sleep(epd: eInk.EPD):
- logger.info("Set display to sleep-mode")
- epd.sleep()
+ logger.info("Set display to sleep-mode")
+ epd.sleep()
def draw_text_centered(text: str, point: Tuple[float, float], canvas: TImageDraw, text_font: ImageFont.FreeTypeFont):
- text_width, _ = text_font.getsize(text)
- canvas.text((point[0] - text_width/2, point[1]),
- text, font=text_font, fill=0)
+ _ ,_, text_width, _ = text_font.getbbox(text)
+ canvas.text((point[0] - text_width/2, point[1]),
+ text, font=text_font, fill=0)
+
+
+def get_font_height(font: ImageFont.FreeTypeFont, withDescender: bool = False):
+ """
+ Calculate the height of the given font, including or excluding font extenders (ascenders and descenders).
+ Parameters:
+ -----------
+ font : ImageFont.FreeTypeFont
+ The font object from which the height is calculated. This should be an instance of `ImageFont.FreeTypeFont`
+ (from the Pillow library).
+
+ withDescender : bool, optional, default=False
+ If True, the height includes the size of the descender. If False, it only will returns the font's ascent.
-def get_font_height(font: ImageFont.FreeTypeFont):
- _, text_height = font.getsize("A")
- return text_height
+ Returns:
+ --------
+ int
+ The total height of the font. These values define the distance from the baseline to the top of the highest ascender and if withDescender is True to the bottom of the lowest descender.
+ Example:
+ --------
+ ```python
+ from PIL import ImageFont
+
+ font = ImageFont.truetype("arial.ttf", 40)
+ height = get_font_height(font)
+ print(f"Font height: {height} pixels")
+ ```
+
+ This will output the combined ascent and descent of the given font.
+
+ """
+ font_ascent, font_descent = font.getmetrics()
+ if withDescender:
+ # _, _, _, bottom = font.getbbox("A") # Potential future enhancement for more accurate extenders handling
+ return font_ascent + abs(font_descent)
+ else:
+ return font_ascent
def get_font_width(font: ImageFont.FreeTypeFont, text: str):
- text_width, _ = font.getsize(text)
- return text_width
+ _, _, right, _ = font.getbbox(text)
+ return right
def convert_image_to_screen(image: TImage) -> TImage:
- def convert_f(e):
- if (e > 0):
- return 0
- else:
- return 2
- vfunc = np.vectorize(convert_f)
+ def convert_f(e):
+ if (e > 0):
+ return 0
+ else:
+ return 2
+ vfunc = np.vectorize(convert_f)
- image_array = np.array(image)
- converted_image_array = vfunc(image_array)
- return Image.fromarray(converted_image_array)
+ image_array = np.array(image)
+ converted_image_array = vfunc(image_array)
+
+ # Cast the result to uint8 (Image only supports uint8 and this is int64)
+ converted_image_array = converted_image_array.astype(np.uint8)
+
+ return Image.fromarray(converted_image_array)
def get_portal_images(cake=False, flying=False, pellet_hazard=False, bridge=False) -> List[TImage]:
- def load_picture(name: str) -> TImage:
- return convert_image_to_screen(Image.open(
- os.path.join(PICTURE_DICT, name)))
-
- def bool_to_array_index(boolean: bool) -> int:
- if boolean:
- return 1
- else:
- return 0
-
- image_cake_names = ["Chamber_icon_cake.gif", "Chamber_icon_cake_on.gif"]
- image_pellet_hazard_names = [
- "Chamber_icon_pellet_hazard.gif", "Chamber_icon_pellet_hazard_on.gif"]
- image_cube_hazard_names = ["Chamber_icon_cube_hazard.gif",
- "Chamber_icon_cube_hazard_on.gif"]
- image_light_bridge_names = [
- "Chamber_icon_light_bridge.gif", "Chamber_icon_light_bridge_on.gif"]
- image_flying_exit_names = [
- "Chamber_icon_flying_exit.gif", "Chamber_icon_flying_exit_on.gif"]
-
- image_list = []
- image_list.append(load_picture(
- image_cake_names[bool_to_array_index(cake)]))
- image_list.append(load_picture(
- image_flying_exit_names[bool_to_array_index(flying)]))
- image_list.append(load_picture(
- image_pellet_hazard_names[bool_to_array_index(pellet_hazard)]))
- image_list.append(load_picture(
- image_light_bridge_names[bool_to_array_index(bridge)]))
- return image_list
+ def load_picture(name: str) -> TImage:
+ return convert_image_to_screen(Image.open(
+ os.path.join(PICTURE_DICT, name)))
+
+ def bool_to_array_index(boolean: bool) -> int:
+ if boolean:
+ return 1
+ else:
+ return 0
+
+ image_cake_names = ["Chamber_icon_cake.gif", "Chamber_icon_cake_on.gif"]
+ image_pellet_hazard_names = [
+ "Chamber_icon_pellet_hazard.gif", "Chamber_icon_pellet_hazard_on.gif"]
+ image_cube_hazard_names = ["Chamber_icon_cube_hazard.gif",
+ "Chamber_icon_cube_hazard_on.gif"]
+ image_light_bridge_names = [
+ "Chamber_icon_light_bridge.gif", "Chamber_icon_light_bridge_on.gif"]
+ image_flying_exit_names = [
+ "Chamber_icon_flying_exit.gif", "Chamber_icon_flying_exit_on.gif"]
+
+ image_list = []
+ image_list.append(load_picture(
+ image_cake_names[bool_to_array_index(cake)]))
+ image_list.append(load_picture(
+ image_flying_exit_names[bool_to_array_index(flying)]))
+ image_list.append(load_picture(
+ image_pellet_hazard_names[bool_to_array_index(pellet_hazard)]))
+ image_list.append(load_picture(
+ image_light_bridge_names[bool_to_array_index(bridge)]))
+ return image_list
+
+def draw_black_red_white_text(draw_blk, draw_red, text, position, font, black_density, red_density=0.0, white_density=0.0):
+ """
+ Draw text with epaper black/red color text on a black-and-white image context by controlling the density of black pixels using the existing draw contexts for black and red.
+
+ :param draw_blk: ImageDraw.Draw object for the image
+ :param draw_red: ImageDraw.Draw object for the image
+ :param text: Text to be written
+ :param position: Tuple (x, y) for text position
+ :param font: Font to use
+ :param black_density: Fraction of black pixels in the text. It will be normalized to a total of 1 with the other two colors.
+ :param red_density: Fraction of red pixels in the text. It will be normalized to a total of 1 with the other two colors.
+ :param white_density: Fraction of white pixels in the text. It will be normalized to a total of 1 with the other two colors.
+
+ """
+ #Normalize color values
+ total_density = black_density + red_density + white_density
+
+ black_density = black_density/total_density
+ red_density = red_density/total_density
+ white_density = white_density/total_density
+
+ # Calculate text size
+ _, _, text_width, text_height = font.getbbox(text)
+
+ x, y = position
+
+ # Generate an image with the text
+ # Create a blank image for the text
+ text_image = Image.new('L', (text_width, text_height), 255) # White background
+ #Generate the context for writing the text
+ text_draw = ImageDraw.Draw(text_image)
+ ##Write the text
+ text_draw.text((0, 0), text, font=font, fill=1)
+
+ # Convert the text image to a NumPy array for manipulation
+ text_array = np.array(text_image)
+
+ # Iterate over the array and test each point. If pass will write a point to the main context
+ for j in range(text_height):
+ for i in range(text_width):
+ if text_array[j, i] == 1: # If the pixel is part of the text
+ #The test is for the color density of the letters.
+ #A random number is generated and if is above the threshold no point will be written
+ random_value = random.random()
+ if random_value < black_density:
+ # Draw a black point if the random value is below the black density
+ draw_blk.point((x + i, y + j), fill=1)
+ elif random_value < red_density + black_density:
+ #draw a red point if the value is between the black density and its sum wih the red one
+ draw_red.point((x + i, y + j), fill=1)
+ #Otherwise will stay white
+class Pattern(Enum):
+ BLACK = auto()
+ RED = auto()
+ VERTICALSTRIPES = auto()
+ HORIZONTALSTRIPES = auto()
+ DIAGONALSTRIPESLOWERRIGHT = auto()
+ DIAGONALSTRIPESUPPERRIGHT = auto()
+#import random
+def draw_pattern(
+ pattern: Pattern,
+ draw_blk: ImageDraw.Draw,
+ draw_red: ImageDraw.Draw,
+ corner1: (int, int),
+ corner2: (int, int),
+ use_red: bool = False
+ ) -> None:
+ """
+ Draws a specified pattern within a rectangle defined by two corner points.
+
+ The pattern can be solid black, solid red, or various striped patterns (vertical, horizontal, diagonal).
+ Striped patterns can be black and white, or black and red depending on the use_red flag.
+
+ Parameters:
+ -----------
+ pattern : Pattern
+ The pattern to draw. Must be one of the defined Pattern Enum values.
+ draw_blk : ImageDraw.Draw
+ The drawing context for black color. Typically obtained from PIL.ImageDraw.Draw for the black image.
+ draw_red : ImageDraw.Draw
+ The drawing context for red color. Typically obtained from PIL.ImageDraw.Draw for the red image.
+ corner1 : (int, int)
+ The (x, y) coordinates of one corner of the rectangle.
+ corner2 : (int, int)
+ The (x, y) coordinates of the opposite corner of the rectangle.
+ use_red : bool, optional
+ If True, red color will be used in the striped patterns instead of white.
+ Default is False (black and white stripes).
+
+ Returns:
+ --------
+ None
+ """
+ line_width = 1 # The width of the lines in the patterns
+
+ # Determine the min and max x coordinates
+ extremes_x = int(corner1[0]), int(corner2[0])
+ x_min = min(extremes_x)
+ x_max = max(extremes_x)
+
+ # Determine the min and max y coordinates
+ extremes_y = int(corner1[1]), int(corner2[1])
+ y_min = min(extremes_y)
+ y_max = max(extremes_y)
+
+ # Calculate the width and height of the rectangle
+ width = x_max - x_min
+ height = y_max - y_min
+
+ #Use for testing
+ #pattern=random.choice(list(Pattern))
+ #use_red=random.choice([True, False])
+
+ # Draw the pattern based on the specified type
+ match pattern:
+ case Pattern.BLACK:
+ # Fill the rectangle with solid black
+ draw_blk.rectangle([corner1, corner2], fill=1)
+
+ case Pattern.RED:
+ # Fill the rectangle with solid red
+ draw_red.rectangle([corner1, corner2], fill=1)
+
+ case Pattern.VERTICALSTRIPES:
+ # Draw vertical stripes within the rectangle
+ for x in range(x_min, x_max, line_width):
+ line = [(x, y_min), (x, y_max)]
+
+ if ((x - x_min) % (line_width*3)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width*2, fill=1)
+ elif use_red and ((x - x_min) % (line_width*3)) > line_width*2-1:
+ # Draw red stripe if use_red is True
+ draw_red.line(line, width=line_width, fill=1)
+
+ case Pattern.HORIZONTALSTRIPES:
+ # Draw horizontal stripes within the rectangle
+ for y in range(y_min, y_max, line_width):
+ line = [(x_min, y), (x_max, y)]
+
+ if ((y - y_min) % (line_width * 3)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width*2, fill=1)
+ elif use_red and ((y - y_min) % (line_width * 3)) > line_width*2-1:
+ # Draw red stripe if use_red is True
+ draw_red.line(line, width=line_width, fill=1)
+
+ case Pattern.DIAGONALSTRIPESLOWERRIGHT:
+ # Draw diagonal stripes from lower left to upper right (sloping downwards to the right)
+ line_width = 2
+ ##Correct a optical artifact for the diagonals
+ x_max = x_max-1
+ width = width-1
+
+ # First set of lines starting from x-axis increments
+ for delta_x in range(0, width, line_width):
+ x = x_min + delta_x
+
+ line = [
+ (x, y_min),
+ (min(x_max, x + height), min(y_min + (x_max - x), y_max))
+ ]
+
+ if (delta_x % (line_width * 2)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width, fill=1)
+ elif use_red:
+ # Draw red stripe (with thinner line width)
+ draw_red.line(line, width=round(line_width / 2), fill=1)
+ # The red lines are thinner to account for the extra pixels in a diagonal.
+
+ # Second set of lines starting from y-axis increments
+ for delta_y in range(0, height, line_width):
+ y = y_min + delta_y
+
+ line = [
+ (x_min, y),
+ (min(x_max, x_min + (y_max - y)), min(y_max, y + width))
+ ]
+
+ if (delta_y % (line_width * 2)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width, fill=1)
+ elif use_red:
+ # Draw red stripe
+ draw_red.line(line, width=round(line_width / 2), fill=1)
+
+ case Pattern.DIAGONALSTRIPESUPPERRIGHT:
+ # Draw diagonal stripes from upper left to lower right (sloping upwards to the right)
+ line_width = 2
+ ##Correct a optical artifact for the diagonals
+ x_min = x_min+1
+ width = width-1
+
+ # First set of lines starting from y-axis decrements
+ for delta_y in range(0, height, line_width):
+ y = y_max - delta_y
+
+ line = [
+ (x_min, y),
+ (min(x_max, x_min + (y - y_min)), max(y_min, y - width))
+ ]
+
+ if (delta_y % (line_width * 2)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width, fill=1)
+ elif use_red:
+ # Draw red stripe
+ draw_red.line(line, width=round(line_width / 2), fill=1)
+
+ # Second set of lines starting from x-axis increments
+ for delta_x in range(0, width, line_width):
+ x = x_min + delta_x
+
+ line = [
+ (x, y_max),
+ (min(x_max, x + height), max(y_max - (x_max - x), y_min))
+ ]
+
+ if (delta_x % (line_width * 2)) == 0:
+ # Draw black stripe
+ draw_blk.line(line, width=line_width, fill=1)
+ elif use_red:
+ # Draw red stripe
+ draw_red.line(line, width=round(line_width / 2), fill=1)
+
+ case _:
+ # Default case: fill the rectangle with solid black
+ draw_blk.rectangle([corner1, corner2], fill=1)
\ No newline at end of file
diff --git a/displayRun.py b/displayRun.py
index 8c66fa5..94dd708 100644
--- a/displayRun.py
+++ b/displayRun.py
@@ -7,206 +7,933 @@
import sys
import time
from datetime import datetime
+import zoneinfo
+
+from enum import Enum
+
+import calendar
+
+from holidays import country_holidays
import schedule
+
+import re
+
+import requests
+
from PIL import Image, ImageDraw, ImageFont, ImageOps
from PIL.Image import Image as TImage
from PIL.ImageDraw import ImageDraw as TImageDraw
import lib.epd7in5b_V2 as eInk
from dataHelper import get_events, get_birthdays
+
from displayHelpers import *
-from settings import LOCALE, ROTATE_IMAGE
+from settings import *
+
+#For reading battery levels from the I2C bus (will assume that witty pi is on address 0x08 address)
+from smbus2 import SMBus
+
+
+#Get the conversion from the weather codes to emoji symbols
+from weatherCodesEmoji import *
logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"),
- handlers=[logging.FileHandler(filename="info.log", mode='w'),
- logging.StreamHandler()])
+ handlers=[logging.FileHandler(filename="info.log", mode='w'),
+ logging.StreamHandler()])
logger = logging.getLogger('app')
CURRENT_DICT = os.path.dirname(os.path.realpath(__file__))
PICTURE_DICT = os.path.join(CURRENT_DICT, 'pictures')
FONT_DICT = os.path.join(CURRENT_DICT, 'fonts')
-DEBUG = False
-FONT_ROBOTO_DATE = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Roboto-Black.ttf'), 200)
+#Define debug if it was not already defined in settings.py
+try:
+ DEBUG
+except NameError:
+ DEBUG = False
+
+title_date_font_size=200
+TITLE_DATE = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), title_date_font_size)
FONT_ROBOTO_H1 = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Roboto-Black.ttf'), 40)
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), 40)
FONT_ROBOTO_H2 = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Roboto-Black.ttf'), 30)
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), 30)
FONT_ROBOTO_P = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Roboto-Black.ttf'), 20)
-FONT_POPPINS_BOLT_P = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Poppins-Bold.ttf'), 22)
-FONT_POPPINS_P = ImageFont.truetype(
- os.path.join(FONT_DICT, 'Poppins-Regular.ttf'), 20)
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), 20)
+
+WEATHER_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), 20)
+#To display the glyphs for the state of the weather
+WEATHER_EMOJI_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'NotoEmoji-Regular.ttf'), 20)
+
+
+#The calendar will occupy the same height of the Title Date font, and will have 7 rows.
+#So the size of the font should be at maximum 7 times less (the calendar has 7 rows.)
+#To make sure that there's some space between rows, for the ascenders and descenders and for the size between columns it be half of that.
+calendar_number_font_size = int(round(title_date_font_size/(7*2)))
+
+CALENDAR_NUMBER_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono.ttf'), calendar_number_font_size)
+
+CALENDAR_NUMBER_TODAY_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono-Bold.ttf'), calendar_number_font_size)
+
+#Font for the days numbers of the other months
+CALENDAR_NUMBER_SECONDARY_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono.ttf'), int(round(calendar_number_font_size/4*3)))
+#Font for the calendar header
+CALENDAR_HEADER_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono-Bold.ttf'), calendar_number_font_size)
+
+
+EVENT_TIME_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono.ttf'), 20)
+EVENT_TIME_SECONDARY_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSansMono.ttf'), 16)
+
+EVENT_NAME_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSans.ttf'), 22)
+EVENT_CALENDAR_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSans-Bold.ttf'), 18)
+
+FOOTNOTE_FONT = ImageFont.truetype(
+ os.path.join(FONT_DICT, 'DejaVuSans.ttf'), 8)
+
LINE_WIDTH = 3
+CALENDAR_LINE_WIDTH = 10
def main():
- logger.info(datetime.now())
- try:
- epd = eInk.EPD()
-
- if DEBUG:
- logger.info("DEBUG-Mode activated...")
-
- image_blk = Image.open(os.path.join(
- PICTURE_DICT, "blank-aperture.bmp"))
- image_red = Image.open(os.path.join(
- PICTURE_DICT, "blank-hk.bmp"))
-
- draw_blk = ImageDraw.Draw(image_blk)
- draw_red = ImageDraw.Draw(image_red)
-
- render_content(draw_blk, image_blk, draw_red,
- image_red, epd.width, epd.height)
- show_content(epd, image_blk, image_red)
- # clear_content(epd)
-
- except Exception as e:
- logger.warning(e)
- if not DEBUG:
- logger.info("Trying to module_exit()")
- eInk.epdconfig.module_exit()
- raise e
-
-
-def render_content(draw_blk: TImageDraw, image_blk: TImage, draw_red: TImageDraw, image_red: TImage, height: int, width: int):
- locale.setlocale(locale.LC_ALL, LOCALE)
-
- PADDING_L = int(width/10)
- PADDING_TOP = int(height/100)
- now = time.localtime()
- max_days_in_month = calendar.monthrange(now.tm_year, now.tm_mon)[1]
- day_str = time.strftime("%A")
- day_number = now.tm_mday
- month_str = time.strftime("%B")
-
- # draw_text_centered(str(day_number), (width/2, 0), draw_blk, FONT_ROBOTO_H1)
-
- # Heading
- current_height = height/20
- draw_blk.line((PADDING_L, current_height, width, current_height),
- fill=1, width=LINE_WIDTH)
- draw_blk.text((PADDING_L, current_height), month_str.upper(),
- font=FONT_ROBOTO_H2, fill=1)
- current_height += get_font_height(FONT_ROBOTO_H2)
-
- # Date
- current_font_height = get_font_height(FONT_ROBOTO_DATE)
- draw_blk.text((PADDING_L, current_height - current_font_height/10),
- str(day_number), font=FONT_ROBOTO_DATE, fill=1)
- current_height += current_font_height
-
- # Month-Overview (with day-string)
- current_height += PADDING_TOP
- day_of_month = str(day_number) + "/" + str(max_days_in_month)
- draw_blk.text((PADDING_L, current_height), day_of_month,
- font=FONT_ROBOTO_P, fill=1)
-
- tmp_right_aligned = width - \
- get_font_width(FONT_ROBOTO_P, day_str.upper()) - PADDING_L/4
- draw_blk.text((tmp_right_aligned, current_height), day_str.upper(),
- font=FONT_ROBOTO_P, fill=1)
-
- current_height += get_font_height(FONT_ROBOTO_P) + PADDING_TOP
- draw_blk.line((PADDING_L, current_height, width, current_height),
- fill=1, width=LINE_WIDTH)
-
- # Month-Tally-Overview
- current_height += PADDING_TOP
- tally_height = height/40
- tally_width = LINE_WIDTH + width/120 # width + padding
- available_width = width - PADDING_L
- tally_number = int(available_width / tally_width *
- (day_number / max_days_in_month))
- x_position = PADDING_L + LINE_WIDTH/2
- for i in range(0, tally_number):
- draw_blk.line((x_position, current_height, x_position,
- current_height + tally_height), fill=1, width=LINE_WIDTH)
- x_position += tally_width
- current_height += tally_height
-
- # Calendar
- current_height += height/40
- event_list = get_events(6)
-
- last_event_day = datetime.now().date()
- for event in event_list:
- # Draw new day
- if last_event_day != event.start.date():
- # current_height += height/40
- last_event_day = event.start.date()
- # day_string = "{} {}".format(last_event_day.day,
- # last_event_day.strftime("%a"))
- day_string = last_event_day.strftime("%a %d")
- draw_blk.text((PADDING_L, current_height), day_string,
- font=FONT_ROBOTO_P, fill=1)
- current_height += get_font_height(FONT_ROBOTO_P)
-
- # Draw event
- event_text = ""
- if event.all_day:
- draw_blk.text((PADDING_L, current_height), "- : -",
- font=FONT_POPPINS_P, fill=1)
- else:
- draw_blk.text((PADDING_L, current_height), event.start.strftime("%H:%M"),
- font=FONT_POPPINS_P, fill=1)
-
- summmary_padding = 60
- draw_blk.text((PADDING_L + summmary_padding, current_height), event.summary,
- font=FONT_POPPINS_P, fill=1)
- current_height += get_font_height(FONT_POPPINS_P) * 1.1
-
- # Portal-Icons
- current_height = int(height*0.73)
- draw_blk.line((PADDING_L, current_height, width, current_height),
- fill=1, width=LINE_WIDTH)
- current_height += PADDING_TOP
-
- y = PADDING_L
- bithday_persons = get_birthdays()
- draw_cake = (len(bithday_persons) > 0)
- max_image_height = 0
- for image in get_portal_images(draw_cake, bool(random.getrandbits(1)), bool(random.getrandbits(1)), bool(random.getrandbits(1))):
- image_blk.paste(image, (y, current_height))
- image_width, image_height = image.size
- y += image_width + PADDING_TOP
- max_image_height = image_height if (
- image_height > max_image_height) else max_image_height
- current_height += max_image_height + PADDING_TOP
- # Draw name of birthday-person
- if draw_cake:
- bithday_person_string = ", ".join(bithday_persons)
- draw_red.text((PADDING_L, current_height), bithday_person_string,
- font=FONT_ROBOTO_P, fill=1)
- current_height += get_font_height(FONT_ROBOTO_P)
+ logger.info(datetime.now())
+ try:
+ epd = eInk.EPD()
+
+ if DEBUG:
+ logger.info("DEBUG-Mode activated...")
+
+ #Use aperture image only if the user wants, otherwize use an image without the logo
+ image_blk = Image.open(os.path.join(
+ PICTURE_DICT, "blank-aperture.bmp" if APERTURE_DECORATIONS else "blank-hk.bmp"))
+
+ image_red = Image.open(os.path.join(
+ PICTURE_DICT, "blank-hk.bmp"))
+
+ draw_blk = ImageDraw.Draw(image_blk)
+ draw_red = ImageDraw.Draw(image_red)
+
+ render_content(draw_blk, image_blk, draw_red,
+ image_red, epd.width, epd.height)
+ show_content(epd, image_blk, image_red)
+ # clear_content(epd)
+
+ except Exception as e:
+ logger.warning(e)
+ if not DEBUG:
+ logger.info("Trying to module_exit()")
+ eInk.epdconfig.module_exit()
+ raise e
+
+
+def render_content(draw_blk: TImageDraw, image_blk: TImage, draw_red: TImageDraw, image_red: TImage, height: int, width: int):
+
+ locale.setlocale(locale.LC_ALL, LOCALE)
+
+
+ #Makes sure that antialiasing is disabled in font rendering
+ draw_blk.fontmode = "1"
+ draw_red.fontmode = "1"
+
+ PADDING_L = int(width/10)
+ PADDING_R = PADDING_L/4
+ PADDING_R_COORDINATE = width - PADDING_R
+ PADDING_TOP = int(height/100)
+ now = time.localtime()
+ max_days_in_month = calendar.monthrange(now.tm_year, now.tm_mon)[1]
+ day_str = time.strftime("%A")
+ day_number = now.tm_mday
+ wday_number = now.tm_wday
+ month_number = now.tm_mon
+ year_number = now.tm_year
+ is_weekend = wday_number >= 5
+ month_str = time.strftime("%B")
+
+ #Get the country code from the locale
+ try:
+ country_code = re.split(r'[_\.]', LOCALE)[1]
+ except:
+ country_code = ""
+ #Get the holidays
+ locale_holidays = country_holidays(country_code, years = year_number)
+
+ date_now = datetime(year_number, month_number, day_number).date()
+ #Test if today is a holiday
+ is_holiday = date_now in locale_holidays
+
+ # draw_text_centered(str(day_number), (width/2, 0), draw_blk, FONT_ROBOTO_H1)
+
+
+ vertical_margin = height/20
+
+ current_height = vertical_margin
+
+ #First Line
+ draw_blk.line((PADDING_L, current_height, width, current_height),
+ fill=1, width=LINE_WIDTH)
+ #Weather
+
+ #Check the temperature units settings
+ global TEMPERATURE_UNIT
+ if 'TEMPERATURE_UNIT' not in globals():
+ TEMPERATURE_UNIT = "C"
+ elif TEMPERATURE_UNIT.upper() not in ['C', 'F']:
+ TEMPERATURE_UNIT = "C"
+
+ try:
+
+ unit_system = "imperial" if TEMPERATURE_UNIT.upper() == "F" else "metric"
+
+
+ url = f"https://api.tomorrow.io/v4/timelines?apikey={TOMORROWIO_API_KEY}"
+
+ payload = {
+ "location": WEATHER_LOCATION,
+ "fields": ["temperatureMax", "temperatureMin", "weatherCodeDay", "weatherCodeNight", "weatherCode", "temperatureMinTime", "temperatureMaxTime", "sunriseTime", "sunsetTime"],
+ "units": unit_system,
+ "timesteps": ["1d"],
+ "startTime": "now",
+ "endTime": "nowPlus1d"
+ }
+ headers = {
+ "accept": "application/json",
+ "Accept-Encoding": "gzip",
+ "content-type": "application/json"
+ }
+
+
+
+ except:
+ url = None
+ logger.info("Weather tomorrowIO location or API Key not set")
+
+ tomorrowIO_response = None
+ wait_for_new_request = False
+
+ if url != None:
+ #Will make a request for weather data.
+ #If there's an error will make it again after 10 minutes
+ try:
+ tomorrowIO_response = requests.post(url, json=payload, headers=headers)
+ except:
+ tomorrowIO_response = None
+ wait_for_new_request = True
+
+ if tomorrowIO_response != None:
+ try:
+ tomorrowIO_response.raise_for_status()
+ except Exception as err:
+ wait_for_new_request = True
+
+ if tomorrowIO_response.status_code == 400:
+ logger.error(f"The URL seems to be malformed. Check the wether parameters on settings - {err}")
+ else:
+ logger.warning(f"Could not make a connection to weather server: {err}. Will try again in 10 minutes.")
+
+
+ if wait_for_new_request:
+ #If there was an error try again 10 minutes later
+ time.sleep(600)
+
+ #try again a request
+ try:
+ tomorrowIO_response = requests.post(url, json=payload, headers=headers)
+ except:
+ tomorrowIO_response = None
+
+ #Check the response
+ if tomorrowIO_response != None:
+ try:
+ tomorrowIO_response.raise_for_status()
+ except requests.exceptions.HTTPError as err:
+ # Handle specific HTTP error responses (non-200)
+ print(f"HTTP error occurred: {err}")
+ except Exception as err:
+ # Handle other errors (e.g., network errors)
+ print(f"Other error occurred: {err}")
+
+
+ if tomorrowIO_response != None and tomorrowIO_response.status_code == 200:
+ tomorrowIO_response_json = tomorrowIO_response.json()
+ # Get the location
+ #responselocation = tomorrowIO_response_json["location"]
+ logger.info(f"Retrieved weather data for {WEATHER_LOCATION}.")
+
+ #Get the current weather
+ weather_data_by_interval = tomorrowIO_response_json["data"]["timelines"][0]["intervals"]
+
+
+ # Get the current time in the local timezone
+ local_timezone = zoneinfo.ZoneInfo("localtime")
+ now = datetime.now(local_timezone)
+
+ #Get an dict of results with a tuple were the key is the datetime of the forecast
+ max_temp_date = { datetime.fromisoformat(interval["values"]["temperatureMaxTime"]): interval["values"]["temperatureMax"] for interval in weather_data_by_interval}
+ min_temp_date = { datetime.fromisoformat(interval["values"]["temperatureMinTime"]): interval["values"]["temperatureMin"] for interval in weather_data_by_interval}
+
+
+ #Select the max temperature
+ #It will be the one closest with the current time on the current day or after.
+
+ #If there more that 1 value will test for the ones of the current day or after
+ if len(max_temp_date) > 1:
+ #Current day at midnight
+ midnight_today = now.replace(hour=0, minute=0, second=0, microsecond=0)
+ max_temp_date_filtered = [time for time in max_temp_date if time > midnight_today]
+
+ #Will get the datetime of the value closest to now
+ max_closest_time = min(max_temp_date_filtered, key=lambda date: abs(now - date))
+
+ #Will define the maximum temperature
+ max_temp = max_temp_date[max_closest_time]
+ else:
+ max_temp = max_temp_date.values()[0]
+
+
+ #Select the min temperature
+ #It will be the one closest with the current time.
+ # I think is the best way to have a meaningfull value
+ min_closest_time = min(min_temp_date.keys(), key=lambda date: abs(now - date))
+ min_temp = min_temp_date[min_closest_time]
+
+
+ #Get the next sunset and sunrise
+ sunrises_times = [datetime.fromisoformat(interval["values"]["sunriseTime"]) for interval in weather_data_by_interval]
+ sunsets_times = [datetime.fromisoformat(interval["values"]["sunsetTime"]) for interval in weather_data_by_interval]
+
+ next_sunrise = min([sunrise for sunrise in sunrises_times if sunrise >= now])
+ next_sunset = min([sunset for sunset in sunsets_times if sunset >= now])
+
+ #Get the day/night status
+ is_night = next_sunrise < next_sunset
+
+ #WeatherCodeDay
+ #Test if the current time is at night (between sunset and sunrise). If the sunrise is before the next predition use the current weathercodeDay prediction. Otherwise use the next one.
+ #This is only to not show a prediction fior a period in the past (if the next prediction is before the new day the current weather code for the day time is for yestarday)
+ if is_night and len(weather_data_by_interval)>1 and next_sunrise > datetime.fromisoformat(weather_data_by_interval[1]["startTime"]):
+ weatherCodeDay = weather_data_by_interval[1]["values"]["weatherCodeDay"]
+ else:
+ weatherCodeDay = weather_data_by_interval[0]["values"]["weatherCodeDay"]
+
+
+ #WeatherCodeNight
+ #Test if the current time is at day (between sunrise and sunset). If the sunset is before the next predition use the current weathercodeNight prediction. Otherwise use the next one.
+ if not is_night and len(weather_data_by_interval)>1 and next_sunset > datetime.fromisoformat(weather_data_by_interval[1]["startTime"]):
+ weatherCodeNight = weather_data_by_interval[1]["values"]["weatherCodeNight"]
+ else:
+ weatherCodeNight = weather_data_by_interval[0]["values"]["weatherCodeNight"]
+
+
+
+
+
+ try:
+ current_height += get_font_height(WEATHER_FONT) + PADDING_TOP
+
+ weather_box_leading_x = PADDING_L
+ weather_box_trailling_x = width - PADDING_R
+ weather_box_top_y = current_height - get_font_height(WEATHER_FONT)
+ weather_box_bottom_y = current_height
+
+ draw_blk.line((PADDING_L, current_height, width, current_height),
+ fill=1, width=LINE_WIDTH)
+ #Text will be white or red in a black background
+
+ #background
+ draw_blk.rectangle([(weather_box_leading_x, vertical_margin), (width, weather_box_bottom_y)], fill=1)
+
+
+ #Text
+ #Will draw something like ont the bar: |↥🌤️⛈️ ↧☀️ ↧-1ºC ↥5ºC| or |☀️ ↧-1ºC ↥5ºC| if the weather is similar during the day
+
+ #Temperature
+ #It will be draw from right to left.
+ display_celsius = TEMPERATURE_UNIT.upper() != "F"
+
+ temp_symbol = "℃" if display_celsius else "℉"
+
+ high_temp_string = str(round(max_temp))
+ high_temp = high_temp_string+temp_symbol # "28℃"
+ high_temp_symbol = "↑"
+
+ low_temp_string = str(round(min_temp))
+ low_temp = low_temp_string+temp_symbol
+ low_temp_symbol = "↓"
+
+ draw_blk.text((weather_box_trailling_x, weather_box_bottom_y), high_temp, font=WEATHER_FONT, anchor="rd", fill=0)
+
+ high_temp_width = get_font_width(WEATHER_FONT, high_temp_symbol+high_temp)
+
+ draw_blk.text((weather_box_trailling_x-high_temp_width, weather_box_bottom_y), high_temp_symbol, font=WEATHER_FONT, anchor="ld", fill=0)
+
+ high_temp_symbol_space_width = get_font_width(WEATHER_FONT, " " + high_temp_symbol + high_temp)
+
+ low_temp_string = low_temp_symbol+low_temp
+
+ draw_blk.text((weather_box_trailling_x-high_temp_symbol_space_width, weather_box_bottom_y), low_temp_symbol+low_temp, font=WEATHER_FONT, anchor="rd", fill=0)
+
+
+ #weather
+
+
+
+ weather_leading_space = weather_box_leading_x + PADDING_R #PADDING_R to give a padding equal to the right side
+
+ #If both weather codes are equal...
+ if weatherCodeDay//10 == weatherCodeNight//10:
+ #...Only draw one of them
+ all_weather_emojis = wheater_codes_emojis[weatherCodeNight//10]
+
+ draw_blk.text((weather_leading_space, weather_box_bottom_y), all_weather_emojis, font=WEATHER_EMOJI_FONT, anchor="ld", fill=0)
+
+ else:
+ #Otherwise draws both of them with an arrow pointing up or down with each of them
+ #Day weather
+ day_weather_emojis = wheater_codes_emojis[weatherCodeDay]
+
+ #Night weather
+ night_weather_emojis = wheater_codes_emojis[weatherCodeNight]
+
+
+ #Draw the low weather state
+ draw_blk.text((weather_leading_space, weather_box_bottom_y), day_weather_emojis, font=WEATHER_EMOJI_FONT, anchor="ld", fill=0)
+
+ #Get the width of the string of the day weather state
+ day_weather_string_width = get_font_width(WEATHER_EMOJI_FONT, day_weather_emojis+" ")
+
+ #Get the padding for the high weather state symbol
+ night_weather_padding = weather_leading_space + day_weather_string_width
+
+
+ #Draw the night symbol
+ draw_blk.text((night_weather_padding, weather_box_bottom_y), night_weather_emojis, font=WEATHER_EMOJI_FONT, anchor="ld", fill=0)
+
+
+ except Exception as err:
+ # Handle other errors (e.g., network errors)
+ print(f"Error occurred: {err}")
+
+
+
+
+
+ # Heading
+
+ draw_blk.text((PADDING_L, current_height), month_str.upper(),
+ font=FONT_ROBOTO_H2, fill=1)
+
+ #Weather
+ #Bounds
+ #weather_box_leading_x = PADDING_L+(width - PADDING_L - PADDING_R)/2
+ #weather_box_trailling_x = width - PADDING_R
+ #weather_box_top_y = current_height
+ #weather_box_bottom_y = current_height + get_font_height(WEATHER_FONT)
+#
+ ##draw_red.rectangle([(weather_box_leading_x, weather_box_top_y), (weather_box_trailling_x, weather_box_bottom_y)], outline=1, width= 1)
+ #draw_blk.multiline_text((weather_box_trailling_x, weather_box_top_y), "↥28℃ 18h\n↧12℃ 04h", font=WEATHER_FONT, anchor="ra", align="right", fill=1)
+
+ #Moves the height down
+ current_height += get_font_height(FONT_ROBOTO_H2)
+
+ # Day Number Title
+ current_font_height = get_font_height(TITLE_DATE)
+
+ #Write weekends days in red
+ title_date_origin_y = current_height - current_font_height/10
+
+
+ if is_weekend or is_holiday:
+ draw_red.text((PADDING_L, title_date_origin_y),
+ str(day_number), font=TITLE_DATE, fill=1)
+ else:
+ draw_blk.text((PADDING_L, title_date_origin_y),
+ str(day_number), font=TITLE_DATE, fill=1)
+
+ current_height += current_font_height - (current_font_height/10)
+
+
+ #Draws the MONTH CALENDAR
+
+ #Object of the calendar
+ month_calendar = calendar.TextCalendar()
+ #Set the first day of the week acording with settings
+ try:
+ month_calendar.setfirstweekday(calendar.SUNDAY if FIRST_WEEKDAY_IS_SUNDAY else calendar.MONDAY)
+ except:
+ month_calendar.setfirstweekday(calendar.MONDAY)
+
+ #list of lists of each day of each week of the month
+ days_of_month = month_calendar.monthdatescalendar(year_number, month_number)
+ number_of_weeks = len(days_of_month)
+ #Calculates distances and coordinates
+ line_test_leading_x = PADDING_L+2*(width - PADDING_L - PADDING_R)/3
+ line_test_trailing_x = PADDING_R_COORDINATE
+
+ line_test_bottom_y = current_height
+ line_test_top_y = current_height-current_font_height+2*(current_font_height/10)
+
+ cal_width = line_test_trailing_x-line_test_leading_x
+ day_width = round(cal_width/7)
+ #A padding to make the letters/numbers be draw on the center, center align
+ day_width_padding = round(day_width/2)
+
+ line_height_max = (line_test_bottom_y-line_test_top_y)/7
+
+ #Radius for the circle of the today day. The radius will be half the row or column size, whatever the lesser.
+ #Will be a bit bigger if the number has two digits (bigger so to evolve better the number but more little so it doesnt go abve the header if in the first row)
+ today_circle_radius = min(line_height_max, day_width) / 2 + (1 if day_number >= 10 else 0)
+
+ #The text should be aligned by the font baseline. However it sould appear centered on the screen below the upperedge of the current day number on the right
+ #This will aloow the text to be lowered.
+ #line_row_baseline_adjustment = get_font_height(CALENDAR_HEADER_FONT)/2
+
+ #Month Gridlines
+ #Bounds
+ #draw_red.rectangle([(line_test_leading_x, line_test_top_y), (line_test_trailing_x, line_test_bottom_y)], outline=1, width= 1)
+ ##Rows Lines (for 6 weeks, max number of weeks in a month, and the header)
+ #
+ #
+ #for row_number in range (1,7):
+ # row_height = line_test_top_y+row_number*line_height_max
+ # draw_red.line((line_test_leading_x, row_height, line_test_trailing_x, row_height), fill=1, width=1)
+
+ #Iterate the rows
+ for row_number in range (1,8):
+ #The row heigh will be half way between rows
+ row_height = int(round(line_test_top_y+(row_number-0.5)*line_height_max))
+
+ # In the first row draws the header with the week days name
+ if row_number == 1:
+ for index, header_day_number in enumerate(month_calendar.iterweekdays()):
+
+ #Day name first letter in caps
+ day_name = calendar.day_abbr[header_day_number]
+ day_name_header = day_name[0].upper()
+ day_name_coordinate = (line_test_leading_x+index*day_width+day_width_padding, row_height)
+
+ #Coordinates for the rectangle/background color
+ header_x_leading = line_test_leading_x+index*day_width
+ header_y_top = row_height - line_height_max/2
+
+ header_x_trailing = line_test_leading_x+index*day_width+day_width
+ header_y_bottom = row_height + line_height_max/2
+
+ #Will draw the rectangle in red if in a weekend. Otherwise in black
+ if header_day_number >= 5:
+ draw_red.rectangle([(header_x_leading, header_y_top), (header_x_trailing, header_y_bottom)], fill=1)
+
+ #Draw the first letter of the weekday in the background color
+ draw_red.text(day_name_coordinate, day_name_header, font=CALENDAR_HEADER_FONT, anchor="mm", fill=0)
+
+ else:
+ draw_blk.rectangle([(header_x_leading, header_y_top), (header_x_trailing, header_y_bottom)], fill=1)
+
+ #Draw the first letter of the weekday in the background color
+ draw_blk.text(day_name_coordinate, day_name_header, font=CALENDAR_HEADER_FONT, anchor="mm", fill=0)
+
+
+
+ elif number_of_weeks > row_number-2:
+ #If there is a days on the month to display in this row will retrieve and draw them
+ #Iterate the number columns
+ for day in range(0,7):
+ day_data = days_of_month[row_number-2][day]
+ cal_day_number = day_data.day
+ cal_day_number_string = str(cal_day_number).replace("0", "O")
+ cal_month_number = day_data.month
+ #The week day
+ cal_day_weekday = day_data.weekday()
+
+
+ center_day_coord = (line_test_leading_x+day*day_width+day_width_padding, row_height)
+
+
+ if cal_day_number == day_number and cal_month_number == month_number:
+ #Draw a circle on the current day. The radius will be half the row or column size, whatever the lesser
+ #Will be red on the weekends or holidays
+ if cal_day_weekday >= 5 or day_data in locale_holidays:
+ draw_red.circle(center_day_coord, today_circle_radius, fill=1)
+ draw_red.text(center_day_coord, cal_day_number_string, font=CALENDAR_NUMBER_TODAY_FONT, anchor="mm", fill=0, features=["-zero"])
+ else:
+ draw_blk.circle(center_day_coord, today_circle_radius, fill=1)
+ draw_blk.text(center_day_coord, cal_day_number_string, font=CALENDAR_NUMBER_TODAY_FONT, anchor="mm", fill=0, features=["-zero"])
+
+ else:
+ cal_font = CALENDAR_NUMBER_FONT if cal_month_number == month_number else CALENDAR_NUMBER_SECONDARY_FONT
+
+ #If the weekday is saturday or sunday or a holiday will paint it red
+ if cal_day_weekday >= 5 or day_data in locale_holidays:
+ draw_red.text(center_day_coord, cal_day_number_string, font=cal_font, anchor="mm", fill=1, features=["-zero"])
+ else:
+ draw_blk.text(center_day_coord, cal_day_number_string, font=cal_font, anchor="mm", fill=1, features=["-zero"])
+
+
+ # Month-Overview (with day-string)
+ current_height += PADDING_TOP
+ day_of_month = str(day_number) + "/" + str(max_days_in_month)
+ draw_blk.text((PADDING_L, current_height), day_of_month,
+ font=FONT_ROBOTO_P, fill=1)
+
+ draw_blk.text((PADDING_R_COORDINATE, current_height), day_str.upper(),
+ font=FONT_ROBOTO_P, anchor = "ra", fill=1)
+
+ #First line of the calendar
+ current_height += get_font_height(FONT_ROBOTO_P) + PADDING_TOP
+
+
+ draw_blk.line((PADDING_L, current_height, width, current_height),
+ fill=1, width=LINE_WIDTH)
+
+ # Month-Tally-Overview
+ #Only show if the Aperture decorations are to be shown
+ if APERTURE_DECORATIONS:
+ current_height += PADDING_TOP
+ tally_height = height/40
+ tally_width = LINE_WIDTH + width/120 # width + padding
+ available_width = width - PADDING_L
+ tally_number = int(available_width / tally_width *
+ (day_number / max_days_in_month))
+ x_position = PADDING_L + LINE_WIDTH/2
+ for i in range(0, tally_number):
+ draw_blk.line((x_position, current_height, x_position,
+ current_height + tally_height), fill=1, width=LINE_WIDTH)
+ x_position += tally_width
+ current_height += tally_height
+
+
+
+ # schedule
+
+ #Font Heights
+ event_calendar_font_height = get_font_height(EVENT_CALENDAR_FONT)
+ event_name_font_height = get_font_height(EVENT_NAME_FONT, withDescender = True)
+
+ #Line height
+ line_height = event_name_font_height * 1.0
+
+ #Stores the coordinate for later calculate the number of events to get
+ calendar_start_height = current_height
+ #Last line position of the calendar
+ #If the aperture science is hidden this line will be at the bottom
+ calendar_end_height = height*0.73 if APERTURE_DECORATIONS else height-vertical_margin
+
+ #Get the max number of event lines. Some of them will be later the days but the excess will be filtered out
+ available_events_lines = int((calendar_end_height - calendar_start_height)/line_height)
+ #Events
+ event_list = get_events(available_events_lines)
+
+ #Calendar names
+ calendar_names = {event.calendar_name for event in event_list}
+
+ #Get the width available to each calendar. Will not be more than 25% of the available area
+ max_calendar_name_width = width*0.25
+
+ calendar_names_width = {}
+ calendar_names_fitted = {}
+
+ #Iterate for each calendar name and checks if will fits in the max_calendar_name_width.
+ #If not will trim the last letter until it fits (with an …)
+ for calendar_name in calendar_names:
+ name_to_test = calendar_name
+ text_width = get_font_width(EVENT_CALENDAR_FONT, name_to_test)
+
+ while len(name_to_test) > 0 and text_width > max_calendar_name_width:
+ name_to_test = name_to_test[:-1]
+ text_width = get_font_width(EVENT_CALENDAR_FONT, name_to_test + "…")
+
+ calendar_names_fitted[calendar_name] = name_to_test + "…" if calendar_name != name_to_test else name_to_test
+ calendar_names_width[calendar_name] = text_width
+
+
+ calendar_names_width = {name:min(get_font_width(EVENT_CALENDAR_FONT, name), max_calendar_name_width) for name in calendar_names}
+
+
+ last_event_day = datetime.now().date()
+
+ #Distance between the time and the summary
+ column_spacing = 10
+
+
+ #Size of the times (they are monospaced)
+ event_start_time_width = get_font_width(EVENT_TIME_FONT, "00:00")
+ event_end_time_width = get_font_width(EVENT_TIME_SECONDARY_FONT, "00:00")
+
+ #Calculates the size of the text plus the padding, assuming a monospaced font for the times
+ end_date_padding = event_start_time_width + column_spacing/2 + event_end_time_width
+ summmary_padding = end_date_padding + column_spacing
+
+
+ #New line
+ current_height += line_height
+
+ #current calendar for drawing id lines
+ event_to_draw = None
+ current_event_height_start = None
+
+ #Size of the event font descender to correct the calendars vertical lines.
+ event_font_ascent , event_font_descent = EVENT_NAME_FONT.getmetrics()
+
+ #Vertical padding to separate each vertical line identifying a calendar
+ event_line_vertical_padding = 2
+
+ #Start the loop to write each event
+ for event in event_list:
+
+ #Calendar Lines
+ #Draw the lines that identify areas with same calendar.
+ #Note: As the text is aligned by its baseline all the vertical points have to be shifted dow by the size of the descending of the fon
+ if current_event_height_start == None:
+ event_to_draw = event
+ current_event_height_start = current_height - event_name_font_height + event_font_descent + event_line_vertical_padding
+
+ elif (event.calendar_name != event_to_draw.calendar_name or last_event_day != event.start.date()) and event_to_draw != None:
+ current_event_height_stop = current_height - line_height + event_font_descent - event_line_vertical_padding
+
+ #draw_blk.rectangle([(PADDING_L-CALENDAR_LINE_WIDTH-column_spacing, current_event_height_start), (PADDING_L-column_spacing, current_event_height_stop)], fill=1)
+ draw_pattern(
+ Pattern[event_to_draw.pattern_fill],
+ draw_blk,
+ draw_red,
+ (PADDING_L-CALENDAR_LINE_WIDTH-column_spacing, current_event_height_start),
+ (PADDING_L-column_spacing, current_event_height_stop),
+ use_red = event_to_draw.pattern_red_stripes,
+ )
+
+ event_to_draw = event
+ current_event_height_start = current_height - event_name_font_height + event_font_descent + event_line_vertical_padding
+
+ #Stops the for cycle if the new line will be outside the bounds or is day name/number after it is outside the bounds
+ #Use 1.5 times the line size to do a bit of padding.
+ if current_height + line_height * 0.5 > calendar_end_height or (last_event_day != event.start.date() and current_height + line_height * 1.5 > calendar_end_height):
+ #Finish drawing the calendar line
+
+ #get the height of the last line
+ current_event_height_stop = current_height + event_font_descent - line_height - event_line_vertical_padding
+
+ #if this height is superior of the stored line start height it will draw the line
+ #Otherwise a new line was to be started and was to be drawn
+ if current_event_height_stop >= current_event_height_start:
+ draw_pattern(
+ Pattern[event_to_draw.pattern_fill],
+ draw_blk,
+ draw_red,
+ (PADDING_L-CALENDAR_LINE_WIDTH-column_spacing, current_event_height_start),
+ (PADDING_L-column_spacing, current_event_height_stop),
+ use_red = event_to_draw.pattern_red_stripes,
+ )
+ #Stops writting more calendar events
+ break
+
+
+ # Draw new day
+ if last_event_day != event.start.date():
+ # current_height += height/40
+ last_event_day = event.start.date()
+ # day_string = "{} {}".format(last_event_day.day,
+ # last_event_day.strftime("%a"))
+ day_string = last_event_day.strftime("%A %-d")#.upper()
+
+ ##Halftoned day text
+ #draw_black_red_white_text(draw_blk, draw_red, text=day_string, position=(PADDING_L, current_height), font=FONT_ROBOTO_P, black_density=0.2, red_density=0.8, white_density=0.0)
+ #draw_blk.text((PADDING_L, current_height), day_string, font=FONT_ROBOTO_P, fill=0, stroke_width=1, stroke_fill=1)
+ draw_red.text((PADDING_L, current_height), day_string, font=FONT_ROBOTO_P, fill=1, anchor="ls", stroke_width=0, stroke_fill=0)
+ #draw_blk.text((PADDING_L, current_height), day_string, font=FONT_ROBOTO_P, fill=1)
+
+ #New Line
+ current_height += line_height
+
+ #Resets the vertical line placement
+ event_to_draw = event
+ current_event_height_start = current_height - event_name_font_height + event_font_descent
+
+ # Draw event
+ event_text = ""
+
+ #Event Start Date
+ if event.all_day:
+ draw_blk.text((PADDING_L+event_start_time_width, current_height), "- : -",
+ font=EVENT_TIME_FONT, anchor="rs", fill=1)
+ elif event.start.date() < last_event_day:
+ #If the date to end is before this date will only show the day, but in red
+ draw_red.text((PADDING_L+event_start_time_width, current_height), event.start.strftime("%a%d").replace("0", "O"),
+ font=EVENT_TIME_FONT, anchor="rs",fill=1)
+ else:
+ draw_blk.text((PADDING_L+event_start_time_width, current_height), event.start.strftime("%H:%M").replace("0", "O"),
+ font=EVENT_TIME_FONT, anchor="rs", fill=1)
+
+ #Event End Date
+ if event.all_day:
+ draw_blk.text((PADDING_L+end_date_padding, current_height), "- : -",
+ font=EVENT_TIME_SECONDARY_FONT, anchor="rs",fill=1)
+ elif event.end.date() > last_event_day:
+ #If the date to end is after today will only show the day, but in red
+ draw_red.text((PADDING_L+end_date_padding, current_height), event.end.strftime("%a%d").replace("0", "O"),
+ font=EVENT_TIME_SECONDARY_FONT, anchor="rs",fill=1)
+ else:
+ draw_blk.text((PADDING_L+end_date_padding, current_height), event.end.strftime("%H:%M").replace("0", "O"),
+ font=EVENT_TIME_SECONDARY_FONT, anchor="rs", fill=1)
+
+ #Title
+ #Will test if the text fits in the available space. If not wil trim it char by char, appending a ... until it does
+
+ #Get the available space
+ #If there is only one clanedar he will not be displayed and there will more space
+ calendar_name_space = column_spacing + calendar_names_width[event.calendar_name] if len(calendar_names) > 1 else 0
+ available_space = width - (PADDING_L + summmary_padding + calendar_name_space + PADDING_R)
+
+ #WiLl store the text to display
+ trimmed_event_summary = event.summary
+ #Will store the width of the text
+ trimmed_event_summary_width = get_font_width(EVENT_NAME_FONT, trimmed_event_summary)
+
+ #Text if the text is too big (or already empy)
+ while len(trimmed_event_summary) > 0 and trimmed_event_summary_width > available_space:
+ #If too big will trim it and test it again
+ trimmed_event_summary = trimmed_event_summary[:-1]
+ trimmed_event_summary_width = get_font_width(EVENT_NAME_FONT, trimmed_event_summary + "…")
+
+ #If the text was changed will append a ...
+ if trimmed_event_summary != event.summary:
+ trimmed_event_summary = trimmed_event_summary + "…"
+
+ #Display the adjusted text
+ draw_blk.text((PADDING_L + summmary_padding, current_height), trimmed_event_summary,
+ font=EVENT_NAME_FONT, anchor="ls", fill=1)
+
+ if len(calendar_names) > 1:
+ #Calendar Name (padded to the right and using a fitted name defined above to make sure that won't occupies more space that available, as defined by max_calendar_name_width)
+ #Will only be shown if there is more than one calendar
+ draw_blk.text((PADDING_R_COORDINATE, current_height), calendar_names_fitted[event.calendar_name],
+ font=EVENT_CALENDAR_FONT, anchor="rs", fill=1)
+
+ #Next line location
+ current_height += line_height
+
+
+ #Draw the last line of the calendar
+ current_height = calendar_end_height
+ draw_blk.line((PADDING_L, current_height, width, current_height),
+ fill=1, width=LINE_WIDTH)
+
+
+ #Only show Aperture Images if the user wants
+ if APERTURE_DECORATIONS:
+ current_height += PADDING_TOP
+ # Portal-Icons
+ y = PADDING_L
+ bithday_persons = get_birthdays()
+ draw_cake = (len(bithday_persons) > 0)
+ max_image_height = 0
+ for image in get_portal_images(draw_cake, bool(random.getrandbits(1)), bool(random.getrandbits(1)), bool(random.getrandbits(1))):
+ image_blk.paste(image, (y, int(current_height)))
+ image_width, image_height = image.size
+ y += image_width + PADDING_TOP
+ max_image_height = image_height if (
+ image_height > max_image_height) else max_image_height
+
+ current_height += max_image_height + PADDING_TOP
+
+ # Draw name of birthday-person
+ if draw_cake:
+ bithday_person_string = ", ".join(bithday_persons)
+ draw_red.text((PADDING_L, int(current_height)), bithday_person_string,
+ font=FONT_ROBOTO_P, fill=1)
+ current_height += get_font_height(FONT_ROBOTO_P)
+
+
+ #Footnote with data
+ #Will print current date and hour for update reference
+ now = datetime.now()
+ draw_blk.text((PADDING_R_COORDINATE, height), now.strftime('%x')+" "+now.strftime('%X'),
+ font=FOOTNOTE_FONT, anchor="rd", fill=1)
+
+ #BATTERY LEVELS
+ #Will show a red empty battery for charging when the battery is more empty
+ bus = SMBus(1)
+ # 1 Integer part for input voltage, 2 Decimal part (multiple 100 times) for input voltage
+ battery_voltage = float(bus.read_byte_data(8, 1) + bus.read_byte_data(8, 2)/100)
+ #7 Power mode: Power via LDO regulator = 1, Input 5V via USB Type C = 0
+ is_charging = bus.read_byte_data(8, 7) == 0
+ bus.close()
+
+ try:
+ should_recharge = battery_voltage <= RECHARGE_VOlTAGE
+ except:
+ should_recharge = false
+
+
+ if should_recharge:
+ image_bat = Image.open(os.path.join(PICTURE_DICT, "battery-icon-1_3.bmp"))
+
+ _, height = image_bat.size
+ image_vertical_padding = abs(round((vertical_margin-height)/2))
+ image_red.paste(image_bat, (PADDING_L, image_vertical_padding))
+ image_bat.close()
+
+ #A more compreensive battery status icons
+ #
+# print_bat_red = False
+# if is_charging:
+# # print a charging icon
+# bat_file = "battery-icon-charging.bmp"
+# elif should_recharge:
+# # Print a low charge icon in red
+# bat_file = "battery-icon-1_3.bmp"
+# print_bat_red = True
+# else:
+# # Batt full
+# bat_file = "battery-icon-3_3.bmp"
+#
+# #Battery charge:
+# #Only show a low bat indicator when in battery and its depleted.
+# #Get for the registers 1 and 2
+# image_bat = Image.open(os.path.join(PICTURE_DICT, bat_file))
+#
+# _, height = image_bat.size
+# image_vertical_padding = abs(round((vertical_margin-height)/2))
+#
+# if print_bat_red:
+# image_red.paste(image_bat, (PADDING_L, image_vertical_padding))
+# else:
+# image_blk.paste(image_bat, (PADDING_L, image_vertical_padding))
+#
+# image_bat.close()
def show_content(epd: eInk.EPD, image_blk: TImage, image_red: TImage):
- logger.info("Exporting finial images")
- image_blk.save("EXPORT-black.bmp")
- image_red.save("EXPORT-red.bmp")
- if ROTATE_IMAGE:
- image_blk = image_blk.rotate(180)
- image_red = image_red.rotate(180)
- if not DEBUG:
- init_display(epd)
- logger.info("Writing on display")
- epd.display(epd.getbuffer(image_blk), epd.getbuffer(image_red))
- set_sleep(epd)
+ logger.info("Exporting final images")
+ image_blk.save("EXPORT-black.bmp")
+ image_red.save("EXPORT-red.bmp")
+ if ROTATE_IMAGE:
+ image_blk = image_blk.rotate(180)
+ image_red = image_red.rotate(180)
+ if not DEBUG:
+ init_display(epd)
+ logger.info("Writing on display")
+ epd.display(epd.getbuffer(image_blk), epd.getbuffer(image_red))
+ set_sleep(epd)
def clear_content(epd: eInk.EPD):
- if DEBUG:
- logger.warning("Clear has no effect while debugging")
- else:
- init_display(epd)
- clear_display(epd)
- set_sleep(epd)
+ if DEBUG:
+ logger.warning("Clear has no effect while debugging")
+ else:
+ init_display(epd)
+ clear_display(epd)
+ set_sleep(epd)
if __name__ == '__main__':
- main()
+ main()
diff --git a/displayTest.py b/displayTest.py
index ac5657a..578f4ca 100644
--- a/displayTest.py
+++ b/displayTest.py
@@ -23,8 +23,8 @@ def clearDisplay():
epd.init()
epd.Clear()
- image = Image.open(os.path.join(pictureDict, 'Weihnachsbaum-b.bmp'))
- image_red = Image.open(os.path.join(pictureDict, 'Weihnachsbaum-r.bmp'))
+ image = Image.open(os.path.join(pictureDict, 'ChristmasTree-b.bmp'))
+ image_red = Image.open(os.path.join(pictureDict, 'ChristmasTree-r.bmp'))
epd.display(epd.getbuffer(image), epd.getbuffer(image_red))
time.sleep(10)
diff --git a/fonts/DejaVuSans-Bold.ttf b/fonts/DejaVuSans-Bold.ttf
new file mode 100644
index 0000000..6d65fa7
Binary files /dev/null and b/fonts/DejaVuSans-Bold.ttf differ
diff --git a/fonts/DejaVuSans.ttf b/fonts/DejaVuSans.ttf
new file mode 100644
index 0000000..e5f7eec
Binary files /dev/null and b/fonts/DejaVuSans.ttf differ
diff --git a/fonts/DejaVuSansCondensed-Bold.ttf b/fonts/DejaVuSansCondensed-Bold.ttf
new file mode 100644
index 0000000..22987c6
Binary files /dev/null and b/fonts/DejaVuSansCondensed-Bold.ttf differ
diff --git a/fonts/DejaVuSansCondensed.ttf b/fonts/DejaVuSansCondensed.ttf
new file mode 100644
index 0000000..3259bc2
Binary files /dev/null and b/fonts/DejaVuSansCondensed.ttf differ
diff --git a/fonts/DejaVuSansMono-Bold.ttf b/fonts/DejaVuSansMono-Bold.ttf
new file mode 100644
index 0000000..8184ced
Binary files /dev/null and b/fonts/DejaVuSansMono-Bold.ttf differ
diff --git a/fonts/DejaVuSansMono.ttf b/fonts/DejaVuSansMono.ttf
new file mode 100644
index 0000000..f578602
Binary files /dev/null and b/fonts/DejaVuSansMono.ttf differ
diff --git a/fonts/NotoEmoji-Bold.ttf b/fonts/NotoEmoji-Bold.ttf
new file mode 100644
index 0000000..bd4224b
Binary files /dev/null and b/fonts/NotoEmoji-Bold.ttf differ
diff --git a/fonts/NotoEmoji-Regular.ttf b/fonts/NotoEmoji-Regular.ttf
new file mode 100644
index 0000000..5c902c0
Binary files /dev/null and b/fonts/NotoEmoji-Regular.ttf differ
diff --git a/fonts/Poppins-Bold.ttf b/fonts/Poppins-Bold.ttf
deleted file mode 100644
index b94d47f..0000000
Binary files a/fonts/Poppins-Bold.ttf and /dev/null differ
diff --git a/fonts/Poppins-Light.ttf b/fonts/Poppins-Light.ttf
deleted file mode 100644
index 2ab0221..0000000
Binary files a/fonts/Poppins-Light.ttf and /dev/null differ
diff --git a/fonts/Poppins-Regular.ttf b/fonts/Poppins-Regular.ttf
deleted file mode 100644
index be06e7f..0000000
Binary files a/fonts/Poppins-Regular.ttf and /dev/null differ
diff --git a/fonts/Roboto-Black.ttf b/fonts/Roboto-Black.ttf
deleted file mode 100644
index 86ec2b2..0000000
Binary files a/fonts/Roboto-Black.ttf and /dev/null differ
diff --git a/fonts/Roboto-Bold.ttf b/fonts/Roboto-Bold.ttf
deleted file mode 100644
index 91ec212..0000000
Binary files a/fonts/Roboto-Bold.ttf and /dev/null differ
diff --git a/fonts/Roboto-Licence.txt b/fonts/Roboto-Licence.txt
deleted file mode 100644
index 9b82742..0000000
--- a/fonts/Roboto-Licence.txt
+++ /dev/null
@@ -1,204 +0,0 @@
-All used Roboto-* fonts are protected under the following licence:
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
\ No newline at end of file
diff --git a/hardware/Battery samsung inr18650-35e/Technical Report325.pdf b/hardware/Battery samsung inr18650-35e/Technical Report325.pdf
new file mode 100644
index 0000000..01557ae
Binary files /dev/null and b/hardware/Battery samsung inr18650-35e/Technical Report325.pdf differ
diff --git a/hardware/Battery samsung inr18650-35e/samsung-35e-datasheet-inr18650-35e.pdf b/hardware/Battery samsung inr18650-35e/samsung-35e-datasheet-inr18650-35e.pdf
new file mode 100644
index 0000000..8dad9ae
Binary files /dev/null and b/hardware/Battery samsung inr18650-35e/samsung-35e-datasheet-inr18650-35e.pdf differ
diff --git a/hardware/E-Paper Driver HAT/E-Paper Driver HAT - Waveshare Wiki.pdf b/hardware/E-Paper Driver HAT/E-Paper Driver HAT - Waveshare Wiki.pdf
new file mode 100644
index 0000000..14b31fa
Binary files /dev/null and b/hardware/E-Paper Driver HAT/E-Paper Driver HAT - Waveshare Wiki.pdf differ
diff --git a/hardware/E-Paper Driver HAT/E-Paper_Driver_HAT.pdf b/hardware/E-Paper Driver HAT/E-Paper_Driver_HAT.pdf
new file mode 100644
index 0000000..fdfd6bd
Binary files /dev/null and b/hardware/E-Paper Driver HAT/E-Paper_Driver_HAT.pdf differ
diff --git a/hardware/E-Paper Driver HAT/E-paper-driver-hat-user-manual.pdf b/hardware/E-Paper Driver HAT/E-paper-driver-hat-user-manual.pdf
new file mode 100644
index 0000000..48cd5c9
Binary files /dev/null and b/hardware/E-Paper Driver HAT/E-paper-driver-hat-user-manual.pdf differ
diff --git "a/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch e-Paper HAT (B) Manual - Waveshare Wiki.pdf" "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch e-Paper HAT (B) Manual - Waveshare Wiki.pdf"
new file mode 100644
index 0000000..5ed906f
Binary files /dev/null and "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch e-Paper HAT (B) Manual - Waveshare Wiki.pdf" differ
diff --git "a/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch-e-paper-b-v3-specification.pdf" "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch-e-paper-b-v3-specification.pdf"
new file mode 100644
index 0000000..c60f3cd
Binary files /dev/null and "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/7.5inch-e-paper-b-v3-specification.pdf" differ
diff --git "a/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/E-Paper-Driver-HAT-Schematic.pdf" "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/E-Paper-Driver-HAT-Schematic.pdf"
new file mode 100644
index 0000000..4d77bb9
Binary files /dev/null and "b/hardware/Waveshare 800\303\227480 7.5inch E-Ink display - 13505/E-Paper-Driver-HAT-Schematic.pdf" differ
diff --git a/hardware/Witty Pi 4 L3V7/WittyPi4L3V7_UserManual.pdf b/hardware/Witty Pi 4 L3V7/WittyPi4L3V7_UserManual.pdf
new file mode 100644
index 0000000..3ca7494
Binary files /dev/null and b/hardware/Witty Pi 4 L3V7/WittyPi4L3V7_UserManual.pdf differ
diff --git a/hardware/Witty Pi 4 L3V7/install to use as a reference if needed.sh b/hardware/Witty Pi 4 L3V7/install to use as a reference if needed.sh
new file mode 100644
index 0000000..528371d
--- /dev/null
+++ b/hardware/Witty Pi 4 L3V7/install to use as a reference if needed.sh
@@ -0,0 +1,160 @@
+[ -z $BASH ] && { exec bash "$0" "$@" || exit; }
+#!/bin/bash
+# file: install.sh
+#
+# This script will install required software for Witty Pi.
+# It is recommended to run it in your home directory.
+#
+
+# check if sudo is used
+if [ "$(id -u)" != 0 ]; then
+ echo 'Sorry, you need to run this script with sudo'
+ exit 1
+fi
+
+# target directory
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/wittypi"
+
+# error counter
+ERR=0
+
+# config file
+if [ "$(lsb_release -si)" == "Ubuntu" ]; then
+ # Ubuntu
+ BOOT_CONFIG_FILE="/boot/firmware/usercfg.txt"
+else
+ # Raspberry Pi OS ("$(lsb_release -si)" == "Debian") and others
+ if [ -e /boot/firmware/config.txt ] ; then
+ BOOT_CONFIG_FILE="/boot/firmware/config.txt"
+ else
+ BOOT_CONFIG_FILE="/boot/config.txt"
+ fi
+fi
+
+echo '================================================================================'
+echo '| |'
+echo '| Witty Pi Software Installation Script |'
+echo '| |'
+echo '================================================================================'
+
+# enable I2C on Raspberry Pi
+echo '>>> Enable I2C'
+if grep -q 'i2c-bcm2708' /etc/modules; then
+ echo 'Seems i2c-bcm2708 module already exists, skip this step.'
+else
+ echo 'i2c-bcm2708' >> /etc/modules
+fi
+if grep -q 'i2c-dev' /etc/modules; then
+ echo 'Seems i2c-dev module already exists, skip this step.'
+else
+ echo 'i2c-dev' >> /etc/modules
+fi
+
+i2c1=$(grep 'dtparam=i2c1=on' ${BOOT_CONFIG_FILE})
+i2c1=$(echo -e "$i2c1" | sed -e 's/^[[:space:]]*//')
+if [[ -z "$i2c1" || "$i2c1" == "#"* ]]; then
+ echo 'dtparam=i2c1=on' >> ${BOOT_CONFIG_FILE}
+else
+ echo 'Seems i2c1 parameter already set, skip this step.'
+fi
+
+i2c_arm=$(grep 'dtparam=i2c_arm=on' ${BOOT_CONFIG_FILE})
+i2c_arm=$(echo -e "$i2c_arm" | sed -e 's/^[[:space:]]*//')
+if [[ -z "$i2c_arm" || "$i2c_arm" == "#"* ]]; then
+ echo 'dtparam=i2c_arm=on' >> ${BOOT_CONFIG_FILE}
+else
+ echo 'Seems i2c_arm parameter already set, skip this step.'
+fi
+
+miniuart=$(grep 'dtoverlay=miniuart-bt' ${BOOT_CONFIG_FILE})
+miniuart=$(echo -e "$miniuart" | sed -e 's/^[[:space:]]*//')
+if [[ -z "$miniuart" || "$miniuart" == "#"* ]]; then
+ echo 'dtoverlay=miniuart-bt' >> ${BOOT_CONFIG_FILE}
+else
+ echo 'Seems setting Bluetooth to use mini-UART is done already, skip this step.'
+fi
+
+if [ -f /etc/modprobe.d/raspi-blacklist.conf ]; then
+ sed -i 's/^blacklist spi-bcm2708/#blacklist spi-bcm2708/' /etc/modprobe.d/raspi-blacklist.conf
+ sed -i 's/^blacklist i2c-bcm2708/#blacklist i2c-bcm2708/' /etc/modprobe.d/raspi-blacklist.conf
+else
+ echo 'File raspi-blacklist.conf does not exist, skip this step.'
+fi
+
+# install i2c-tools
+echo '>>> Install i2c-tools'
+if hash i2cget 2>/dev/null; then
+ echo 'Seems i2c-tools is installed already, skip this step.'
+else
+ apt install -y i2c-tools || ((ERR++))
+fi
+
+# make sure en_GB.UTF-8 locale is installed
+echo '>>> Make sure en_GB.UTF-8 locale is installed'
+locale_commentout=$(sed -n 's/\(#\).*en_GB.UTF-8 UTF-8/1/p' /etc/locale.gen)
+if [[ $locale_commentout -ne 1 ]]; then
+ echo 'Seems en_GB.UTF-8 locale has been installed, skip this step.'
+else
+ sed -i.bak 's/^.*\(en_GB.UTF-8[[:blank:]]\+UTF-8\)/\1/' /etc/locale.gen
+ locale-gen
+fi
+
+# install wiringPi
+if hash gpio 2>/dev/null; then
+ echo 'Seems wiringPi has been installed, skip this step.'
+else
+ os=$(lsb_release -r | grep 'Release:' | sed 's/Release:\s*//')
+ if [ $os -le 10 ]; then
+ apt install -y wiringpi || ((ERR++))
+ elif [ $os -eq 11 ]; then
+ wget https://github.com/WiringPi/WiringPi/releases/download/3.2/wiringpi_3.2-bullseye_armhf.deb -O wiringpi.deb || ((ERR++))
+ apt install -y ./wiringpi.deb || ((ERR++))
+ rm wiringpi.deb
+ else
+ arch=$(dpkg --print-architecture)
+ if [ "$arch" == "arm64" ]; then
+ wget https://github.com/WiringPi/WiringPi/releases/download/3.2/wiringpi_3.2_arm64.deb -O wiringpi.deb || ((ERR++))
+ else
+ wget https://github.com/WiringPi/WiringPi/releases/download/3.2/wiringpi_3.2_armhf.deb -O wiringpi.deb || ((ERR++))
+ fi
+ apt install -y ./wiringpi.deb || ((ERR++))
+ rm wiringpi.deb
+ fi
+fi
+
+# install wittyPi
+if [ $ERR -eq 0 ]; then
+ echo '>>> Install wittypi'
+ if [ -d "wittypi" ]; then
+ echo 'Seems wittypi is installed already, skip this step.'
+ else
+ wget https://www.uugear.com/repo/WittyPi4/LATEST -O wittyPi.zip || ((ERR++))
+ unzip wittyPi.zip -d wittypi || ((ERR++))
+ cd wittypi
+ chmod +x wittyPi.sh
+ chmod +x daemon.sh
+ chmod +x runScript.sh
+ chmod +x beforeScript.sh
+ chmod +x afterStartup.sh
+ chmod +x beforeShutdown.sh
+ sed -e "s#/home/pi/wittypi#$DIR#g" init.sh >/etc/init.d/wittypi
+ chmod +x /etc/init.d/wittypi
+ update-rc.d wittypi defaults || ((ERR++))
+ touch wittyPi.log
+ touch schedule.log
+ cd ..
+ chown -R $SUDO_USER:$(id -g -n $SUDO_USER) wittypi || ((ERR++))
+ sleep 2
+ rm wittyPi.zip
+ fi
+fi
+
+# install UUGear Web Interface
+curl https://www.uugear.com/repo/UWI/installUWI.sh | bash
+
+echo
+if [ $ERR -eq 0 ]; then
+ echo '>>> All done. Please reboot your Pi :-)'
+else
+ echo '>>> Something went wrong. Please check the messages above :-('
+fi
diff --git a/hardware/Witty Pi 4 L3V7/runScript.sh b/hardware/Witty Pi 4 L3V7/runScript.sh
new file mode 100755
index 0000000..d8fc40c
--- /dev/null
+++ b/hardware/Witty Pi 4 L3V7/runScript.sh
@@ -0,0 +1,203 @@
+#!/bin/bash
+# file: runScript.sh
+#
+# This script will run automatically after startup, and make next schedule
+# according to the "schedule.wpi" script file
+#
+
+# delay if first argument exists
+if [ ! -z "$1" ]; then
+ sleep $1
+fi
+
+# get current directory and schedule file path
+cur_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+schedule_file="$cur_dir/schedule.wpi"
+
+# utilities
+. "$cur_dir/utilities.sh"
+
+# pending until system time gets initialized
+while [[ "$(date +%Y)" == *"1969"* ]] || [[ "$(date +%Y)" == *"1970"* ]]; do
+ sleep 1
+done
+
+# get current timestamp
+cur_time=$(current_timestamp)
+echo "--------------- $(date -d @$cur_time +'%Y-%m-%d %H:%M:%S') ---------------"
+
+extract_timestamp()
+{
+ IFS=' ' read -r point date timestr <<< $1
+ local date_reg='(20[1-9][0-9])-([0-9][0-9])-([0-3][0-9])'
+ local time_reg='([0-2][0-9]):([0-5][0-9]):([0-5][0-9])'
+ if [[ $date =~ $date_reg ]] && [[ $timestr =~ $time_reg ]] ; then
+ echo $(date -d "$date $timestr" +%s)
+ else
+ echo 0
+ fi
+}
+
+extract_duration()
+{
+ local duration=0
+ local day_reg='D([0-9]+)'
+ local hour_reg='H([0-9]+)'
+ local min_reg='M([0-9]+)'
+ local sec_reg='S([0-9]+)'
+ IFS=' ' read -a parts <<< $*
+ for part in "${parts[@]}"
+ do
+ if [[ $part =~ $day_reg ]] ; then
+ duration=$((duration+${BASH_REMATCH[1]}*86400))
+ elif [[ $part =~ $hour_reg ]] ; then
+ duration=$((duration+${BASH_REMATCH[1]}*3600))
+ elif [[ $part =~ $min_reg ]] ; then
+ duration=$((duration+${BASH_REMATCH[1]}*60))
+ elif [[ $part =~ $sec_reg ]] ; then
+ duration=$((duration+${BASH_REMATCH[1]}))
+ fi
+ done
+ echo $duration
+}
+
+setup_off_state()
+{
+ local res=$(check_sys_and_rtc_time)
+ if [ ! -z "$res" ]; then
+ log "$res"
+ fi
+ log "Schedule next startup at: $(date -d @$1 +'%Y-%m-%d %H:%M:%S')"
+ local date=$(date -d "@$1" +"%d")
+ local hour=$(date -d "@$1" +"%H")
+ local minute=$(date -d "@$1" +"%M")
+ local second=$(date -d "@$1" +"%S")
+ set_startup_time $date $hour $minute $second
+}
+
+setup_on_state()
+{
+ local res=$(check_sys_and_rtc_time)
+ if [ ! -z "$res" ]; then
+ log "$res"
+ fi
+ log "Schedule next shutdown at: $(date -d @$1 +'%Y-%m-%d %H:%M:%S')"
+ local date=$(date -d "@$1" +"%d")
+ local hour=$(date -d "@$1" +"%H")
+ local minute=$(date -d "@$1" +"%M")
+ local second=$(date -d "@$1" +"%S")
+ set_shutdown_time $date $hour $minute $second
+}
+
+if [ -f $schedule_file ]; then
+ begin=0
+ end=0
+ count=0
+ while IFS='' read -r line || [[ -n "$line" ]]; do
+ cpos=`expr index "$line" \#`
+ if [ $cpos != 0 ]; then
+ line=${line:0:$cpos-1}
+ fi
+ line=$(trim "$line")
+ if [[ $line == BEGIN* ]]; then
+ begin=$(extract_timestamp "$line")
+ elif [[ $line == END* ]]; then
+ end=$(extract_timestamp "$line")
+ elif [ "$line" != "" ]; then
+ states[$count]=$(echo $line)
+ count=$((count+1))
+ fi
+ done < $schedule_file
+
+ if [ $begin == 0 ] ; then
+ log 'I can not find the begin time in the script...'
+ elif [ $end == 0 ] ; then
+ log 'I can not find the end time in the script...'
+ elif [ $count == 0 ] ; then
+ log 'I can not find any state defined in the script.'
+ else
+ if [ $((cur_time < begin)) == '1' ] ; then
+ cur_time=$begin
+ fi
+ if [ $((cur_time >= end)) == '1' ] ; then
+ log 'The schedule script has ended already.'
+ else
+ schedule_script_interrupted
+ interrupted=$? # should be 0 if scheduled startup is in the future and shutdown is in the pass
+ if [ ! -z "$2" ] && [ $interrupted == 0 ] ; then
+ log 'Schedule script is interrupted, revising the schedule...'
+ fi
+ index=0
+ found_states=0
+ check_time=$begin
+ script_duration=0
+ found_off=0
+ found_on=0
+ while [ $found_states != 2 ] && [ $((check_time < end)) == '1' ] ;
+ do
+ duration=$(extract_duration ${states[$index]})
+ check_time=$((check_time+duration))
+ if [ $found_off == 0 ] && [[ ${states[$index]} == OFF* ]] ; then
+ found_off=1
+ fi
+ if [ $found_on == 0 ] && [[ ${states[$index]} == ON* ]] ; then
+ found_on=1
+ fi
+ # find the current ON state and incoming OFF state
+ if [ $((check_time >= cur_time)) == '1' ] && ([ $found_states == 1 ] || [[ ${states[$index]} == ON* ]]) ; then
+ found_states=$((found_states+1))
+ if [[ ${states[$index]} == ON* ]]; then
+ if [[ ${states[$index]} == *WAIT ]]; then
+ log 'Skip scheduling next shutdown, which should be done externally.'
+ else
+ if [ ! -z "$2" ] && [ $interrupted == 0 ] ; then
+ # schedule a shutdown 1 minute before next startup
+ #NOTE: Edited to 10 minutes to have time for a propershutdown
+ setup_on_state $((check_time-duration-600))
+ else
+ setup_on_state $check_time
+ fi
+ fi
+ elif [[ ${states[$index]} == OFF* ]] ; then
+ if [[ ${states[$index]} == *WAIT ]]; then
+ log 'Skip scheduling next startup, which should be done externally.'
+ else
+ if [ ! -z "$2" ] && [ $interrupted == 0 ] && [ $index != 0 ] ; then
+ # jump back to previous OFF state
+ prev_state=${states[$((index-1))]}
+ prev_duration=$(extract_duration $prev_state)
+ setup_off_state $((check_time-duration-prev_duration))
+ else
+ setup_off_state $check_time
+ fi
+ fi
+ else
+ log "I can not recognize this state: ${states[$index]}"
+ fi
+ fi
+ index=$((index+1))
+ if [ $index == $count ] ; then
+ index=0
+ if [ $script_duration == 0 ] ; then
+ if [ $found_off == 0 ] ; then
+ log 'I need at least one OFF state in the script.'
+ check_time=$end # skip all remaining cycles
+ elif [ $found_on == 0 ] ; then
+ log 'I need at least one ON state in the script.'
+ check_time=$end # skip all remaining cycles
+ else
+ script_duration=$((check_time-begin))
+ skip=$((cur_time-check_time))
+ skip=$((skip-skip%script_duration))
+ check_time=$((check_time+skip)) # skip some useless cycles
+ fi
+ fi
+ fi
+ done
+ fi
+ fi
+else
+ log "File \"schedule.wpi\" not found, skip running schedule script."
+fi
+
+echo '---------------------------------------------------'
diff --git a/hardware/Witty Pi 4 L3V7/schedule.wpi b/hardware/Witty Pi 4 L3V7/schedule.wpi
new file mode 100644
index 0000000..42ddd7e
--- /dev/null
+++ b/hardware/Witty Pi 4 L3V7/schedule.wpi
@@ -0,0 +1,9 @@
+BEGIN 2024-09-01 07:00:00
+# Will not end (or at least in the following 40 years)
+END 2064-09-01 07:15:00
+#Will stay on 20 minutes (the displayRun.py has a timeout of 10 minutes for a network connection retry)
+ON M20
+#Will startup in about 6 hours (H6) in production.
+OFF H5 M40
+# For testing, allowing less time between boots you can use the following line (after commenting the previous)
+#OFF M15
diff --git a/hardware/Abdeckung.STL b/hardware/case/pi 3b/Abdeckung.STL
similarity index 100%
rename from hardware/Abdeckung.STL
rename to hardware/case/pi 3b/Abdeckung.STL
diff --git a/hardware/Front.STL b/hardware/case/pi 3b/Front.STL
similarity index 100%
rename from hardware/Front.STL
rename to hardware/case/pi 3b/Front.STL
diff --git a/hardware/case/pi zero/Abdeckungv2.stl b/hardware/case/pi zero/Abdeckungv2.stl
new file mode 100644
index 0000000..02dc8ee
Binary files /dev/null and b/hardware/case/pi zero/Abdeckungv2.stl differ
diff --git a/hardware/case/pi zero/Calendar Case Raspberry Pi zero v1.f3z b/hardware/case/pi zero/Calendar Case Raspberry Pi zero v1.f3z
new file mode 100644
index 0000000..5c0678c
Binary files /dev/null and b/hardware/case/pi zero/Calendar Case Raspberry Pi zero v1.f3z differ
diff --git a/hardware/case/pi zero/Frontv2.stl b/hardware/case/pi zero/Frontv2.stl
new file mode 100644
index 0000000..6a74885
Binary files /dev/null and b/hardware/case/pi zero/Frontv2.stl differ
diff --git a/hardware/case/pi zero/backcover.stl b/hardware/case/pi zero/backcover.stl
new file mode 100644
index 0000000..fc4d43b
Binary files /dev/null and b/hardware/case/pi zero/backcover.stl differ
diff --git a/lib b/lib
new file mode 120000
index 0000000..ef6a8ee
--- /dev/null
+++ b/lib
@@ -0,0 +1 @@
+submodules/waveshare_e-paper/RaspberryPi_JetsonNano/python/lib/waveshare_epd
\ No newline at end of file
diff --git a/lib 2 b/lib 2
new file mode 120000
index 0000000..ef6a8ee
--- /dev/null
+++ b/lib 2
@@ -0,0 +1 @@
+submodules/waveshare_e-paper/RaspberryPi_JetsonNano/python/lib/waveshare_epd
\ No newline at end of file
diff --git a/lib/__init__.py b/lib/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/__pycache__/__init__.cpython-37.pyc b/lib/__pycache__/__init__.cpython-37.pyc
deleted file mode 100644
index 1a58269..0000000
Binary files a/lib/__pycache__/__init__.cpython-37.pyc and /dev/null differ
diff --git a/lib/__pycache__/epd7in5_V2.cpython-37.pyc b/lib/__pycache__/epd7in5_V2.cpython-37.pyc
deleted file mode 100644
index 875c5b6..0000000
Binary files a/lib/__pycache__/epd7in5_V2.cpython-37.pyc and /dev/null differ
diff --git a/lib/__pycache__/epd7in5b_V2.cpython-37.pyc b/lib/__pycache__/epd7in5b_V2.cpython-37.pyc
deleted file mode 100644
index 71731c4..0000000
Binary files a/lib/__pycache__/epd7in5b_V2.cpython-37.pyc and /dev/null differ
diff --git a/lib/__pycache__/epd7in5bc.cpython-37.pyc b/lib/__pycache__/epd7in5bc.cpython-37.pyc
deleted file mode 100644
index 6294610..0000000
Binary files a/lib/__pycache__/epd7in5bc.cpython-37.pyc and /dev/null differ
diff --git a/lib/__pycache__/epdconfig.cpython-37.pyc b/lib/__pycache__/epdconfig.cpython-37.pyc
deleted file mode 100644
index 16b6e81..0000000
Binary files a/lib/__pycache__/epdconfig.cpython-37.pyc and /dev/null differ
diff --git a/lib/epd1in02.py b/lib/epd1in02.py
deleted file mode 100644
index 24f10a8..0000000
--- a/lib/epd1in02.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# ******************************************************************************/
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 80
-EPD_HEIGHT = 128
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- #full screen update LUT
-
- lut_w1 =[
- 0x60, 0x5A, 0x5A, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_b1 =[
- 0x90, 0x5A, 0x5A, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- # partial screen update LUT
- lut_w = [
- 0x60, 0x01, 0x01, 0x00, 0x00, 0x01,
- 0x80, 0x1f, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_b = [
- 0x90, 0x01, 0x01, 0x00, 0x00, 0x01,
- 0x40, 0x1f, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0) # module reset
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- busy =not(busy & 0x01)
- while(busy):
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- busy =not(busy & 0x01)
- epdconfig.delay_ms(800)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x12)
- epdconfig.delay_ms(10)
- self.ReadBusy()
-
- def SetFulltReg(self):
- self.send_command(0x23)
- for count in range(0, 42):
- self.send_data(self.lut_w1[count])
-
- self.send_command(0x24)
- for count in range(0, 42):
- self.send_data(self.lut_b1[count])
-
- def SetPartReg(self):
- self.send_command(0x23)
- for count in range(0, 42):
- self.send_data(self.lut_w[count])
-
- self.send_command(0x24)
- for count in range(0, 42):
- self.send_data(self.lut_b[count])
-
- def Init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0xD2)
- self.send_data(0x3F)
-
- self.send_command(0x00)
- self.send_data (0x6F) #from outside
-
- self.send_command(0x01) #power setting
- self.send_data (0x03)
- self.send_data (0x00)
- self.send_data (0x2b)
- self.send_data (0x2b)
-
- self.send_command(0x06) #Configuring the charge pump
- self.send_data(0x3f)
-
- self.send_command(0x2A) #Setting XON and the options of LUT
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x30) #Set the clock frequency
- self.send_data(0x17) #50Hz
-
- self.send_command(0x50) #Set VCOM and data output interval
- self.send_data(0x57)
-
- self.send_command(0x60) #Set The non-overlapping period of Gate and Source.
- self.send_data(0x22)
-
- self.send_command(0x61) #resolution setting
- self.send_data (0x50) #source 128
- self.send_data (0x80)
-
- self.send_command(0x82) #sets VCOM_DC value
- self.send_data(0x12) #-1v
-
- self.send_command(0xe3)#Set POWER SAVING
- self.send_data(0x33)
- self.SetFulltReg()
- self.send_command(0x04) #power on
- self.ReadBusy()
- # EPD hardware init end
- return 0
-
- def Partial_Init(self):
- self.reset()
-
- self.send_command(0xD2)
- self.send_data(0x3F)
-
- self.send_command(0x00)
- self.send_data (0x6F) #from outside
-
- self.send_command(0x01) #power setting
- self.send_data (0x03)
- self.send_data (0x00)
- self.send_data (0x2b)
- self.send_data (0x2b)
-
- self.send_command(0x06) #Configuring the charge pump
- self.send_data(0x3f)
-
- self.send_command(0x2A) #Setting XON and the options of LUT
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x30) #Set the clock frequency
- self.send_data(0x17)
-
- self.send_command(0x50) #Set VCOM and data output interval
- self.send_data(0xf2)
-
- self.send_command(0x60) #Set The non-overlapping period of Gate and Source.
- self.send_data(0x22)
-
- self.send_command(0x82) #Set VCOM_DC value
- self.send_data(0x12)#-1v
-
- self.send_command(0xe3)#Set POWER SAVING
- self.send_data(0x33)
-
- self.SetPartReg()
-
- self.send_command(0x04)#Set POWER SAVING
- self.ReadBusy()
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- buf = [0xFF] * (int(self.width / 8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def Display(self, image):
- if (image == None):
- return
- # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1)
- if(self.width % 8 == 0):
- Width = self.width / 8
- else:
- Width = self.width / 8 + 1
-
- self.send_command(0x10)
- for j in range(0, self.height):
- for i in range(0, int(Width)):
- self.send_data(0xff)
-
- self.send_command(0x13)
- for j in range(0, self.height):
- for i in range(0, int(Width)):
- self.send_data(image[i + j * int(Width)])
- self.TurnOnDisplay()
-
- def Clear(self):
- # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1)
- if(self.width % 8 == 0):
- Width = self.width / 8
- else:
- Width = self.width / 8 + 1
-
- Height = self.height
-
- self.send_command(0x10)
- for j in range(0, Height):
- for i in range(0, int(Width)):
- self.send_data(0x00)
-
- self.send_command(0x13)
- for j in range(0, Height):
- for i in range(0, int(Width)):
- self.send_data(0xff)
- self.TurnOnDisplay()
-
- def DisplayPartial(self, old_Image, Image):
-
- # Set partial Windows */
- self.send_command(0x91) #This command makes the display enter partial mode
- self.send_command(0x90) #resolution setting
- self.send_data(0) #x-start
- self.send_data(79) #x-end
-
- self.send_data(0)
- self.send_data(127) #y-end
- self.send_data(0x00)
-
- # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1)
- if(self.width % 8 == 0):
- Width = self.width / 8
- else:
- Width = self.width / 8 + 1
-
- Height = self.height
- # send data
- self.send_command(0x10)
- for j in range(0, Height):
- for i in range(0, int(Width)):
- self.send_data(old_Image[i + j * int(Width)])
-
- self.send_command(0x13)
- for j in range(0, Height):
- for i in range(0, int(Width)):
- self.send_data(Image[i + j * int(Width)])
-
- # Set partial refresh
- self.TurnOnDisplay()
-
- def Sleep(self):
- self.send_command(0x50)
- self.send_data(0xf7)
- self.send_command(0x02)
- self.ReadBusy()
- self.send_command(0x07)
- self.send_data(0xA5)
- epdconfig.delay_ms(200)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd1in54.py b/lib/epd1in54.py
deleted file mode 100644
index 4fdba04..0000000
--- a/lib/epd1in54.py
+++ /dev/null
@@ -1,260 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V3.1
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# V3.1(2019-06-18):
-# 2.remove commands define:
-# #define PANEL_SETTING 0x00
-# #define POWER_SETTING 0x01
-# #define POWER_OFF 0x02
-# #define POWER_OFF_SEQUENCE_SETTING 0x03
-# #define POWER_ON 0x04
-# #define POWER_ON_MEASURE 0x05
-# #define BOOSTER_SOFT_START 0x06
-# #define DEEP_SLEEP 0x07
-# #define DATA_START_TRANSMISSION_1 0x10
-# #define DATA_STOP 0x11
-# #define DISPLAY_REFRESH 0x12
-# #define DATA_START_TRANSMISSION_2 0x13
-# #define PLL_CONTROL 0x30
-# #define TEMPERATURE_SENSOR_COMMAND 0x40
-# #define TEMPERATURE_SENSOR_CALIBRATION 0x41
-# #define TEMPERATURE_SENSOR_WRITE 0x42
-# #define TEMPERATURE_SENSOR_READ 0x43
-# #define VCOM_AND_DATA_INTERVAL_SETTING 0x50
-# #define LOW_POWER_DETECTION 0x51
-# #define TCON_SETTING 0x60
-# #define TCON_RESOLUTION 0x61
-# #define SOURCE_AND_GATE_START_SETTING 0x62
-# #define GET_STATUS 0x71
-# #define AUTO_MEASURE_VCOM 0x80
-# #define VCOM_VALUE 0x81
-# #define VCM_DC_SETTING_REGISTER 0x82
-# #define PROGRAM_MODE 0xA0
-# #define ACTIVE_PROGRAM 0xA1
-# #define READ_OTP_DATA 0xA2
-# -----------------------------------------------------------------------------
-# V3.0(2018-11-01):
-# # 1.Remove:
-# digital_write(self, pin, value)
-# digital_read(self, pin)
-# delay_ms(self, delaytime)
-# set_lut(self, lut)
-# self.lut = self.lut_full_update
-# * 2.Change:
-# display_frame -> TurnOnDisplay
-# set_memory_area -> SetWindow
-# set_memory_pointer -> SetCursor
-# * 3.How to use
-# epd = epd1in54.EPD()
-# epd.init(epd.lut_full_update)
-# image = Image.new('1', (epd1in54.EPD_WIDTH, epd1in54.EPD_HEIGHT), 255)
-# ...
-# drawing ......
-# ...
-# epd.display(getbuffer(image))
-# ******************************************************************************/
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 200
-EPD_HEIGHT = 200
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_full_update = [
- 0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22,
- 0x66, 0x69, 0x69, 0x59, 0x58, 0x99, 0x99, 0x88,
- 0x00, 0x00, 0x00, 0x00, 0xF8, 0xB4, 0x13, 0x51,
- 0x35, 0x51, 0x51, 0x19, 0x01, 0x00
- ]
-
- lut_partial_update = [
- 0x10, 0x18, 0x18, 0x08, 0x18, 0x18, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0) # module reset
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xC4)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE
-
- self.ReadBusy()
-
- def SetWindow(self, x_start, y_start, x_end, y_end):
- self.send_command(0x44) # 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(0x45) # 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)
-
- def SetCursor(self, x, y):
- self.send_command(0x4E) # 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(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(y & 0xFF)
- self.send_data((y >> 8) & 0xFF)
- # self.ReadBusy()
-
- def init(self, lut):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # 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(0x0C) # BOOSTER_SOFT_START_CONTROL
- self.send_data(0xD7)
- self.send_data(0xD6)
- self.send_data(0x9D)
-
- self.send_command(0x2C) # WRITE_VCOM_REGISTER
- self.send_data(0xA8) # VCOM 7C
-
- self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD
- self.send_data(0x1A) # 4 dummy lines per gate
-
- self.send_command(0x3B) # SET_GATE_TIME
- self.send_data(0x08) # 2us per line
-
- self.send_command(0x11) # DATA_ENTRY_MODE_SETTING
- self.send_data(0x03) # X increment Y increment
-
- # set the look-up table register
- self.send_command(0x32)
- for i in range(0, len(lut)):
- self.send_data(lut[i])
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- buf = [0xFF] * (int(self.width / 8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- if (image == None):
- return
-
- self.SetWindow(0, 0, self.width, self.height)
- for j in range(0, self.height):
- self.SetCursor(0, j)
- self.send_command(0x24)
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
- self.TurnOnDisplay()
-
- def Clear(self, color):
- # self.SetWindow(0, 0, self.width - 1, self.height - 1)
- # send the color data
- self.SetWindow(0, 0, self.width, self.height)
- # epdconfig.digital_write(self.dc_pin, 1)
- # epdconfig.digital_write(self.cs_pin, 0)
- for j in range(0, self.height):
- self.SetCursor(0, j)
- self.send_command(0x24)
- for i in range(0, int(self.width / 8)):
- self.send_data(color)
- # epdconfig.digital_write(self.cs_pin, 1)
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0x10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd1in54_V2.py b/lib/epd1in54_V2.py
deleted file mode 100644
index b489d9a..0000000
--- a/lib/epd1in54_V2.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 200
-EPD_HEIGHT = 200
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # waveform full refresh
- WF_Full_1IN54 = [
- 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x80, 0x48, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x40, 0x48, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x8, 0x1, 0x0, 0x8, 0x1, 0x0, 0x2,
- 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
- 0x22, 0x17, 0x41, 0x0, 0x32, 0x20
- ]
-
- # waveform partial refresh(fast)
- WF_PARTIAL_1IN54_0 = [
- 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0xF,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x1,0x1,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
- 0x02,0x17,0x41,0xB0,0x32,0x28,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1):
- epdconfig.delay_ms(20)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xc7)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.ReadBusy()
-
- def TurnOnDisplayPart(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xcF)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.ReadBusy()
-
- def lut(self, lut):
- self.send_command(0x32) # WRITE_LUT_REGISTER
- for i in range(0, len(lut)):
- self.send_data(lut[i])
-
- def set_lut(self, lut):
- self.lut(lut)
-
- self.send_command(0x3f)
- self.send_data(lut[153])
-
- self.send_command(0x03)
- self.send_data(lut[154])
-
- self.send_command(0x04)
- self.send_data(lut[155])
- self.send_data(lut[156])
- self.send_data(lut[157])
-
- self.send_command(0x2c)
- self.send_data(lut[158])
-
- def SetWindows(self, Xstart, Ystart, Xend, Yend):
- self.send_command(0x44); # SET_RAM_X_ADDRESS_START_END_POSITION
- self.send_data((Xstart>>3) & 0xFF);
- self.send_data((Xend>>3) & 0xFF);
-
- self.send_command(0x45); # SET_RAM_Y_ADDRESS_START_END_POSITION
- self.send_data(Ystart & 0xFF);
- self.send_data((Ystart >> 8) & 0xFF);
- self.send_data(Yend & 0xFF);
- self.send_data((Yend >> 8) & 0xFF);
-
-
- def SetCursor(self, Xstart, Ystart):
- self.send_command(0x4E); # SET_RAM_X_ADDRESS_COUNTER
- self.send_data(Xstart & 0xFF);
-
- self.send_command(0x4F); # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(Ystart & 0xFF);
- self.send_data((Ystart >> 8) & 0xFF);
-
- def init(self, isPartial):
- if (epdconfig.module_init() != 0):
- return -1
-
- if(isPartial):
- logger.debug("partial refresh")
- self.reset()
- self.ReadBusy()
-
- self.set_lut(self.WF_PARTIAL_1IN54_0)
-
- self.send_command(0x37)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x40)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3c) # BorderWavefrom
- self.send_data(0x80)
-
- self.send_command(0x22)
- self.send_data(0xc0)
- self.send_command(0x20)
- self.ReadBusy()
-
- else:
- logger.debug("full refresh")
- # EPD hardware init start
- self.reset()
-
- self.ReadBusy()
- self.send_command(0x12) # SWRESET (software reset)
- self.ReadBusy()
-
- self.send_command(0x01) # DRIVER_OUTPUT_CONTROL
- self.send_data(0xC7) # (EPD_HEIGHT - 1) & 0xFF
- self.send_data(0x00) # ((EPD_HEIGHT - 1) >> 8) & 0xFF
- self.send_data(0x01) # GD = 0 SM = 0 TB = 0
-
- self.send_command(0x11) # data entry mode
- self.send_data(0x01)
-
- self.SetWindows(0, self.height-1, self.width-1, 0) # Set Windows
-
- self.send_command(0x3C) # BorderWavefrom
- self.send_data(0x01)
-
- self.send_command(0x18)
- self.send_data(0x80)
-
- self.send_command(0x22) # #Load Temperature and waveform setting.
- self.send_data(0XB1)
- self.send_command(0x20)
-
- self.SetCursor(0, self.height-1) # Set Cursor
-
- self.ReadBusy()
-
- self.set_lut(self.WF_Full_1IN54) # Set lut
-
- def Clear(self, color):
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(color)
-
- self.TurnOnDisplay()
-
- def getbuffer(self, image):
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- if (image == None):
- return
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
- self.TurnOnDisplay()
-
- def displayPartBaseImage(self, image):
- if (image == None):
- return
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.TurnOnDisplay()
-
- def displayPart(self, image):
- if (image == None):
- return
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.TurnOnDisplayPart()
-
- def sleep(self):
- self.send_command(0x10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd1in54b.py b/lib/epd1in54b.py
deleted file mode 100644
index fe8fa17..0000000
--- a/lib/epd1in54b.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54b.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 200
-EPD_HEIGHT = 200
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_vcom0 = [0x0E, 0x14, 0x01, 0x0A, 0x06, 0x04, 0x0A, 0x0A, 0x0F, 0x03, 0x03, 0x0C, 0x06, 0x0A, 0x00]
- lut_w = [0x0E, 0x14, 0x01, 0x0A, 0x46, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x86, 0x0A, 0x04]
- lut_b = [0x0E, 0x14, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x4A, 0x04]
- lut_g1 = [0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04]
- lut_g2 = [0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, 0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04]
- lut_vcom1 = [0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
- lut_red0 = [0x83, 0x5D, 0x01, 0x81, 0x48, 0x23, 0x77, 0x77, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
- lut_red1 = [0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0) # module reset
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0):
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def set_lut_bw(self):
- self.send_command(0x20) # vcom
- for count in range(0, 15):
- self.send_data(self.lut_vcom0[count])
- self.send_command(0x21) # ww --
- for count in range(0, 15):
- self.send_data(self.lut_w[count])
- self.send_command(0x22) # bw r
- for count in range(0, 15):
- self.send_data(self.lut_b[count])
- self.send_command(0x23) # wb w
- for count in range(0, 15):
- self.send_data(self.lut_g1[count])
- self.send_command(0x24) # bb b
- for count in range(0, 15):
- self.send_data(self.lut_g2[count])
-
- def set_lut_red(self):
- self.send_command(0x25)
- for count in range(0, 15):
- self.send_data(self.lut_vcom1[count])
- self.send_command(0x26)
- for count in range(0, 15):
- self.send_data(self.lut_red0[count])
- self.send_command(0x27)
- for count in range(0, 15):
- self.send_data(self.lut_red1[count])
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x07)
- self.send_data(0x00)
- self.send_data(0x08)
- self.send_data(0x00)
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0x07)
- self.send_data(0x07)
- self.send_data(0x07)
- self.send_command(0x04) # POWER_ON
-
- self.ReadBusy()
-
- self.send_command(0X00) # PANEL_SETTING
- self.send_data(0xCF)
- self.send_command(0X50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x17)
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x39)
- self.send_command(0x61) # TCON_RESOLUTION set x and y
- self.send_data(0xC8)
- self.send_data(0x00)
- self.send_data(0xC8)
- self.send_command(0x82) # VCM_DC_SETTING_REGISTER
- self.send_data(0x0E)
-
- self.set_lut_bw()
- self.set_lut_red()
- return 0
-
- def getbuffer(self, image):
- buf = [0xFF] * int(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[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- return buf
-
- def display(self, blackimage, redimage):
- # send black data
- if (blackimage != None):
- self.send_command(0x10) # DATA_START_TRANSMISSION_1
- for i in range(0, int(self.width * self.height / 8)):
- temp = 0x00
- for bit in range(0, 4):
- if (blackimage[i] & (0x80 >> bit) != 0):
- temp |= 0xC0 >> (bit * 2)
- self.send_data(temp)
- temp = 0x00
- for bit in range(4, 8):
- if (blackimage[i] & (0x80 >> bit) != 0):
- temp |= 0xC0 >> ((bit - 4) * 2)
- self.send_data(temp)
-
- # send red data
- if (redimage != None):
- self.send_command(0x13) # DATA_START_TRANSMISSION_2
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(redimage[i])
-
- self.send_command(0x12) # DISPLAY_REFRESH
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10) # DATA_START_TRANSMISSION_1
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- self.send_data(0xFF)
-
- self.send_command(0x13) # DATA_START_TRANSMISSION_2
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12) # DISPLAY_REFRESH
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x17)
- self.send_command(0x82) # to solve Vcom drop
- self.send_data(0x00)
- self.send_command(0x01) # power setting
- self.send_data(0x02) # gate switch to external
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.ReadBusy()
-
- self.send_command(0x02) # power off
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd1in54b_V2.py b/lib/epd1in54b_V2.py
deleted file mode 100644
index 1a9a52b..0000000
--- a/lib/epd1in54b_V2.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54b.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 200
-EPD_HEIGHT = 200
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0) # module reset
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1):
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusy()
- self.send_command(0x12) #SWRESET
- self.ReadBusy()
-
- self.send_command(0x01) #Driver output control
- self.send_data(0xC7)
- self.send_data(0x00)
- self.send_data(0x01)
-
- self.send_command(0x11) #data entry mode
- self.send_data(0x01)
-
- self.send_command(0x44) #set Ram-X address start/end position
- self.send_data(0x00)
- self.send_data(0x18) #0x18-->(24+1)*8=200
-
- self.send_command(0x45) #set Ram-Y address start/end position
- self.send_data(0xC7) #0xC7-->(199+1)=200
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3C) #BorderWavefrom
- self.send_data(0x05)
-
- self.send_command(0x18) #Read built-in temperature sensor
- self.send_data(0x80)
-
- self.send_command(0x4E) # set RAM x address count to 0
- self.send_data(0x00)
- self.send_command(0x4F) # set RAM y address count to 0X199
- self.send_data(0xC7)
- self.send_data(0x00)
- self.ReadBusy()
- return 0
-
- def getbuffer(self, image):
- buf = [0xFF] * int(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[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- return buf
-
- def display(self, blackimage, redimage):
- # send black data
- if (blackimage != None):
- self.send_command(0x24) # DATA_START_TRANSMISSION_1
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(blackimage[i])
-
- # send red data
- if (redimage != None):
- self.send_command(0x26) # DATA_START_TRANSMISSION_2
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~redimage[i])
-
- self.send_command(0x22) # DISPLAY_REFRESH
- self.send_data(0xF7)
- self.send_command(0x20) # DISPLAY_REFRESH
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x24) # DATA_START_TRANSMISSION_1
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x26) # DATA_START_TRANSMISSION_2
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
-
- self.send_command(0x22) # DISPLAY_REFRESH
- self.send_data(0xF7)
- self.send_command(0x20) # DISPLAY_REFRESH
- self.ReadBusy()
-
-
- def sleep(self):
- self.send_command(0x10) #enter deep sleep
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd1in54c.py b/lib/epd1in54c.py
deleted file mode 100644
index 9b2bbb6..0000000
--- a/lib/epd1in54c.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# *****************************************************************************
-# * | File : epd1in54c.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 152
-EPD_HEIGHT = 152
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(10)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(1)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(10)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x06) # boost soft start
- self.send_data(0x17)
- self.send_data(0x17)
- self.send_data(0x17)
- self.send_command(0x04) # power on
-
- self.ReadBusy()
-
- self.send_command(0x00) # panel setting
- self.send_data(0x0f) # LUT from OTP,160x296
- self.send_data(0x0d) # VCOM to 0V fast
-
- self.send_command(0x61) # resolution setting
- self.send_data(0x98)
- self.send_data(0x00)
- self.send_data(0x98)
-
- self.send_command(0x50)
- self.send_data(0x77)
-
- def getbuffer(self, image):
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, blackimage, yellowimage):
- self.send_command(0x10)
- logger.debug("blackimage")
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(blackimage[i])
- self.send_command(0x13)
- logger.debug("yellowimage")
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(yellowimage[i])
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- # after this, call epd.init() to awaken the module
- def sleep(self):
- self.send_command(0X02) # power off
- self.ReadBusy()
- self.send_command(0X07) # deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in13.py b/lib/epd2in13.py
deleted file mode 100644
index 59afdc8..0000000
--- a/lib/epd2in13.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-import numpy as np
-
-# Display resolution
-EPD_WIDTH = 122
-EPD_HEIGHT = 250
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- 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
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
-
- def TurnOnDisplay(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xC4)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE
-
- logger.debug("e-Paper busy")
- self.ReadBusy()
- logger.debug("e-Paper busy release")
-
- def init(self, lut):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
- self.send_command(0x01) # 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(0x0C) # BOOSTER_SOFT_START_CONTROL
- self.send_data(0xD7)
- self.send_data(0xD6)
- self.send_data(0x9D)
-
- self.send_command(0x2C) # WRITE_VCOM_REGISTER
- self.send_data(0xA8) # VCOM 7C
-
- self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD
- self.send_data(0x1A) # 4 dummy lines per gate
-
- self.send_command(0x3B) # SET_GATE_TIME
- self.send_data(0x08) # 2us per line
-
- self.send_command(0X3C) # BORDER_WAVEFORM_CONTROL
- self.send_data(0x03)
-
- self.send_command(0X11) # DATA_ENTRY_MODE_SETTING
- self.send_data(0x03) # X increment; Y increment
-
- # WRITE_LUT_REGISTER
- self.send_command(0x32)
- for count in range(30):
- self.send_data(lut[count])
-
- return 0
-
-##
- # @brief: specify the memory area for data R/W
- ##
- def SetWindows(self, x_start, y_start, x_end, y_end):
- self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
- self.send_data((x_start >> 3) & 0xFF)
- self.send_data((x_end >> 3) & 0xFF)
- self.send_command(0x45) # 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 SetCursor(self, x, y):
- self.send_command(0x4E) # 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(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(y & 0xFF)
- self.send_data((y >> 8) & 0xFF)
- self.ReadBusy()
-
- def getbuffer(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- buf = [0xFF] * (linewidth * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
-
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- if pixels[x, y] == 0:
- # x = imwidth - x
- buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- # newy = imwidth - newy - 1
- buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8))
- return buf
-
-
- def display(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.SetWindows(0, 0, self.width, self.height);
- for j in range(0, self.height):
- self.SetCursor(0, j);
- self.send_command(0x24);
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplay()
-
- def Clear(self, color):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.SetWindows(0, 0, self.width, self.height);
- for j in range(0, self.height):
- self.SetCursor(0, j);
- self.send_command(0x24);
- for i in range(0, linewidth):
- self.send_data(color)
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0x10) #enter deep sleep
- self.send_data(0x01)
- epdconfig.delay_ms(100)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in13_V2.py b/lib/epd2in13_V2.py
deleted file mode 100644
index 6670428..0000000
--- a/lib/epd2in13_V2.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-import numpy as np
-
-# Display resolution
-EPD_WIDTH = 122
-EPD_HEIGHT = 250
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- FULL_UPDATE = 0
- PART_UPDATE = 1
- lut_full_update= [
- 0x80,0x60,0x40,0x00,0x00,0x00,0x00, #LUT0: BB: VS 0 ~7
- 0x10,0x60,0x20,0x00,0x00,0x00,0x00, #LUT1: BW: VS 0 ~7
- 0x80,0x60,0x40,0x00,0x00,0x00,0x00, #LUT2: WB: VS 0 ~7
- 0x10,0x60,0x20,0x00,0x00,0x00,0x00, #LUT3: WW: VS 0 ~7
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT4: VCOM: VS 0 ~7
-
- 0x03,0x03,0x00,0x00,0x02, # TP0 A~D RP0
- 0x09,0x09,0x00,0x00,0x02, # TP1 A~D RP1
- 0x03,0x03,0x00,0x00,0x02, # TP2 A~D RP2
- 0x00,0x00,0x00,0x00,0x00, # TP3 A~D RP3
- 0x00,0x00,0x00,0x00,0x00, # TP4 A~D RP4
- 0x00,0x00,0x00,0x00,0x00, # TP5 A~D RP5
- 0x00,0x00,0x00,0x00,0x00, # TP6 A~D RP6
-
- 0x15,0x41,0xA8,0x32,0x30,0x0A,
- ]
-
- lut_partial_update = [ #20 bytes
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT0: BB: VS 0 ~7
- 0x80,0x00,0x00,0x00,0x00,0x00,0x00, #LUT1: BW: VS 0 ~7
- 0x40,0x00,0x00,0x00,0x00,0x00,0x00, #LUT2: WB: VS 0 ~7
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT3: WW: VS 0 ~7
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00, #LUT4: VCOM: VS 0 ~7
-
- 0x0A,0x00,0x00,0x00,0x00, # TP0 A~D RP0
- 0x00,0x00,0x00,0x00,0x00, # TP1 A~D RP1
- 0x00,0x00,0x00,0x00,0x00, # TP2 A~D RP2
- 0x00,0x00,0x00,0x00,0x00, # TP3 A~D RP3
- 0x00,0x00,0x00,0x00,0x00, # TP4 A~D RP4
- 0x00,0x00,0x00,0x00,0x00, # TP5 A~D RP5
- 0x00,0x00,0x00,0x00,0x00, # TP6 A~D RP6
-
- 0x15,0x41,0xA8,0x32,0x30,0x0A,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
-
- def TurnOnDisplay(self):
- self.send_command(0x22)
- self.send_data(0xC7)
- self.send_command(0x20)
- self.ReadBusy()
-
- def TurnOnDisplayPart(self):
- self.send_command(0x22)
- self.send_data(0x0c)
- self.send_command(0x20)
- self.ReadBusy()
-
- def init(self, update):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
- if(update == self.FULL_UPDATE):
- self.ReadBusy()
- self.send_command(0x12) # soft reset
- self.ReadBusy()
-
- self.send_command(0x74) #set analog block control
- self.send_data(0x54)
- self.send_command(0x7E) #set digital block control
- self.send_data(0x3B)
-
- self.send_command(0x01) #Driver output control
- self.send_data(0xF9)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x11) #data entry mode
- self.send_data(0x01)
-
- self.send_command(0x44) #set Ram-X address start/end position
- self.send_data(0x00)
- self.send_data(0x0F) #0x0C-->(15+1)*8=128
-
- self.send_command(0x45) #set Ram-Y address start/end position
- self.send_data(0xF9) #0xF9-->(249+1)=250
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3C) #BorderWavefrom
- self.send_data(0x03)
-
- self.send_command(0x2C) #VCOM Voltage
- self.send_data(0x55) #
-
- self.send_command(0x03)
- self.send_data(self.lut_full_update[70])
-
- self.send_command(0x04) #
- self.send_data(self.lut_full_update[71])
- self.send_data(self.lut_full_update[72])
- self.send_data(self.lut_full_update[73])
-
- self.send_command(0x3A) #Dummy Line
- self.send_data(self.lut_full_update[74])
- self.send_command(0x3B) #Gate time
- self.send_data(self.lut_full_update[75])
-
- self.send_command(0x32)
- for count in range(70):
- self.send_data(self.lut_full_update[count])
-
- self.send_command(0x4E) # set RAM x address count to 0
- self.send_data(0x00)
- self.send_command(0x4F) # set RAM y address count to 0X127
- self.send_data(0xF9)
- self.send_data(0x00)
- self.ReadBusy()
- else:
- self.send_command(0x2C) #VCOM Voltage
- self.send_data(0x26)
-
- self.ReadBusy()
-
- self.send_command(0x32)
- for count in range(70):
- self.send_data(self.lut_partial_update[count])
-
- self.send_command(0x37)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x40)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x22)
- self.send_data(0xC0)
- self.send_command(0x20)
- self.ReadBusy()
-
- self.send_command(0x3C) #BorderWavefrom
- self.send_data(0x01)
- return 0
-
- def getbuffer(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- buf = [0xFF] * (linewidth * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
-
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- if pixels[x, y] == 0:
- x = imwidth - x
- buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- newy = imwidth - newy - 1
- buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8))
- return buf
-
-
- def display(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplay()
-
- def displayPartial(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
-
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(~image[i + j * linewidth])
- self.TurnOnDisplayPart()
-
- def displayPartBaseImage(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
-
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplay()
-
- def Clear(self, color):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
- # logger.debug(linewidth)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(color)
-
- # self.send_command(0x26)
- # for j in range(0, self.height):
- # for i in range(0, linewidth):
- # self.send_data(color)
-
- self.TurnOnDisplay()
-
- def sleep(self):
- # self.send_command(0x22) #POWER OFF
- # self.send_data(0xC3)
- # self.send_command(0x20)
-
- self.send_command(0x10) #enter deep sleep
- self.send_data(0x03)
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in13_V3.py b/lib/epd2in13_V3.py
deleted file mode 100644
index c5cccfc..0000000
--- a/lib/epd2in13_V3.py
+++ /dev/null
@@ -1,397 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13_V3.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.1
-# * | Date : 2021-10-30
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-import numpy as np
-
-# Display resolution
-EPD_WIDTH = 122
-EPD_HEIGHT = 250
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_partial_update= [
- 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x14,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
- 0x22,0x17,0x41,0x00,0x32,0x36,
- ]
-
- lut_full_update = [
- 0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x40, 0x4A, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x40, 0x4A, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0xF, 0x0, 0x0, 0xF, 0x0, 0x0, 0x2,
- 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x0, 0x0, 0x0,
- 0x22, 0x17, 0x41, 0x0, 0x32, 0x36,
- ]
-
- '''
- function :Hardware reset
- parameter:
- '''
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
-
- '''
- function :send command
- parameter:
- command : Command register
- '''
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- '''
- function :send data
- parameter:
- data : Write data
- '''
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- '''
- function :Wait until the busy_pin goes LOW
- parameter:
- '''
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- '''
- function : Turn On Display
- parameter:
- '''
- def TurnOnDisplay(self):
- self.send_command(0x22) # Display Update Control
- self.send_data(0xC7)
- self.send_command(0x20) # Activate Display Update Sequence
- self.ReadBusy()
-
- '''
- function : Turn On Display Part
- parameter:
- '''
- def TurnOnDisplayPart(self):
- self.send_command(0x22) # Display Update Control
- self.send_data(0x0f) # fast:0x0c, quality:0x0f, 0xcf
- self.send_command(0x20) # Activate Display Update Sequence
- self.ReadBusy()
-
- '''
- function : Set lut
- parameter:
- lut : lut data
- '''
- def Lut(self, lut):
- self.send_command(0x32)
- for i in range(0, 153):
- self.send_data(lut[i])
- self.ReadBusy()
-
- '''
- function : Send lut data and configuration
- parameter:
- lut : lut data
- '''
- def SetLut(self, lut):
- self.Lut(lut)
- self.send_command(0x3f)
- self.send_data(lut[153])
- self.send_command(0x03); # gate voltage
- self.send_data(lut[154])
- self.send_command(0x04); # source voltage
- self.send_data(lut[155]) # VSH
- self.send_data(lut[156]) # VSH2
- self.send_data(lut[157]) # VSL
- self.send_command(0x2c); # VCOM
- self.send_data(lut[158])
-
- '''
- function : Setting the display window
- parameter:
- xstart : X-axis starting position
- ystart : Y-axis starting position
- xend : End position of X-axis
- yend : End position of Y-axis
- '''
- def SetWindow(self, x_start, y_start, x_end, y_end):
- self.send_command(0x44) # 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(0x45) # 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)
-
- '''
- function : Set Cursor
- parameter:
- x : X-axis starting position
- y : Y-axis starting position
- '''
- def SetCursor(self, x, y):
- self.send_command(0x4E) # 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 & 0xFF)
-
- self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(y & 0xFF)
- self.send_data((y >> 8) & 0xFF)
-
- '''
- function : Initialize the e-Paper register
- parameter:
- '''
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusy()
- self.send_command(0x12) #SWRESET
- self.ReadBusy()
-
- self.send_command(0x01) #Driver output control
- self.send_data(0xf9)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x11) #data entry mode
- self.send_data(0x03)
-
- self.SetWindow(0, 0, self.width-1, self.height-1)
- self.SetCursor(0, 0)
-
- self.send_command(0x3c)
- self.send_data(0x05)
-
- self.send_command(0x21) # Display update control
- self.send_data(0x00)
- self.send_data(0x80)
-
- self.send_command(0x18)
- self.send_data(0x80)
-
- self.ReadBusy()
-
- self.SetLut(self.lut_full_update)
- return 0
-
- '''
- function : Display images
- parameter:
- image : Image data
- '''
- def getbuffer(self, image):
- img = image
- imwidth, imheight = img.size
- if(imwidth == self.width and imheight == self.height):
- img = img.convert('1')
- elif(imwidth == self.height and imheight == self.width):
- # image has correct dimensions, but needs to be rotated
- img = img.rotate(90, expand=True).convert('1')
- else:
- logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
- # return a blank buffer
- return [0x00] * (int(self.width/8) * self.height)
-
- buf = bytearray(img.tobytes('raw'))
- return buf
-
- '''
- function : Sends the image buffer in RAM to e-Paper and displays
- parameter:
- image : Image data
- '''
- def display(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplay()
-
- '''
- function : Sends the image buffer in RAM to e-Paper and partial refresh
- parameter:
- image : Image data
- '''
- def displayPartial(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(1)
- epdconfig.digital_write(self.reset_pin, 1)
-
- self.SetLut(self.lut_partial_update)
- self.send_command(0x37)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x40)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3C) #BorderWavefrom
- self.send_data(0x80)
-
- self.send_command(0x22)
- self.send_data(0xC0)
- self.send_command(0x20)
- self.ReadBusy()
-
- self.SetWindow(0, 0, self.width - 1, self.height - 1)
- self.SetCursor(0, 0)
-
- self.send_command(0x24) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplayPart()
-
- '''
- function : Refresh a base image
- parameter:
- image : Image data
- '''
- def displayPartBaseImage(self, image):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(image[i + j * linewidth])
- self.TurnOnDisplay()
-
- '''
- function : Clear screen
- parameter:
- '''
- def Clear(self, color):
- if self.width%8 == 0:
- linewidth = int(self.width/8)
- else:
- linewidth = int(self.width/8) + 1
- # logger.debug(linewidth)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, linewidth):
- self.send_data(color)
-
- self.TurnOnDisplay()
-
- '''
- function : Enter sleep mode
- parameter:
- '''
- def sleep(self):
- self.send_command(0x10) #enter deep sleep
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in13b_V3.py b/lib/epd2in13b_V3.py
deleted file mode 100644
index fa8e3e1..0000000
--- a/lib/epd2in13b_V3.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 104
-EPD_HEIGHT = 212
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0x71);
- while(epdconfig.digital_read(self.busy_pin) == 0):
- self.send_command(0x71);
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
- self.send_command(0x04);
- self.ReadBusy();#waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x00); #panel setting
- self.send_data(0x0f); #LUT from OTP,128x296
- self.send_data(0x89); #Temperature sensor, boost and other related timing settings
-
- self.send_command(0x61); #resolution setting
- self.send_data (0x68);
- self.send_data (0x00);
- self.send_data (0xD4);
-
- self.send_command(0X50); #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x77); #WBmode:VBDF 17|D7 VBDW 97 VBDB 57
- # WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i])
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imagered[i])
-
- self.send_command(0x12) # REFRESH
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12) # REFRESH
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X50)
- self.send_data(0xf7)
- self.send_command(0X02)
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0xA5) # check code
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in13bc.py b/lib/epd2in13bc.py
deleted file mode 100644
index 601ebc6..0000000
--- a/lib/epd2in13bc.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 104
-EPD_HEIGHT = 212
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0x17)
- self.send_data(0x17)
- self.send_data(0x17)
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0x8F)
-
- self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0xF0)
-
- self.send_command(0x61) # RESOLUTION_SETTING
- self.send_data(self.width & 0xff)
- self.send_data(self.height >> 8)
- self.send_data(self.height & 0xff)
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i])
- # self.send_command(0x92)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imagered[i])
- # self.send_command(0x92)
-
- self.send_command(0x12) # REFRESH
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- self.send_command(0x92)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- self.send_command(0x92)
-
- self.send_command(0x12) # REFRESH
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0xA5) # check code
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in13d.py b/lib/epd2in13d.py
deleted file mode 100644
index 2430261..0000000
--- a/lib/epd2in13d.py
+++ /dev/null
@@ -1,361 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in13d.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-from PIL import Image
-import RPi.GPIO as GPIO
-
-# Display resolution
-EPD_WIDTH = 104
-EPD_HEIGHT = 212
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_vcomDC = [
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- ]
-
- lut_ww = [
- 0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bw = [
- 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x0F, 0x0F, 0x00, 0x00, 0x03,
- 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_wb = [
- 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bb = [
- 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_vcom1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- ]
-
- lut_ww1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bw1 = [
- 0x80, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_wb1 = [
- 0x40, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bb1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0x71)
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER SETTING
- self.send_data(0x03)
- self.send_data(0x00)
- self.send_data(0x2b)
- self.send_data(0x2b)
- self.send_data(0x03)
-
- self.send_command(0x06) # boost soft start
- self.send_data(0x17) # A
- self.send_data(0x17) # B
- self.send_data(0x17) # C
-
- self.send_command(0x04)
- self.ReadBusy()
-
- self.send_command(0x00) # panel setting
- self.send_data(0xbf) # LUT from OTP,128x296
- self.send_data(0x0d) # VCOM to 0V fast
-
- self.send_command(0x30) # PLL setting
- self.send_data(0x3a) # 3a 100HZ 29 150Hz 39 200HZ 31 171HZ
-
- self.send_command(0x61) # resolution setting
- self.send_data(self.width)
- self.send_data((self.height >> 8) & 0xff)
- self.send_data(self.height& 0xff)
-
- self.send_command(0x82) # vcom_DC setting
- self.send_data(0x28)
- return 0
-
- def SetFullReg(self):
- self.send_command(0x82)
- self.send_data(0x00)
- self.send_command(0X50)
- self.send_data(0x97)
-
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcomDC[count])
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww[count])
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw[count])
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_wb[count])
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_bb[count])
-
- def SetPartReg(self):
- self.send_command(0x82)
- self.send_data(0x03)
- self.send_command(0X50)
- self.send_data(0x47)
-
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcom1[count])
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww1[count])
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw1[count])
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_wb1[count])
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_bb1[count])
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- if (Image == None):
- return
-
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
- epdconfig.delay_ms(10)
-
- self.SetFullReg()
- self.TurnOnDisplay()
-
- def DisplayPartial(self, image):
- if (Image == None):
- return
-
- self.send_command(0x91)
- self.send_command(0x90)
- self.send_data(0)
- self.send_data(self.width - 1)
-
- self.send_data(0)
- self.send_data(0)
- self.send_data(int(self.height / 256))
- self.send_data(self.height % 256 - 1)
- self.send_data(0x28)
-
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~image[i])
- epdconfig.delay_ms(10)
-
- self.SetPartReg()
- self.TurnOnDisplay()
-
- def Clear(self, color):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- epdconfig.delay_ms(10)
-
- self.SetFullReg()
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0X50)
- self.send_data(0xf7)
- self.send_command(0X02) # power off
- self.send_command(0X07) # deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in66.py b/lib/epd2in66.py
deleted file mode 100644
index d8b4384..0000000
--- a/lib/epd2in66.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in66.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-07-22
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 152
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- WF_PARTIAL = [
- 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x0A,0x00,0x00,0x00,0x00,0x00,0x02,0x01,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x22,0x22,0x22,0x22,0x22,0x22,
- 0x00,0x00,0x00,0x22,0x17,0x41,0xB0,0x32,0x36,
- ]
-
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
-
- def init(self, mode):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x12)
- epdconfig.delay_ms(300)
- self.ReadBusy()
-
- self.send_command(0x11) # setting gaet number
- self.send_data(0x03)
- self.send_command(0x44) # set gate voltage
- self.send_data(0x01)
- self.send_data(0x13)
- self.send_command(0x45) # set source voltage
- self.send_data(0x0)
- self.send_data(0x0)
- self.send_data(0x28)
- self.send_data(0x01)
-
- if(mode == 0): #full
- self.send_command(0x3C)
- self.send_data(0x01)
-
- elif(mode == 1): #partial
- self.load_lut(self.WF_PARTIAL)
- self.send_command(0x37) # set display option, these setting turn on previous function
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x40)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3C)
- self.send_data(0x80)
-
- self.send_command(0x22)
- self.send_data(0xcf)
-
- self.send_command(0x20)
- self.ReadBusy()
-
- else:
- logger.debug("There is no such mode")
-
- return 0
-
-
- def load_lut(self, lut):
- self.send_command(0x32)
- for i in range(0, 153):
- self.send_data(lut[i])
-
-
- def turnon_display(self):
- self.send_command(0x20)
- self.ReadBusy()
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
-
- def display(self, image):
- if (image == None):
- return
-
- self.send_command(0x4E)
- self.send_data(0x01)
- self.send_command(0x4F)
- self.send_data(0x27)
- self.send_data(0x01)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.turnon_display()
-
-
- def Clear(self):
- self.send_command(0x4E)
- self.send_data(0x01)
- self.send_command(0x4F)
- self.send_data(0x27)
- self.send_data(0x01)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0xff)
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0xff)
-
- self.turnon_display()
-
-
- def sleep(self):
- self.send_command(0X10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in66b.py b/lib/epd2in66b.py
deleted file mode 100644
index a52e6f8..0000000
--- a/lib/epd2in66b.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in66b.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-12-01
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 152
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(20)
- logger.debug("e-Paper busy release")
-
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x12)
- epdconfig.delay_ms(30)
- self.ReadBusy()
-
- self.send_command(0x11) # setting gaet number
- self.send_data(0x03)
-
- self.setWindows(0, 0, self.width-1, self.height-1)
-
- self.send_command(0x21)
- self.send_data(0x00)
- self.send_data(0x80)
-
- self.setCursor(0, 0)
- self.ReadBusy()
-
- return 0
-
- def setWindows(self, Xstart, Ystart, Xend, Yend):
- self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
- self.send_data((Xstart>>3) & 0x1F)
- self.send_data((Xend>>3) & 0x1F)
-
- self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
- self.send_data(Ystart & 0xFF)
- self.send_data((Ystart >> 8) & 0x01)
- self.send_data(Yend & 0xFF)
- self.send_data((Yend >> 8) & 0x01)
-
- def setCursor(self, Xstart, Ystart):
- self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
- self.send_data(Xstart & 0x1F)
-
- self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(Ystart & 0xFF)
- self.send_data((Ystart >> 8) & 0x01)
-
- def turnon_display(self):
- self.send_command(0x20)
- self.ReadBusy()
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, Blackimage, Redimage):
- if (Blackimage == None or Redimage == None):
- return
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(Blackimage[i + j * int(self.width / 8)])
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(~Redimage[i + j * int(self.width / 8)])
-
- self.turnon_display()
-
-
- def Clear(self):
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0xff)
-
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0x00)
-
- self.turnon_display()
-
-
- def sleep(self):
- self.send_command(0X10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd2in7.py b/lib/epd2in7.py
deleted file mode 100644
index 831492b..0000000
--- a/lib/epd2in7.py
+++ /dev/null
@@ -1,527 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in7.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 176
-EPD_HEIGHT = 264
-
-GRAY1 = 0xff #white
-GRAY2 = 0xC0
-GRAY3 = 0x80 #gray
-GRAY4 = 0x00 #Blackest
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
- self.GRAY1 = GRAY1 #white
- self.GRAY2 = GRAY2
- self.GRAY3 = GRAY3 #gray
- self.GRAY4 = GRAY4 #Blackest
-
- lut_vcom_dc = [0x00, 0x00,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x60, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- ]
- lut_ww = [
- 0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_bw = [
- 0x40, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x40, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_bb = [
- 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_wb = [
- 0x80, 0x08, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x28, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x50, 0x12, 0x12, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- ###################full screen update LUT######################
- #0~3 gray
- gray_lut_vcom = [
- 0x00, 0x00,
- 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01,
- 0x60, 0x14, 0x14, 0x00, 0x00, 0x01,
- 0x00, 0x14, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x13, 0x0A, 0x01, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- #R21
- gray_lut_ww =[
- 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
- 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
- 0x10, 0x14, 0x0A, 0x00, 0x00, 0x01,
- 0xA0, 0x13, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- #R22H r
- gray_lut_bw =[
- 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
- 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
- 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
- 0x99, 0x0C, 0x01, 0x03, 0x04, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- #R23H w
- gray_lut_wb =[
- 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01,
- 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
- 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01,
- 0x99, 0x0B, 0x04, 0x04, 0x01, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- #R24H b
- gray_lut_bb =[
- 0x80, 0x0A, 0x00, 0x00, 0x00, 0x01,
- 0x90, 0x14, 0x14, 0x00, 0x00, 0x01,
- 0x20, 0x14, 0x0A, 0x00, 0x00, 0x01,
- 0x50, 0x13, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def set_lut(self):
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcom_dc[count])
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww[count])
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw[count])
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_bb[count])
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_wb[count])
-
- def gray_SetLut(self):
- self.send_command(0x20)
- for count in range(0, 44): #vcom
- self.send_data(self.gray_lut_vcom[count])
-
- self.send_command(0x21) #red not use
- for count in range(0, 42):
- self.send_data(self.gray_lut_ww[count])
-
- self.send_command(0x22) #bw r
- for count in range(0, 42):
- self.send_data(self.gray_lut_bw[count])
-
- self.send_command(0x23) #wb w
- for count in range(0, 42):
- self.send_data(self.gray_lut_wb[count])
-
- self.send_command(0x24) #bb b
- for count in range(0, 42):
- self.send_data(self.gray_lut_bb[count])
-
- self.send_command(0x25) #vcom
- for count in range(0, 42):
- self.send_data(self.gray_lut_ww[count])
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x03) # VDS_EN, VDG_EN
- self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
- self.send_data(0x2b) # VDH
- self.send_data(0x2b) # VDL
- self.send_data(0x09) # VDHR
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0x07)
- self.send_data(0x07)
- self.send_data(0x17)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x60)
- self.send_data(0xA5)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x89)
- self.send_data(0xA5)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x90)
- self.send_data(0x00)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x93)
- self.send_data(0x2A)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0xA0)
- self.send_data(0xA5)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0xA1)
- self.send_data(0x00)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x73)
- self.send_data(0x41)
-
- self.send_command(0x16) # PARTIAL_DISPLAY_REFRESH
- self.send_data(0x00)
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0xAF) # KW-BF KWR-AF BWROTP 0f
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3A) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x57)
-
- self.send_command(0x82) # VCM_DC_SETTING_REGISTER
- self.send_data(0x12)
- self.set_lut()
- return 0
-
- def Init_4Gray(self):
- if (epdconfig.module_init() != 0):
- return -1
- self.reset()
-
- self.send_command(0x01) #POWER SETTING
- self.send_data (0x03)
- self.send_data (0x00)
- self.send_data (0x2b)
- self.send_data (0x2b)
-
-
- self.send_command(0x06) #booster soft start
- self.send_data (0x07) #A
- self.send_data (0x07) #B
- self.send_data (0x17) #C
-
- self.send_command(0xF8) #boost??
- self.send_data (0x60)
- self.send_data (0xA5)
-
- self.send_command(0xF8) #boost??
- self.send_data (0x89)
- self.send_data (0xA5)
-
- self.send_command(0xF8) #boost??
- self.send_data (0x90)
- self.send_data (0x00)
-
- self.send_command(0xF8) #boost??
- self.send_data (0x93)
- self.send_data (0x2A)
-
- self.send_command(0xF8) #boost??
- self.send_data (0xa0)
- self.send_data (0xa5)
-
- self.send_command(0xF8) #boost??
- self.send_data (0xa1)
- self.send_data (0x00)
-
- self.send_command(0xF8) #boost??
- self.send_data (0x73)
- self.send_data (0x41)
-
- self.send_command(0x16)
- self.send_data(0x00)
-
- self.send_command(0x04)
- self.ReadBusy()
-
- self.send_command(0x00) #panel setting
- self.send_data(0xbf) #KW-BF KWR-AF BWROTP 0f
-
- self.send_command(0x30) #PLL setting
- self.send_data (0x90) #100hz
-
- self.send_command(0x61) #resolution setting
- self.send_data (0x00) #176
- self.send_data (0xb0)
- self.send_data (0x01) #264
- self.send_data (0x08)
-
- self.send_command(0x82) #vcom_DC setting
- self.send_data (0x12)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x57)
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def getbuffer_4Gray(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width / 4) * self.height)
- image_monocolor = image.convert('L')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- i=0
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i= i+1
- if(i%4 == 0):
- buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
-
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for x in range(imwidth):
- for y in range(imheight):
- newx = y
- newy = self.height - x - 1
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i= i+1
- if(i%4 == 0):
- buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
- return buf
-
- def display(self, image):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
- self.send_command(0x12)
- self.ReadBusy()
-
- def display_4Gray(self, image):
- self.send_command(0x10)
- for i in range(0, 5808): #5808*4 46464
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01#white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else: #0x40
- temp3 |= 0x00 #gray2
- temp3 <<= 1
-
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else : #0x40
- temp3 |= 0x00 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.send_command(0x13)
- for i in range(0, 5808): #5808*4 46464
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01#white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- temp3 <<= 1
-
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.gray_SetLut()
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
- # pass
-
- def Clear(self, color=0xFF):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(color)
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(color)
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X50)
- self.send_data(0xf7)
- self.send_command(0X02)
- self.send_command(0X07)
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in7b.py b/lib/epd2in7b.py
deleted file mode 100644
index 314c828..0000000
--- a/lib/epd2in7b.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in7b.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 176
-EPD_HEIGHT = 264
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_vcom_dc = [
- 0x00, 0x00,
- 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01,
- 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10,
- 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
- 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
- 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
- ]
-
- lut_ww = [
- 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
- 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
- 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
- 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
- 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
- ]
-
- # R22H r
- lut_bw = [
- 0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01,
- 0x00, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
- 0x90, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05,
- 0xB0, 0x03, 0x0E, 0x00, 0x00, 0x0A,
- 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01
- ]
-
- # R23H w
- lut_bb = [
- 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
- 0x40, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
- 0x80, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
- 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
- 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
- ]
- # R24H b
- lut_wb = [
- 0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01,
- 0x20, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10,
- 0x10, 0x0A, 0x0A, 0x00, 0x00, 0x08,
- 0x00, 0x04, 0x10, 0x00, 0x00, 0x05,
- 0x00, 0x03, 0x0E, 0x00, 0x00, 0x0A,
- 0x00, 0x23, 0x00, 0x00, 0x00, 0x01
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def set_lut(self):
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcom_dc[count])
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww[count])
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw[count])
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_bb[count])
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_wb[count])
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0xaf) #KW-BF KWR-AF BWROTP 0f
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3a) #3A 100HZ 29 150Hz 39 200HZ 31 171HZ
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x03) # VDS_EN, VDG_EN
- self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
- self.send_data(0x2b) # VDH
- self.send_data(0x2b) # VDL
- self.send_data(0x09) # VDHR
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0x07)
- self.send_data(0x07)
- self.send_data(0x17)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x60)
- self.send_data(0xA5)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x89)
- self.send_data(0xA5)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x90)
- self.send_data(0x00)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x93)
- self.send_data(0x2A)
-
- # Power optimization
- self.send_command(0xF8)
- self.send_data(0x73)
- self.send_data(0x41)
-
- self.send_command(0x82) # VCM_DC_SETTING_REGISTER
- self.send_data(0x12)
- self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x87) # define by OTP
-
- self.set_lut()
-
- self.send_command(0x16) # PARTIAL_DISPLAY_REFRESH
- self.send_data(0x00)
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~imageblack[i])
- self.send_command(0x11)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~imagered[i])
- self.send_command(0x11)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def Clear(self, color=0x00):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(color)
- self.send_command(0x11)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(color)
- self.send_command(0x11)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X50)
- self.send_data(0xf7)
- self.send_command(0X02)
- self.send_command(0X07)
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in7b_V2.py b/lib/epd2in7b_V2.py
deleted file mode 100644
index 3c1b25e..0000000
--- a/lib/epd2in7b_V2.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in7b_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-10-22
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 176
-EPD_HEIGHT = 264
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- # Send Command
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- # Send Data
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- # Read Busy
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- # Setting the display window
- def SetWindows(self, Xstart, Ystart, Xend, Yend):
- self.send_command(0x44)
- self.send_data((Xstart >> 3) & 0xff)
- self.send_data((Xend >> 3) & 0xff)
-
- self.send_command(0x45)
- self.send_data(Ystart & 0xff)
- self.send_data((Ystart >> 8) & 0xff)
- self.send_data(Yend & 0xff)
- self.send_data((Yend >> 8) & 0xff)
-
- # Set Cursor
- def SetCursor(self, Xstart, Ystart):
- self.send_command(0x4E)
- self.send_data(Xstart & 0xff)
- self.send_command(0x4F)
- self.send_data(Ystart & 0xff)
- self.send_data((Ystart >> 8) & 0xff)
-
- # Initialize the e-Paper register
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.ReadBusy()
- self.send_command(0x12)
- self.ReadBusy()
-
- self.send_command(0x00)
- self.send_data(0x27)
- self.send_data(0x01)
- self.send_data(0x00)
-
- self.send_command(0x11)
- self.send_data(0x03)
-
- self.SetWindows(0, 0, self.width-1, self.height-1)
- self.SetCursor(0, 0)
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- # Sends the image buffer in RAM to e-Paper and displays
- def display(self, imageblack, imagered):
- Width = self.width / 8
- Height = self.height
-
- self.send_command(0x24)
- for i in range(0, int(Width * Height)):
- self.send_data(imageblack[i])
-
- self.send_command(0x26)
- for i in range(0, int(Width * Height)):
- self.send_data(~imagered[i])
-
- self.TurnOnDisplay()
-
- # Clear the screen
- def Clear(self):
- self.send_command(0x24)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
-
- self.send_command(0x26)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
-
- self.TurnOnDisplay()
-
- # Turn on display
- def TurnOnDisplay(self):
- self.send_command(0x20)
- self.ReadBusy()
-
- # Enter sleep mode
- def sleep(self):
- self.send_command(0x10)
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in9.py b/lib/epd2in9.py
deleted file mode 100644
index 22246a0..0000000
--- a/lib/epd2in9.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in9.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 128
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_full_update = [
- 0x50, 0xAA, 0x55, 0xAA, 0x11, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xFF, 0xFF, 0x1F, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- ]
-
- lut_partial_update = [
- 0x10, 0x18, 0x18, 0x08, 0x18, 0x18,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x13, 0x14, 0x44, 0x12,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(200)
-
- def TurnOnDisplay(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xC4)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE
-
- logger.debug("e-Paper busy")
- self.ReadBusy()
- logger.debug("e-Paper busy release")
-
- def SetWindow(self, x_start, y_start, x_end, y_end):
- self.send_command(0x44) # 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(0x45) # 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)
-
- def SetCursor(self, x, y):
- self.send_command(0x4E) # 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(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(y & 0xFF)
- self.send_data((y >> 8) & 0xFF)
- self.ReadBusy()
-
- def init(self, lut):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # 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(0x0C) # BOOSTER_SOFT_START_CONTROL
- self.send_data(0xD7)
- self.send_data(0xD6)
- self.send_data(0x9D)
-
- self.send_command(0x2C) # WRITE_VCOM_REGISTER
- self.send_data(0xA8) # VCOM 7C
-
- self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD
- self.send_data(0x1A) # 4 dummy lines per gate
-
- self.send_command(0x3B) # SET_GATE_TIME
- self.send_data(0x08) # 2us per line
-
- self.send_command(0x11) # DATA_ENTRY_MODE_SETTING
- self.send_data(0x03) # X increment Y increment
-
- self.send_command(0x32) # WRITE_LUT_REGISTER
- for i in range(0, len(lut)):
- self.send_data(lut[i])
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- if (image == None):
- return
- self.SetWindow(0, 0, self.width - 1, self.height - 1)
- for j in range(0, self.height):
- self.SetCursor(0, j)
- self.send_command(0x24) # WRITE_RAM
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
- self.TurnOnDisplay()
-
- def Clear(self, color):
- self.SetWindow(0, 0, self.width - 1, self.height - 1)
- for j in range(0, self.height):
- self.SetCursor(0, j)
- self.send_command(0x24) # WRITE_RAM
- for i in range(0, int(self.width / 8)):
- self.send_data(color)
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0x10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in9_V2.py b/lib/epd2in9_V2.py
deleted file mode 100644
index 76d630e..0000000
--- a/lib/epd2in9_V2.py
+++ /dev/null
@@ -1,303 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in9_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-10-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 128
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- WF_PARTIAL_2IN9 = [
- 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0A,0x0,0x0,0x0,0x0,0x0,0x1,
- 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x1,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
- 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0,
- 0x22,0x17,0x41,0xB0,0x32,0x36,
- ]
-
- WS_20_30 = [
- 0x80, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0,
- 0x10, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0,
- 0x80, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0,
- 0x10, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x2,
- 0xA, 0xA, 0x0, 0xA, 0xA, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x14, 0x8, 0x0, 0x1, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0,
- 0x22, 0x17, 0x41, 0x0, 0x32, 0x36
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(50)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(50)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0xc7)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.ReadBusy()
-
- def TurnOnDisplay_Partial(self):
- self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
- self.send_data(0x0F)
- self.send_command(0x20) # MASTER_ACTIVATION
- self.ReadBusy()
-
- def lut(self, lut):
- self.send_command(0x32)
- for i in range(0, 153):
- self.send_data(lut[i])
- self.ReadBusy()
-
- def SetLut(self, lut):
- self.lut(lut)
- self.send_command(0x3f)
- self.send_data(lut[153])
- self.send_command(0x03); # gate voltage
- self.send_data(lut[154])
- self.send_command(0x04); # source voltage
- self.send_data(lut[155]) # VSH
- self.send_data(lut[156]) # VSH2
- self.send_data(lut[157]) # VSL
- self.send_command(0x2c); # VCOM
- self.send_data(lut[158])
-
- def SetWindow(self, x_start, y_start, x_end, y_end):
- self.send_command(0x44) # 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(0x45) # 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)
-
- def SetCursor(self, x, y):
- self.send_command(0x4E) # 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 & 0xFF)
-
- self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
- self.send_data(y & 0xFF)
- self.send_data((y >> 8) & 0xFF)
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusy()
- self.send_command(0x12) #SWRESET
- self.ReadBusy()
-
- self.send_command(0x01) #Driver output control
- self.send_data(0x27)
- self.send_data(0x01)
- self.send_data(0x00)
-
- self.send_command(0x11) #data entry mode
- self.send_data(0x03)
-
- self.SetWindow(0, 0, self.width-1, self.height-1)
-
- self.send_command(0x21) # Display update control
- self.send_data(0x00)
- self.send_data(0x80)
-
- self.SetCursor(0, 0)
- self.ReadBusy()
-
- self.SetLut(self.WS_20_30)
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- if (image == None):
- return
- self.send_command(0x24) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
- self.TurnOnDisplay()
-
- def display_Base(self, image):
- if (image == None):
- return
-
- self.send_command(0x24) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.send_command(0x26) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.TurnOnDisplay()
-
- def display_Partial(self, image):
- if (image == None):
- return
-
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(2)
-
- self.SetLut(self.WF_PARTIAL_2IN9)
- self.send_command(0x37)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x40)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x3C) #BorderWavefrom
- self.send_data(0x80)
-
- self.send_command(0x22)
- self.send_data(0xC0)
- self.send_command(0x20)
- self.ReadBusy()
-
- self.SetWindow(0, 0, self.width - 1, self.height - 1)
- self.SetCursor(0, 0)
-
- self.send_command(0x24) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
- self.TurnOnDisplay_Partial()
-
- def Clear(self, color):
- self.send_command(0x24) # WRITE_RAM
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(color)
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0x10) # DEEP_SLEEP_MODE
- self.send_data(0x01)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in9b_V3.py b/lib/epd2in9b_V3.py
deleted file mode 100644
index 7749155..0000000
--- a/lib/epd2in9b_V3.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in9b_V3.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.1
-# * | Date : 2020-12-03
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 128
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0X71)
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0X71)
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x04)
- self.ReadBusy()#waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x00) #panel setting
- self.send_data(0x0f) #LUT from OTP,128x296
- self.send_data(0x89) #Temperature sensor, boost and other related timing settings
-
- self.send_command(0x61) #resolution setting
- self.send_data (0x80)
- self.send_data (0x01)
- self.send_data (0x28)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x77) #WBmode:VBDF 17|D7 VBDW 97 VBDB 57
- # WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, blackimage, ryimage): # ryimage: red or yellow image
- if (blackimage != None):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(blackimage[i])
- if (ryimage != None):
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(ryimage[i])
-
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
-
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X02) # power off
- self.ReadBusy()
- self.send_command(0X07) # deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in9bc.py b/lib/epd2in9bc.py
deleted file mode 100644
index 51ea5b5..0000000
--- a/lib/epd2in9bc.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# *****************************************************************************
-# * | File : epd2in9bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 128
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x06) # boost
- self.send_data (0x17)
- self.send_data (0x17)
- self.send_data (0x17)
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
- self.send_command(0X00) # PANEL_SETTING
- self.send_data(0x8F)
- self.send_command(0X50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x77)
- self.send_command(0x61) # TCON_RESOLUTION
- self.send_data (0x80)
- self.send_data (0x01)
- self.send_data (0x28)
- # self.send_command(VCM_DC_SETTING_REGISTER)
- # self.send_data (0x0A)
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, blackimage, ryimage): # ryimage: red or yellow image
- if (blackimage != None):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(blackimage[i])
- if (ryimage != None):
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(ryimage[i])
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X02) # power off
- self.ReadBusy()
- self.send_command(0X07) # deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd2in9d.py b/lib/epd2in9d.py
deleted file mode 100644
index b48d7d8..0000000
--- a/lib/epd2in9d.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/python
-# -*- coding:utf-8 -*-
-
-# *****************************************************************************
-# * | File : epd2in9d.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V2.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-from PIL import Image
-import RPi.GPIO as GPIO
-
-# Display resolution
-EPD_WIDTH = 128
-EPD_HEIGHT = 296
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- lut_vcom1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00,
- ]
-
- lut_ww1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bw1 = [
- 0x80, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_wb1 = [
- 0x40, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- lut_bb1 = [
- 0x00, 0x19, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0x71)
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x12)
- epdconfig.delay_ms(10)
- self.ReadBusy()
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x04)
- self.ReadBusy() #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x00) #panel setting
- self.send_data(0x1f) # LUT from OTP,KW-BF KWR-AF BWROTP 0f BWOTP 1f
-
- self.send_command(0x61) #resolution setting
- self.send_data (0x80)
- self.send_data (0x01)
- self.send_data (0x28)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x97) #WBmode:VBDF 17|D7 VBDW 97 VBDB 57 WBRmode:VBDF F7 VBDW 77 VBDB 37 VBDR B7
-
- return 0
-
- def SetPartReg(self):
-
- self.send_command(0x01) #POWER SETTING
- self.send_data(0x03)
- self.send_data(0x00)
- self.send_data(0x2b)
- self.send_data(0x2b)
- self.send_data(0x03)
-
- self.send_command(0x06) #boost soft start
- self.send_data(0x17) #A
- self.send_data(0x17) #B
- self.send_data(0x17) #C
-
- self.send_command(0x04)
- self.ReadBusy()
-
- self.send_command(0x00) #panel setting
- self.send_data(0xbf) #LUT from OTP,128x296
-
- self.send_command(0x30) #PLL setting
- self.send_data(0x3a) # 3a 100HZ 29 150Hz 39 200HZ 31 171HZ
-
- self.send_command(0x61) #resolution setting
- self.send_data(self.width)
- self.send_data((self.height >> 8) & 0xff)
- self.send_data(self.height & 0xff)
-
- self.send_command(0x82) #vcom_DC setting
- self.send_data(0x12)
-
- self.send_command(0X50)
- self.send_data(0x97)
-
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcom1[count])
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww1[count])
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw1[count])
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_wb1[count])
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_bb1[count])
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
- epdconfig.delay_ms(10)
-
- self.TurnOnDisplay()
-
- def DisplayPartial(self, image):
- self.SetPartReg()
- self.send_command(0x91)
- self.send_command(0x90)
- self.send_data(0)
- self.send_data(self.width - 1)
-
- self.send_data(0)
- self.send_data(0)
- self.send_data(int(self.height / 256))
- self.send_data(self.height % 256 - 1)
- self.send_data(0x28)
-
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~image[i])
- epdconfig.delay_ms(10)
-
- self.TurnOnDisplay()
-
- def Clear(self, color):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- epdconfig.delay_ms(10)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
- epdconfig.delay_ms(10)
-
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0X50)
- self.send_data(0xf7)
- self.send_command(0X02) #power off
- self.send_command(0X07) #deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd3in7.py b/lib/epd3in7.py
deleted file mode 100644
index fe4dd26..0000000
--- a/lib/epd3in7.py
+++ /dev/null
@@ -1,453 +0,0 @@
-# *****************************************************************************
-# * | File : epd3in7.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-07-16
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 280
-EPD_HEIGHT = 480
-
-GRAY1 = 0xff #white
-GRAY2 = 0xC0 #Close to white
-GRAY3 = 0x80 #Close to black
-GRAY4 = 0x00 #black
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
- self.GRAY1 = GRAY1 #white
- self.GRAY2 = GRAY2
- self.GRAY3 = GRAY3 #gray
- self.GRAY4 = GRAY4 #Blackest
-
- lut_4Gray_GC = [
- 0x2A,0x06,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x28,0x06,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x20,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x14,0x06,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x02,0x02,0x0A,0x00,0x00,0x00,0x08,0x08,0x02,
- 0x00,0x02,0x02,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x22,0x22,0x22,0x22,0x22
- ]
-
- lut_1Gray_GC = [
- 0x2A,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x2A,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x02,0x03,0x0A,0x00,0x02,0x06,0x0A,0x05,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x22,0x22,0x22,0x22,0x22
- ]
-
- lut_1Gray_DU = [
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x01,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x0A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x05,0x05,0x00,0x05,0x03,0x05,0x05,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x22,0x22,0x22,0x22,0x22
- ]
-
- lut_1Gray_A2 = [
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x03,0x05,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x22,0x22,0x22,0x22,0x22
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
-
- def init(self, mode):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x12)
- epdconfig.delay_ms(300)
-
- self.send_command(0x46)
- self.send_data(0xF7)
- self.ReadBusy()
- self.send_command(0x47)
- self.send_data(0xF7)
- self.ReadBusy()
-
- self.send_command(0x01) # setting gaet number
- self.send_data(0xDF)
- self.send_data(0x01)
- self.send_data(0x00)
-
- self.send_command(0x03) # set gate voltage
- self.send_data(0x00)
-
- self.send_command(0x04) # set source voltage
- self.send_data(0x41)
- self.send_data(0xA8)
- self.send_data(0x32)
-
- self.send_command(0x11) # set data entry sequence
- self.send_data(0x03)
-
- self.send_command(0x3C) # set border
- self.send_data(0x03)
-
- self.send_command(0x0C) # set booster strength
- self.send_data(0xAE)
- self.send_data(0xC7)
- self.send_data(0xC3)
- self.send_data(0xC0)
- self.send_data(0xC0)
-
- self.send_command(0x18) # set internal sensor on
- self.send_data(0x80)
-
- self.send_command(0x2C) # set vcom value
- self.send_data(0x44)
-
- if(mode == 0): #4Gray
- self.send_command(0x37) # set display option, these setting turn on previous function
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x00)
- elif(mode == 1): #1Gray
- self.send_command(0x37) # set display option, these setting turn on previous function
- self.send_data(0x00) #can switch 1 gray or 4 gray
- self.send_data(0xFF)
- self.send_data(0xFF)
- self.send_data(0xFF)
- self.send_data(0xFF)
- self.send_data(0x4F)
- self.send_data(0xFF)
- self.send_data(0xFF)
- self.send_data(0xFF)
- self.send_data(0xFF)
- else:
- logger.debug("There is no such mode")
-
- self.send_command(0x44) # setting X direction start/end position of RAM
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0x17)
- self.send_data(0x01)
-
- self.send_command(0x45) # setting Y direction start/end position of RAM
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_data(0xDF)
- self.send_data(0x01)
-
- self.send_command(0x22) # Display Update Control 2
- self.send_data(0xCF)
- return 0
-
-
- def load_lut(self, lut):
- self.send_command(0x32)
- for i in range(0, 105):
- self.send_data(lut[i])
-
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
-
- def getbuffer_4Gray(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width / 4) * self.height)
- image_monocolor = image.convert('L')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- i=0
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i = i + 1
- if(i%4 == 0):
- buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
-
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for x in range(imwidth):
- for y in range(imheight):
- newx = y
- newy = imwidth - x - 1
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i = i + 1
- if(i%4 == 0):
- buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
- return buf
-
-
- def display_4Gray(self, image):
- if (image == None):
- return
-
- self.send_command(0x4E)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_command(0x4F)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x24)
- for i in range(0, (int)(self.height*(self.width/8))):
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01 #white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- temp3 <<= 1
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.send_command(0x4E)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_command(0x4F)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x26)
- for i in range(0, (int)(self.height*(self.width/8))):
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01 #white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else: #0x40
- temp3 |= 0x00 #gray2
- temp3 <<= 1
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else: #0x40
- temp3 |= 0x00 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.load_lut(self.lut_4Gray_GC)
- self.send_command(0x22)
- self.send_data(0xC7)
- self.send_command(0x20)
- self.ReadBusy()
-
-
- def display_1Gray(self, image):
- if (image == None):
- return
-
- self.send_command(0x4E)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_command(0x4F)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(image[i + j * int(self.width / 8)])
-
- self.load_lut(self.lut_1Gray_A2)
- self.send_command(0x20)
- self.ReadBusy()
-
-
- def Clear(self, color, mode):
- self.send_command(0x4E)
- self.send_data(0x00)
- self.send_data(0x00)
- self.send_command(0x4F)
- self.send_data(0x00)
- self.send_data(0x00)
-
- self.send_command(0x24)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0xff)
-
- if(mode == 0): #4Gray
- self.send_command(0x26)
- for j in range(0, self.height):
- for i in range(0, int(self.width / 8)):
- self.send_data(0xff)
- self.load_lut(self.lut_4Gray_GC)
- self.send_command(0x22)
- self.send_data(0xC7)
- elif(mode == 1): #1Gray
- self.load_lut(self.lut_1Gray_DU)
- else:
- logger.debug("There is no such mode")
-
- self.send_command(0x20)
- self.ReadBusy()
-
-
- def sleep(self):
- self.send_command(0X50) # DEEP_SLEEP_MODE
- self.send_data(0xf7)
- self.send_command(0X02) #power off
- self.send_command(0X07) #deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd4in01f.py b/lib/epd4in01f.py
deleted file mode 100644
index ae423fb..0000000
--- a/lib/epd4in01f.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/python
-# -*- coding:utf-8 -*-
-# *****************************************************************************
-# * | File : epd4in01f.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-11-06
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 640
-EPD_HEIGHT = 400
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
- self.BLACK = 0x000000 # 0000 BGR
- self.WHITE = 0xffffff # 0001
- self.GREEN = 0x00ff00 # 0010
- self.BLUE = 0xff0000 # 0011
- self.RED = 0x0000ff # 0100
- self.YELLOW = 0x00ffff # 0101
- self.ORANGE = 0x0080ff # 0110
-
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(1)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusyHigh(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- def ReadBusyLow(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(10)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusyHigh()
- self.send_command(0x00);
- self.send_data(0x2f);
- self.send_data(0x00);
- self.send_command(0x01);
- self.send_data(0x37);
- self.send_data(0x00);
- self.send_data(0x05);
- self.send_data(0x05);
- self.send_command(0x03);
- self.send_data(0x00);
- self.send_command(0x06);
- self.send_data(0xC7);
- self.send_data(0xC7);
- self.send_data(0x1D);
- self.send_command(0x41);
- self.send_data(0x00);
- self.send_command(0x50);
- self.send_data(0x37);
- self.send_command(0x60);
- self.send_data(0x22);
- self.send_command(0x61);
- self.send_data(0x02);
- self.send_data(0x80);
- self.send_data(0x01);
- self.send_data(0x90);
- self.send_command(0xE3);
- self.send_data(0xAA);
-
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- buf = [0x00] * int(self.width * self.height / 2)
- image_monocolor = image.convert('RGB')#Picture mode conversion
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- Add = int((x + y * self.width) / 2)
- Color = 0;
- if (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
- Color = 0
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 255):
- Color = 1
- elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
- Color = 2
- elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 255):
- Color = 3
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
- Color = 4
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
- Color = 5
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 128 and pixels[x, y][2] == 0):
- Color = 6
-
- data_t = buf[Add]&(~(0xF0 >> ((x % 2)*4)))
- buf[Add] = data_t | ((Color << 4) >> ((x % 2)*4));
-
- elif(imwidth == self.height and imheight == self.width):
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- Add = int((newx + newy*self.width) / 2)
- Color = 0;
- if (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
- Color = 0
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 255):
- Color = 1
- elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
- Color = 2
- elif (pixels[x, y][0] == 0 and pixels[x, y][1] == 0 and pixels[x, y][2] == 255):
- Color = 3
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 0 and pixels[x, y][2] == 0):
- Color = 4
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 255 and pixels[x, y][2] == 0):
- Color = 5
- elif (pixels[x, y][0] == 255 and pixels[x, y][1] == 128 and pixels[x, y][2] == 0):
- Color = 6
-
- data_t = buf[Add]&(~(0xF0 >> ((newx % 2)*4)))
- buf[Add] = data_t | ((Color << 4) >> ((newx % 2)*4));
- return buf
-
- def display(self,image):
- self.send_command(0x61)#Set Resolution setting
- self.send_data(0x02)
- self.send_data(0x80)
- self.send_data(0x01)
- self.send_data(0x90)
- self.send_command(0x10)
- for i in range(0, int(EPD_HEIGHT)):
- for j in range(0, int(EPD_WIDTH/2)):
- self.send_data((image[j+(int(EPD_WIDTH/2)*i)]))
- self.send_command(0x04)#0x04
- self.ReadBusyHigh()
- self.send_command(0x12)#0x12
- self.ReadBusyHigh()
- self.send_command(0x02) #0x02
- self.ReadBusyLow()
- # epdconfig.delay_ms(500)
-
- def Clear(self):
- self.send_command(0x61)#Set Resolution setting
- self.send_data(0x02)
- self.send_data(0x80)
- self.send_data(0x01)
- self.send_data(0x90)
- self.send_command(0x10)
- for i in range(0, int(EPD_HEIGHT)):
- for j in range(0, int(EPD_WIDTH/2)):
- self.send_data(0x11)
- #BLACK 0x00 /// 0000
- #WHITE 0x11 /// 0001
- #GREEN 0x22 /// 0010
- #BLUE 0x33 /// 0011
- #RED 0x44 /// 0100
- #YELLOW 0x55 /// 0101
- #ORANGE 0x66 /// 0110
- #CLEAN 0x77 /// 0111 unavailable Afterimage
- self.send_command(0x04)#0x04
- self.ReadBusyHigh()
- self.send_command(0x12)#0x12
- self.ReadBusyHigh()
- self.send_command(0x02) #0x02
- self.ReadBusyLow()
- # epdconfig.delay_ms(500)
-
- def sleep(self):
- # epdconfig.delay_ms(500)
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
\ No newline at end of file
diff --git a/lib/epd4in2.py b/lib/epd4in2.py
deleted file mode 100644
index 6fabd7f..0000000
--- a/lib/epd4in2.py
+++ /dev/null
@@ -1,609 +0,0 @@
-# *****************************************************************************
-# * | File : epd4in2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-from PIL import Image
-import RPi.GPIO as GPIO
-
-# Display resolution
-EPD_WIDTH = 400
-EPD_HEIGHT = 300
-
-GRAY1 = 0xff #white
-GRAY2 = 0xC0
-GRAY3 = 0x80 #gray
-GRAY4 = 0x00 #Blackest
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
- self.GRAY1 = GRAY1 #white
- self.GRAY2 = GRAY2
- self.GRAY3 = GRAY3 #gray
- self.GRAY4 = GRAY4 #Blackest
-
- lut_vcom0 = [
- 0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
- 0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_ww = [
- 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
- 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_bw = [
- 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
- 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_wb = [
- 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
- 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- lut_bb = [
- 0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
- 0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
- 0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
- 0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- ]
- #******************************partial screen update LUT*********************************/
- EPD_4IN2_Partial_lut_vcom1 =[
- 0x00 ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00, ]
-
- EPD_4IN2_Partial_lut_ww1 =[
- 0x00 ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,]
-
- EPD_4IN2_Partial_lut_bw1 =[
- 0x80 ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, ]
-
- EPD_4IN2_Partial_lut_wb1 =[
- 0x40 ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, ]
-
- EPD_4IN2_Partial_lut_bb1 =[
- 0x00 ,0x19 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, ]
-
- #******************************gray*********************************/
- #0~3 gray
- EPD_4IN2_4Gray_lut_vcom =[
- 0x00 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
- 0x60 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x14 ,0x00 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x13 ,0x0A ,0x01 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00
- ]
- #R21
- EPD_4IN2_4Gray_lut_ww =[
- 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
- 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
- 0x10 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
- 0xA0 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- ]
- #R22H r
- EPD_4IN2_4Gray_lut_bw =[
- 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
- 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
- 0x99 ,0x0C ,0x01 ,0x03 ,0x04 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- ]
- #R23H w
- EPD_4IN2_4Gray_lut_wb =[
- 0x40 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
- 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
- 0x99 ,0x0B ,0x04 ,0x04 ,0x01 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- ]
- #R24H b
- EPD_4IN2_4Gray_lut_bb =[
- 0x80 ,0x0A ,0x00 ,0x00 ,0x00 ,0x01,
- 0x90 ,0x14 ,0x14 ,0x00 ,0x00 ,0x01,
- 0x20 ,0x14 ,0x0A ,0x00 ,0x00 ,0x01,
- 0x50 ,0x13 ,0x01 ,0x00 ,0x00 ,0x01,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- 0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- self.send_command(0x71)
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0x71)
- epdconfig.delay_ms(100)
-
- def set_lut(self):
- self.send_command(0x20) # vcom
- for count in range(0, 44):
- self.send_data(self.lut_vcom0[count])
-
- self.send_command(0x21) # ww --
- for count in range(0, 42):
- self.send_data(self.lut_ww[count])
-
- self.send_command(0x22) # bw r
- for count in range(0, 42):
- self.send_data(self.lut_bw[count])
-
- self.send_command(0x23) # wb w
- for count in range(0, 42):
- self.send_data(self.lut_bb[count])
-
- self.send_command(0x24) # bb b
- for count in range(0, 42):
- self.send_data(self.lut_wb[count])
-
-
- def Partial_SetLut(self):
- self.send_command(0x20);
- for count in range(0, 44):
- self.send_data(self.EPD_4IN2_Partial_lut_vcom1[count])
-
- self.send_command(0x21);
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_Partial_lut_ww1[count])
-
- self.send_command(0x22);
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_Partial_lut_bw1[count])
-
- self.send_command(0x23);
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_Partial_lut_wb1[count])
-
- self.send_command(0x24);
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_Partial_lut_bb1[count])
-
-
-
- def Gray_SetLut(self):
- self.send_command(0x20) #vcom
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_vcom[count])
-
- self.send_command(0x21) #red not use
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])
-
- self.send_command(0x22) #bw r
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_bw[count])
-
- self.send_command(0x23) #wb w
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_wb[count])
-
- self.send_command(0x24) #bb b
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_bb[count])
-
- self.send_command(0x25) #vcom
- for count in range(0, 42):
- self.send_data(self.EPD_4IN2_4Gray_lut_ww[count])
-
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER SETTING
- self.send_data(0x03) # VDS_EN, VDG_EN
- self.send_data(0x00) # VCOM_HV, VGHL_LV[1], VGHL_LV[0]
- self.send_data(0x2b) # VDH
- self.send_data(0x2b) # VDL
-
- self.send_command(0x06) # boost soft start
- self.send_data(0x17)
- self.send_data(0x17)
- self.send_data(0x17)
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x00) # panel setting
- self.send_data(0xbf) # KW-BF KWR-AF BWROTP 0f
- self.send_data(0x0d)
-
- self.send_command(0x30) # PLL setting
- self.send_data(0x3c) # 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
-
- self.send_command(0x61) # resolution setting
- self.send_data(0x01)
- self.send_data(0x90) # 128
- self.send_data(0x01)
- self.send_data(0x2c)
-
- self.send_command(0x82) # vcom_DC setting
- self.send_data(0x28)
-
- self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
- self.send_data(0x97) # 97white border 77black border VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
-
- self.set_lut()
- # EPD hardware init end
- return 0
-
- def Init_4Gray(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) #POWER SETTING
- self.send_data (0x03)
- self.send_data (0x00) #VGH=20V,VGL=-20V
- self.send_data (0x2b) #VDH=15V
- self.send_data (0x2b) #VDL=-15V
- self.send_data (0x13)
-
- self.send_command(0x06) #booster soft start
- self.send_data (0x17) #A
- self.send_data (0x17) #B
- self.send_data (0x17) #C
-
- self.send_command(0x04)
- self.ReadBusy()
-
- self.send_command(0x00) #panel setting
- self.send_data(0x3f) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
-
- self.send_command(0x30) #PLL setting
- self.send_data (0x3c) #100hz
-
- self.send_command(0x61) #resolution setting
- self.send_data (0x01) #400
- self.send_data (0x90)
- self.send_data (0x01) #300
- self.send_data (0x2c)
-
- self.send_command(0x82) #vcom_DC setting
- self.send_data (0x12)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x97)
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def getbuffer_4Gray(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width / 4) * self.height)
- image_monocolor = image.convert('L')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- i=0
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i= i+1
- if(i%4 == 0):
- buf[int((x + (y * self.width))/4)] = ((pixels[x-3, y]&0xc0) | (pixels[x-2, y]&0xc0)>>2 | (pixels[x-1, y]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
-
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for x in range(imwidth):
- for y in range(imheight):
- newx = y
- newy = x
- if(pixels[x, y] == 0xC0):
- pixels[x, y] = 0x80
- elif (pixels[x, y] == 0x80):
- pixels[x, y] = 0x40
- i= i+1
- if(i%4 == 0):
- buf[int((newx + (newy * self.width))/4)] = ((pixels[x, y-3]&0xc0) | (pixels[x, y-2]&0xc0)>>2 | (pixels[x, y-1]&0xc0)>>4 | (pixels[x, y]&0xc0)>>6)
-
- return buf
-
- def display(self, image):
- self.send_command(0x92);
- self.set_lut();
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(image[i])
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def EPD_4IN2_PartialDisplay(self, X_start, Y_start, X_end, Y_end, Image):
- # EPD_WIDTH = 400
- # EPD_HEIGHT = 300
- if(EPD_WIDTH % 8 != 0):
- Width = int(EPD_WIDTH / 8) + 1;
- else:
- Width = int(EPD_WIDTH / 8);
- Height = EPD_HEIGHT;
-
- if(X_start % 8 != 0):
- X_start = int(X_start/8)*8+8
- if(X_end % 8 != 0):
- X_end = int(X_end/8)*8+8
-
- self.Partial_SetLut();
- self.send_command(0x91); #This command makes the display enter partial mode
- self.send_command(0x90); #resolution setting
- self.send_data (int(X_start/256));
- self.send_data (int(X_start%256)); #x-start
-
- self.send_data (int(X_end /256));
- self.send_data (int(X_end %256)-1); #x-end
-
- self.send_data (int(Y_start/256));
- self.send_data (int(Y_start%256)); #y-start
-
-
- self.send_data (int(Y_end/256));
- self.send_data (int(Y_end%256)-1); #y-end
- self.send_data (0x28);
-
- self.send_command(0x10); #writes Old data to SRAM for programming
- for j in range(0, int(Y_end - Y_start)):
- for i in range(0, int(X_end/8) - int(X_start/8)):
- self.send_data(Image[(Y_start + j)*Width + int(X_start/8) + i]);
-
- self.send_command(0x13); #writes New data to SRAM.
- for j in range(0, int(Y_end - Y_start)):
- for i in range(0, int(X_end/8) - int(X_start/8)):
- self.send_data(~Image[(Y_start + j)*Width + int(X_start/8) + i]);
-
- self.send_command(0x12); #DISPLAY REFRESH
- epdconfig.delay_ms(200) #The delay here is necessary, 200uS at least!!!
- self.ReadBusy()
-
-
- def display_4Gray(self, image):
- self.send_command(0x92);
- self.set_lut();
- self.send_command(0x10)
- for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)): # EPD_WIDTH * EPD_HEIGHT / 4
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01#white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else: #0x40
- temp3 |= 0x00 #gray2
- temp3 <<= 1
-
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x01 #gray1
- else : #0x40
- temp3 |= 0x00 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.send_command(0x13)
-
- for i in range(0, int(EPD_WIDTH * EPD_HEIGHT / 8)): #5808*4 46464
- temp3=0
- for j in range(0, 2):
- temp1 = image[i*2+j]
- for k in range(0, 2):
- temp2 = temp1&0xC0
- if(temp2 == 0xC0):
- temp3 |= 0x01#white
- elif(temp2 == 0x00):
- temp3 |= 0x00 #black
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- temp3 <<= 1
-
- temp1 <<= 2
- temp2 = temp1&0xC0
- if(temp2 == 0xC0): #white
- temp3 |= 0x01
- elif(temp2 == 0x00): #black
- temp3 |= 0x00
- elif(temp2 == 0x80):
- temp3 |= 0x00 #gray1
- else: #0x40
- temp3 |= 0x01 #gray2
- if(j!=1 or k!=1):
- temp3 <<= 1
- temp1 <<= 2
- self.send_data(temp3)
-
- self.Gray_SetLut()
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
- # pass
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd4in2b_V2.py b/lib/epd4in2b_V2.py
deleted file mode 100644
index db080a5..0000000
--- a/lib/epd4in2b_V2.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# *****************************************************************************
-# * | File : epd4in2bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 400
-EPD_HEIGHT = 300
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0x71);
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0x71);
- epdconfig.delay_ms(20)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x04);
- self.ReadBusy();
-
- self.send_command(0x00);
- self.send_data(0x0f);
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i])
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imagered[i])
-
- self.send_command(0x12)
- epdconfig.delay_ms(20)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12)
- epdconfig.delay_ms(20)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X50);
- self.send_data(0xf7); #border floating
-
- self.send_command(0X02); #power off
- self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal
- self.send_command(0X07); #deep sleep
- self.send_data(0xA5);
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd4in2bc.py b/lib/epd4in2bc.py
deleted file mode 100644
index c948f2f..0000000
--- a/lib/epd4in2bc.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# *****************************************************************************
-# * | File : epd4in2bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 400
-EPD_HEIGHT = 300
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data (0x17)
- self.send_data (0x17)
- self.send_data (0x17) # 07 0f 17 1f 27 2F 37 2f
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0x0F) # LUT from OTP
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i])
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imagered[i])
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xFF)
-
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0xA5) # check code
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd5in65f.py b/lib/epd5in65f.py
deleted file mode 100644
index fc71d79..0000000
--- a/lib/epd5in65f.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/python
-# -*- coding:utf-8 -*-
-# *****************************************************************************
-# * | File : epd5in65f.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-03-02
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-import PIL
-from PIL import Image
-import io
-
-# Display resolution
-EPD_WIDTH = 600
-EPD_HEIGHT = 448
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
- self.BLACK = 0x000000 # 0000 BGR
- self.WHITE = 0xffffff # 0001
- self.GREEN = 0x00ff00 # 0010
- self.BLUE = 0xff0000 # 0011
- self.RED = 0x0000ff # 0100
- self.YELLOW = 0x00ffff # 0101
- self.ORANGE = 0x0080ff # 0110
-
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(600)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data_bulk(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte2(data)
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusyHigh(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def ReadBusyLow(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusyHigh()
- self.send_command(0x00)
- self.send_data(0xEF)
- self.send_data(0x08)
- self.send_command(0x01)
- self.send_data(0x37)
- self.send_data(0x00)
- self.send_data(0x23)
- self.send_data(0x23)
- self.send_command(0x03)
- self.send_data(0x00)
- self.send_command(0x06)
- self.send_data(0xC7)
- self.send_data(0xC7)
- self.send_data(0x1D)
- self.send_command(0x30)
- self.send_data(0x3c)
- self.send_command(0x41)
- self.send_data(0x00)
- self.send_command(0x50)
- self.send_data(0x37)
- self.send_command(0x60)
- self.send_data(0x22)
- self.send_command(0x61)
- self.send_data(0x02)
- self.send_data(0x58)
- self.send_data(0x01)
- self.send_data(0xC0)
- self.send_command(0xE3)
- self.send_data(0xAA)
-
- epdconfig.delay_ms(100)
- self.send_command(0x50)
- self.send_data(0x37)
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- # Create a pallette with the 7 colors supported by the panel
- pal_image = Image.new("P", (1,1))
- pal_image.putpalette( (0,0,0, 255,255,255, 0,255,0, 0,0,255, 255,0,0, 255,255,0, 255,128,0) + (0,0,0)*249)
-
- # Check if we need to rotate the image
- imwidth, imheight = image.size
- if(imwidth == self.width and imheight == self.height):
- image_temp = image
- elif(imwidth == self.height and imheight == self.width):
- image_temp = image.rotate(90, expand=True)
- else:
- logger.warning("Invalid image dimensions: %d x %d, expected %d x %d" % (imwidth, imheight, self.width, self.height))
-
- # Convert the soruce image to the 7 colors, dithering if needed
- image_7color = image_temp.convert("RGB").quantize(palette=pal_image)
- buf_7color = bytearray(image_7color.tobytes('raw'))
-
- # PIL does not support 4 bit color, so pack the 4 bits of color
- # into a single byte to transfer to the panel
- buf = [0x00] * int(self.width * self.height / 2)
- idx = 0
- for i in range(0, len(buf_7color), 2):
- buf[idx] = (buf_7color[i] << 4) + buf_7color[i+1]
- idx += 1
-
- return buf
-
- def display(self,image):
- self.send_command(0x61) #Set Resolution setting
- self.send_data(0x02)
- self.send_data(0x58)
- self.send_data(0x01)
- self.send_data(0xC0)
- self.send_command(0x10)
-
- self.send_data_bulk(image)
- self.send_command(0x04) #0x04
- self.ReadBusyHigh()
- self.send_command(0x12) #0x12
- self.ReadBusyHigh()
- self.send_command(0x02) #0x02
- self.ReadBusyLow()
- epdconfig.delay_ms(500)
-
- def Clear(self):
- self.send_command(0x61) #Set Resolution setting
- self.send_data(0x02)
- self.send_data(0x58)
- self.send_data(0x01)
- self.send_data(0xC0)
- self.send_command(0x10)
-
- # Set all pixels to white
- buf = [0x11] * int(self.width * self.height / 2)
- self.send_data_bulk(buf)
-
- self.send_command(0x04) #0x04
- self.ReadBusyHigh()
- self.send_command(0x12) #0x12
- self.ReadBusyHigh()
- self.send_command(0x02) #0x02
- self.ReadBusyLow()
- epdconfig.delay_ms(500)
-
- def sleep(self):
- epdconfig.delay_ms(500)
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
- epdconfig.digital_write(self.reset_pin, 0)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
diff --git a/lib/epd5in83.py b/lib/epd5in83.py
deleted file mode 100644
index 84fabf0..0000000
--- a/lib/epd5in83.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# *****************************************************************************
-# * | File : epd5in83.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 600
-EPD_HEIGHT = 448
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x37)
- self.send_data(0x00)
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0xCF)
- self.send_data(0x08)
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0xc7)
- self.send_data(0xcc)
- self.send_data(0x28)
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3c)
-
- self.send_command(0x41) # TEMPERATURE_CALIBRATION
- self.send_data(0x00)
-
- self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x77)
-
- self.send_command(0x60) # TCON_SETTING
- self.send_data(0x22)
-
- self.send_command(0x61) # TCON_RESOLUTION
- self.send_data(0x02) # source 600
- self.send_data(0x58)
- self.send_data(0x01) # gate 448
- self.send_data(0xC0)
-
- self.send_command(0x82) # VCM_DC_SETTING
- self.send_data(0x1E) # decide by LUT file
-
- self.send_command(0xe5) # FLASH MODE
- self.send_data(0x03)
-
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- buf = [0x00] * int(self.width * self.height / 4)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] < 64: # black
- buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
- elif pixels[x, y] < 192: # convert gray to red
- buf[int((x + y * self.width) / 4)] &= ~(0xC0 >> (x % 4 * 2))
- buf[int((x + y * self.width) / 4)] |= 0x40 >> (x % 4 * 2)
- else: # white
- buf[int((x + y * self.width) / 4)] |= 0xC0 >> (x % 4 * 2)
- elif(imwidth == self.height and imheight == self.width):
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] < 64: # black
- buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
- elif pixels[x, y] < 192: # convert gray to red
- buf[int((newx + newy*self.width) / 4)] &= ~(0xC0 >> (y % 4 * 2))
- buf[int((newx + newy*self.width) / 4)] |= 0x40 >> (y % 4 * 2)
- else: # white
- buf[int((newx + newy*self.width) / 4)] |= 0xC0 >> (y % 4 * 2)
- return buf
-
- def display(self, image):
- self.send_command(0x10)
- for i in range(0, int(self.width / 4 * self.height)):
- temp1 = image[i]
- j = 0
- while (j < 4):
- if ((temp1 & 0xC0) == 0xC0):
- temp2 = 0x03
- elif ((temp1 & 0xC0) == 0x00):
- temp2 = 0x00
- else:
- temp2 = 0x04
- temp2 = (temp2 << 4) & 0xFF
- temp1 = (temp1 << 2) & 0xFF
- j += 1
- if((temp1 & 0xC0) == 0xC0):
- temp2 |= 0x03
- elif ((temp1 & 0xC0) == 0x00):
- temp2 |= 0x00
- else:
- temp2 |= 0x04
- temp1 = (temp1 << 2) & 0xFF
- self.send_data(temp2)
- j += 1
-
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width / 4 * self.height)):
- for j in range(0, 4):
- self.send_data(0x33)
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd5in83_V2.py b/lib/epd5in83_V2.py
deleted file mode 100644
index 680fcc7..0000000
--- a/lib/epd5in83_V2.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# *****************************************************************************
-# * | File : epd5in83_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-12-09
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 648
-EPD_HEIGHT = 480
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0):
- epdconfig.delay_ms(20)
- logger.debug("e-Paper busy release")
-
- def TurnOnDisplay(self):
- self.send_command(0x12); #POWER ON
- epdconfig.delay_ms(100)
- self.ReadBusy();
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) #POWER SETTING
- self.send_data (0x07)
- self.send_data (0x07) #VGH=20V,VGL=-20V
- self.send_data (0x3f) #VDH=15V
- self.send_data (0x3f) #VDL=-15V
-
- self.send_command(0x04) #POWER ON
- epdconfig.delay_ms(100)
- self.ReadBusy() #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0X00) #PANNEL SETTING
- self.send_data(0x1F) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
-
- self.send_command(0x61) #tres
- self.send_data (0x02) #source 648
- self.send_data (0x88)
- self.send_data (0x01) #gate 480
- self.send_data (0xE0)
-
- self.send_command(0X15)
- self.send_data(0x00)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x10)
- self.send_data(0x07)
-
- self.send_command(0X60) #TCON SETTING
- self.send_data(0x22)
-
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, image):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~image[i])
- self.TurnOnDisplay()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
- self.TurnOnDisplay()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-
-### END OF FILE ###
-
diff --git a/lib/epd5in83b_V2.py b/lib/epd5in83b_V2.py
deleted file mode 100644
index 67fa7f7..0000000
--- a/lib/epd5in83b_V2.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# *****************************************************************************
-# * | File : epd5in83b_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2020-07-04
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 648
-EPD_HEIGHT = 480
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(1)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0X71)
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- self.send_command(0X71)
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x01) #POWER SETTING
- self.send_data (0x07)
- self.send_data (0x07) #VGH=20V,VGL=-20V
- self.send_data (0x3f) #VDH=15V
- self.send_data (0x3f) #VDL=-15V
-
- self.send_command(0x04) #POWER ON
- epdconfig.delay_ms(100)
- self.ReadBusy() #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0X00) #PANNEL SETTING
- self.send_data(0x0F) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
-
- self.send_command(0x61) #tres
- self.send_data (0x02) #source 648
- self.send_data (0x88)
- self.send_data (0x01) #gate 480
- self.send_data (0xe0)
-
- self.send_command(0X15)
- self.send_data(0x00)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x11)
- self.send_data(0x07)
-
- self.send_command(0X60) #TCON SETTING
- self.send_data(0x22)
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- if (imageblack != None):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i])
- if (imagered != None):
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~imagered[i])
-
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0X10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
- self.send_command(0X13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
-
- self.send_command(0x12)
- epdconfig.delay_ms(200)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0X02) # power off
- self.ReadBusy()
- self.send_command(0X07) # deep sleep
- self.send_data(0xA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd5in83bc.py b/lib/epd5in83bc.py
deleted file mode 100644
index cf5d4c4..0000000
--- a/lib/epd5in83bc.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# *****************************************************************************
-# * | File : epd5in83b.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 600
-EPD_HEIGHT = 448
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x37)
- self.send_data(0x00)
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0xCF)
- self.send_data(0x08)
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3A) # PLL: 0-15:0x3C, 15+:0x3A
- self.send_command(0X82) # VCOM VOLTAGE SETTING
- self.send_data(0x28) # all temperature range
-
- self.send_command(0x06) # boost
- self.send_data(0xc7)
- self.send_data(0xcc)
- self.send_data(0x15)
-
- self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
- self.send_data(0x77)
-
- self.send_command(0X60) # TCON SETTING
- self.send_data(0x22)
-
- self.send_command(0X65) # FLASH CONTROL
- self.send_data(0x00)
-
- self.send_command(0x61) # tres
- self.send_data(0x02) # source 600
- self.send_data(0x58)
- self.send_data(0x01) # gate 448
- self.send_data(0xc0)
-
- self.send_command(0xe5) # FLASH MODE
- self.send_data(0x03)
- self.send_data(0x03)
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width / 8 * self.height)):
- temp1 = imageblack[i]
- temp2 = imagered[i]
- j = 0
- while (j < 8):
- if ((temp2 & 0x80) == 0x00):
- temp3 = 0x04 #red
- elif ((temp1 & 0x80) == 0x00):
- temp3 = 0x00 #black
- else:
- temp3 = 0x03 #white
-
- temp3 = (temp3 << 4) & 0xFF
- temp1 = (temp1 << 1) & 0xFF
- temp2 = (temp2 << 1) & 0xFF
- j += 1
- if((temp2 & 0x80) == 0x00):
- temp3 |= 0x04 #red
- elif ((temp1 & 0x80) == 0x00):
- temp3 |= 0x00 #black
- else:
- temp3 |= 0x03 #white
- temp1 = (temp1 << 1) & 0xFF
- temp2 = (temp2 << 1) & 0xFF
- self.send_data(temp3)
- j += 1
-
- self.send_command(0x04) # POWER ON
- self.ReadBusy()
- self.send_command(0x12) # display refresh
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width / 8 * self.height)):
- self.send_data(0x33)
- self.send_data(0x33)
- self.send_data(0x33)
- self.send_data(0x33)
-
- self.send_command(0x04) # POWER ON
- self.ReadBusy()
- self.send_command(0x12) # display refresh
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0xA5) # check code
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5.py b/lib/epd7in5.py
deleted file mode 100644
index 2f8d8fa..0000000
--- a/lib/epd7in5.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 640
-EPD_HEIGHT = 384
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data2(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte2(data)
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data2([0x37, 0x00])
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data2([0xCF, 0x08])
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data2([0xc7, 0xcc, 0x28])
-
- self.send_command(0x04) # POWER_ON
- self.ReadBusy()
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3c)
-
- self.send_command(0x41) # TEMPERATURE_CALIBRATION
- self.send_data(0x00)
-
- self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING
- self.send_data(0x77)
-
- self.send_command(0x60) # TCON_SETTING
- self.send_data(0x22)
-
- self.send_command(0x61) # TCON_RESOLUTION
- self.send_data(EPD_WIDTH >> 8) #source 640
- self.send_data(EPD_WIDTH & 0xff)
- self.send_data(EPD_HEIGHT >> 8) #gate 384
- self.send_data(EPD_HEIGHT & 0xff)
-
- self.send_command(0x82) # VCM_DC_SETTING
- self.send_data(0x1E) # decide by LUT file
-
- self.send_command(0xe5) # FLASH MODE
- self.send_data(0x03)
-
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- img = image
- imwidth, imheight = img.size
- halfwidth = int(self.width / 2)
- buf = [0x33] * halfwidth * self.height
-
- if(imwidth == self.width and imheight == self.height):
- img = img.convert('1')
- elif(imwidth == self.height and imheight == self.width):
- img = img.rotate(90, expand=True).convert('1')
- imwidth, imheight = img.size
- else:
- logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
- # return a blank buffer
- return buf
-
- pixels = img.load()
-
- for y in range(imheight):
- offset = y * halfwidth
- for x in range(1, imwidth, 2):
- i = offset + x // 2
- if(pixels[x-1, y] > 191):
- if(pixels[x, y] > 191):
- buf[i] = 0x33
- else:
- buf[i] = 0x30
- else:
- if(pixels[x, y] > 191):
- buf[i] = 0x03
- else:
- buf[i] = 0x00
- return buf
-
- def display(self, image):
- self.send_command(0x10)
- self.send_data2(image)
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- buf = [0x33] * int(self.width * self.height / 2)
- self.send_command(0x10)
- self.send_data2(buf)
- self.send_command(0x12)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
-
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5_HD.py b/lib/epd7in5_HD.py
deleted file mode 100644
index 908d036..0000000
--- a/lib/epd7in5_HD.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 880
-EPD_HEIGHT = 528
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data2(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte2(data)
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- busy = epdconfig.digital_read(self.busy_pin)
- while(busy == 1):
- busy = epdconfig.digital_read(self.busy_pin)
- epdconfig.delay_ms(200)
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- self.ReadBusy();
- self.send_command(0x12); #SWRESET
- self.ReadBusy();
-
- self.send_command(0x46); # Auto Write Red RAM
- self.send_data(0xf7);
- self.ReadBusy();
- self.send_command(0x47); # Auto Write B/W RAM
- self.send_data(0xf7);
- self.ReadBusy();
-
- self.send_command(0x0C); # Soft start setting
- self.send_data2([0xAE, 0xC7, 0xC3, 0xC0, 0x40])
-
- self.send_command(0x01); # Set MUX as 527
- self.send_data2([0xAF, 0x02, 0x01])
-
- self.send_command(0x11); # Data entry mode
- self.send_data(0x01);
-
- self.send_command(0x44);
- self.send_data2([0x00, 0x00, 0x6F, 0x03]) # RAM x address start at 0
- self.send_command(0x45);
- self.send_data2([0xAF, 0x02, 0x00, 0x00])
-
- self.send_command(0x3C); # VBD
- self.send_data(0x05); # LUT1, for white
-
- self.send_command(0x18);
- self.send_data(0X80);
-
-
- self.send_command(0x22);
- self.send_data(0XB1); #Load Temperature and waveform setting.
- self.send_command(0x20);
- self.ReadBusy();
-
- self.send_command(0x4E); # set RAM x address count to 0;
- self.send_data2([0x00, 0x00])
- self.send_command(0x4F);
- self.send_data2([0x00, 0x00])
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- img = image
- imwidth, imheight = img.size
- if(imwidth == self.width and imheight == self.height):
- img = img.convert('1')
- elif(imwidth == self.height and imheight == self.width):
- img = img.rotate(90, expand=True).convert('1')
- else:
- logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
- # return a blank buffer
- return [0xff] * int(self.width * self.height / 8)
-
- buf = bytearray(img.tobytes('raw'))
- return buf
-
- def display(self, image):
- self.send_command(0x4F);
- self.send_data2([0x00, 0x00])
- self.send_command(0x24);
- self.send_data2(image)
- self.send_command(0x22);
- self.send_data(0xF7);#Load LUT from MCU(0x32)
- self.send_command(0x20);
- epdconfig.delay_ms(10);
- self.ReadBusy();
-
- def Clear(self):
- buf = [0xff] * int(self.width * self.height / 8)
- self.send_command(0x4F);
- self.send_data2([0x00, 0x00])
- self.send_command(0x24)
- self.send_data2(buf)
-
- self.send_command(0x26)
- self.send_data2(buf)
-
- self.send_command(0x22);
- self.send_data(0xF7);#Load LUT from MCU(0x32)
- self.send_command(0x20);
- epdconfig.delay_ms(10);
- self.ReadBusy();
-
- def sleep(self):
- self.send_command(0x10);
- self.send_data(0x01);
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5_V2.py b/lib/epd7in5_V2.py
deleted file mode 100644
index b1495ca..0000000
--- a/lib/epd7in5_V2.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 800
-EPD_HEIGHT = 480
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- Voltage_Frame_7IN5_V2 = [
- 0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
- ]
-
- LUT_VCOM_7IN5_V2 = [
- 0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
- 0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ]
-
- LUT_WW_7IN5_V2 = [
- 0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
- 0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ]
-
- LUT_BW_7IN5_V2 = [
- 0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
- 0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ]
-
- LUT_WB_7IN5_V2 = [
- 0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
- 0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ]
-
- LUT_BB_7IN5_V2 = [
- 0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
- 0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- ]
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(2)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(20)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data2(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.SPI.writebytes2(data)
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- while(busy == 0):
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- epdconfig.delay_ms(20)
- logger.debug("e-Paper busy release")
-
- def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
- self.send_command(0x20)
- for count in range(0, 42):
- self.send_data(lut_vcom[count])
-
- self.send_command(0x21)
- for count in range(0, 42):
- self.send_data(lut_ww[count])
-
- self.send_command(0x22)
- for count in range(0, 42):
- self.send_data(lut_bw[count])
-
- self.send_command(0x23)
- for count in range(0, 42):
- self.send_data(lut_wb[count])
-
- self.send_command(0x24)
- for count in range(0, 42):
- self.send_data(lut_bb[count])
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
- # EPD hardware init start
- self.reset()
-
- # self.send_command(0x06) # btst
- # self.send_data(0x17)
- # self.send_data(0x17)
- # self.send_data(0x28) # If an exception is displayed, try using 0x38
- # self.send_data(0x17)
-
- # self.send_command(0x01) #POWER SETTING
- # self.send_data(0x07)
- # self.send_data(0x07) #VGH=20V,VGL=-20V
- # self.send_data(0x3f) #VDH=15V
- # self.send_data(0x3f) #VDL=-15V
-
- self.send_command(0x01); # power setting
- self.send_data(0x17); # 1-0=11: internal power
- self.send_data(self.Voltage_Frame_7IN5_V2[6]); # VGH&VGL
- self.send_data(self.Voltage_Frame_7IN5_V2[1]); # VSH
- self.send_data(self.Voltage_Frame_7IN5_V2[2]); # VSL
- self.send_data(self.Voltage_Frame_7IN5_V2[3]); # VSHR
-
- self.send_command(0x82); # VCOM DC Setting
- self.send_data(self.Voltage_Frame_7IN5_V2[4]); # VCOM
-
- self.send_command(0x06); # Booster Setting
- self.send_data(0x27);
- self.send_data(0x27);
- self.send_data(0x2F);
- self.send_data(0x17);
-
- self.send_command(0x30); # OSC Setting
- self.send_data(self.Voltage_Frame_7IN5_V2[0]); # 2-0=100: N=4 ; 5-3=111: M=7 ; 3C=50Hz 3A=100HZ
-
- self.send_command(0x04) #POWER ON
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- self.send_command(0X00) #PANNEL SETTING
- self.send_data(0x3F) #KW-3f KWR-2F BWROTP 0f BWOTP 1f
-
- self.send_command(0x61) #tres
- self.send_data(0x03) #source 800
- self.send_data(0x20)
- self.send_data(0x01) #gate 480
- self.send_data(0xE0)
-
- self.send_command(0X15)
- self.send_data(0x00)
-
- self.send_command(0X50) #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x10)
- self.send_data(0x07)
-
- self.send_command(0X60) #TCON SETTING
- self.send_data(0x22)
-
- self.send_command(0x65); # Resolution setting
- self.send_data(0x00);
- self.send_data(0x00); # 800*480
- self.send_data(0x00);
- self.send_data(0x00);
-
- self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
- # EPD hardware init end
- return 0
-
- def getbuffer(self, image):
- img = image
- imwidth, imheight = img.size
- if(imwidth == self.width and imheight == self.height):
- img = img.convert('1')
- elif(imwidth == self.height and imheight == self.width):
- # image has correct dimensions, but needs to be rotated
- img = img.rotate(90, expand=True).convert('1')
- else:
- logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
- # return a blank buffer
- return [0x00] * (int(self.width/8) * self.height)
-
- buf = bytearray(img.tobytes('raw'))
- # The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
- # in the e-paper world 0=white and 1=black.
- for i in range(len(buf)):
- buf[i] ^= 0xFF
- return buf
-
- def display(self, image):
- self.send_command(0x13)
- self.send_data2(image)
-
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- buf = [0x00] * (int(self.width/8) * self.height)
- self.send_command(0x10)
- self.send_data2(buf)
- self.send_command(0x13)
- self.send_data2(buf)
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
-
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5b_HD.py b/lib/epd7in5b_HD.py
deleted file mode 100644
index 89f7979..0000000
--- a/lib/epd7in5b_HD.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5bc_HD.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 880
-EPD_HEIGHT = 528
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(4)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- busy = epdconfig.digital_read(self.busy_pin)
- while(busy == 1):
- busy = epdconfig.digital_read(self.busy_pin)
- epdconfig.delay_ms(200)
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x12); #SWRESET
- self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x46); # Auto Write RAM
- self.send_data(0xF7);
- self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x47); # Auto Write RAM
- self.send_data(0xF7);
- self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x0C); # Soft start setting
- self.send_data(0xAE);
- self.send_data(0xC7);
- self.send_data(0xC3);
- self.send_data(0xC0);
- self.send_data(0x40);
-
- self.send_command(0x01); # Set MUX as 527
- self.send_data(0xAF);
- self.send_data(0x02);
- self.send_data(0x01);
-
- self.send_command(0x11); # Data entry mode
- self.send_data(0x01);
-
- self.send_command(0x44);
- self.send_data(0x00); # RAM x address start at 0
- self.send_data(0x00);
- self.send_data(0x6F); # RAM x address end at 36Fh -> 879
- self.send_data(0x03);
- self.send_command(0x45);
- self.send_data(0xAF); # RAM y address start at 20Fh;
- self.send_data(0x02);
- self.send_data(0x00); # RAM y address end at 00h;
- self.send_data(0x00);
-
- self.send_command(0x3C); # VBD
- self.send_data(0x01); # LUT1, for white
-
- self.send_command(0x18);
- self.send_data(0X80);
- self.send_command(0x22);
- self.send_data(0XB1); #Load Temperature and waveform setting.
- self.send_command(0x20);
- self.ReadBusy(); #waiting for the electronic paper IC to release the idle signal
-
- self.send_command(0x4E);
- self.send_data(0x00);
- self.send_data(0x00);
- self.send_command(0x4F);
- self.send_data(0xAF);
- self.send_data(0x02);
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x4F);
- self.send_data(0xAf);
-
- self.send_command(0x24)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i]);
-
-
- self.send_command(0x26)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~imagered[i]);
-
- self.send_command(0x22);
- self.send_data(0xC7); #Load LUT from MCU(0x32)
- self.send_command(0x20);
- epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!!
- self.ReadBusy();
-
- def Clear(self):
- self.send_command(0x4F);
- self.send_data(0xAf);
-
- self.send_command(0x24)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff);
-
-
- self.send_command(0x26)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00);
-
- self.send_command(0x22);
- self.send_data(0xC7); #Load LUT from MCU(0x32)
- self.send_command(0x20);
- epdconfig.delay_ms(200); #!!!The delay here is necessary, 200uS at least!!!
- self.ReadBusy();
-
- def sleep(self):
- self.send_command(0x10); #deep sleep
- self.send_data(0x01);
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5b_V2.py b/lib/epd7in5b_V2.py
deleted file mode 100644
index bdbd7c5..0000000
--- a/lib/epd7in5b_V2.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5b_V2.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.1
-# * | Date : 2020-11-30
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 800
-EPD_HEIGHT = 480
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(4)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- while(busy == 0):
- self.send_command(0x71)
- busy = epdconfig.digital_read(self.busy_pin)
- epdconfig.delay_ms(200)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- # self.send_command(0x06) # btst
- # self.send_data(0x17)
- # self.send_data(0x17)
- # self.send_data(0x38) # If an exception is displayed, try using 0x38
- # self.send_data(0x17)
-
- self.send_command(0x01); #POWER SETTING
- self.send_data(0x07);
- self.send_data(0x07); #VGH=20V,VGL=-20V
- self.send_data(0x3f); #VDH=15V
- self.send_data(0x3f); #VDL=-15V
-
- self.send_command(0x04); #POWER ON
- epdconfig.delay_ms(100);
- self.ReadBusy();
-
- self.send_command(0X00); #PANNEL SETTING
- self.send_data(0x0F); #KW-3f KWR-2F BWROTP 0f BWOTP 1f
-
- self.send_command(0x61); #tres
- self.send_data(0x03); #source 800
- self.send_data(0x20);
- self.send_data(0x01); #gate 480
- self.send_data(0xE0);
-
- self.send_command(0X15);
- self.send_data(0x00);
-
- self.send_command(0X50); #VCOM AND DATA INTERVAL SETTING
- self.send_data(0x11);
- self.send_data(0x07);
-
- self.send_command(0X60); #TCON SETTING
- self.send_data(0x22);
-
- self.send_command(0x65);
- self.send_data(0x00);
- self.send_data(0x00);
- self.send_data(0x00);
- self.send_data(0x00);
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(imageblack[i]);
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(~imagered[i]);
-
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0xff)
-
- self.send_command(0x13)
- for i in range(0, int(self.width * self.height / 8)):
- self.send_data(0x00)
-
- self.send_command(0x12)
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
-
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epd7in5bc.py b/lib/epd7in5bc.py
deleted file mode 100644
index 14c491c..0000000
--- a/lib/epd7in5bc.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# *****************************************************************************
-# * | File : epd7in5bc.py
-# * | Author : Waveshare team
-# * | Function : Electronic paper driver
-# * | Info :
-# *----------------
-# * | This version: V4.0
-# * | Date : 2019-06-20
-# # | Info : python demo
-# -----------------------------------------------------------------------------
-# 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 logging
-from . import epdconfig
-
-# Display resolution
-EPD_WIDTH = 640
-EPD_HEIGHT = 384
-
-logger = logging.getLogger(__name__)
-
-class EPD:
- def __init__(self):
- self.reset_pin = epdconfig.RST_PIN
- self.dc_pin = epdconfig.DC_PIN
- self.busy_pin = epdconfig.BUSY_PIN
- self.cs_pin = epdconfig.CS_PIN
- self.width = EPD_WIDTH
- self.height = EPD_HEIGHT
-
- # Hardware reset
- def reset(self):
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
- epdconfig.digital_write(self.reset_pin, 0)
- epdconfig.delay_ms(5)
- epdconfig.digital_write(self.reset_pin, 1)
- epdconfig.delay_ms(200)
-
- def send_command(self, command):
- epdconfig.digital_write(self.dc_pin, 0)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([command])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def send_data(self, data):
- epdconfig.digital_write(self.dc_pin, 1)
- epdconfig.digital_write(self.cs_pin, 0)
- epdconfig.spi_writebyte([data])
- epdconfig.digital_write(self.cs_pin, 1)
-
- def ReadBusy(self):
- logger.debug("e-Paper busy")
- while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy
- epdconfig.delay_ms(100)
- logger.debug("e-Paper busy release")
-
- def init(self):
- if (epdconfig.module_init() != 0):
- return -1
-
- self.reset()
-
- self.send_command(0x01) # POWER_SETTING
- self.send_data(0x37)
- self.send_data(0x00)
-
- self.send_command(0x00) # PANEL_SETTING
- self.send_data(0xCF)
- self.send_data(0x08)
-
- self.send_command(0x30) # PLL_CONTROL
- self.send_data(0x3A) # PLL: 0-15:0x3C, 15+:0x3A
-
- self.send_command(0x82) # VCM_DC_SETTING
- self.send_data(0x28) #all temperature range
-
- self.send_command(0x06) # BOOSTER_SOFT_START
- self.send_data(0xc7)
- self.send_data(0xcc)
- self.send_data(0x15)
-
- self.send_command(0x50) # VCOM AND DATA INTERVAL SETTING
- self.send_data(0x77)
-
- self.send_command(0x60) # TCON_SETTING
- self.send_data(0x22)
-
- self.send_command(0x65) # FLASH CONTROL
- self.send_data(0x00)
-
- self.send_command(0x61) # TCON_RESOLUTION
- self.send_data(self.width >> 8) # source 640
- self.send_data(self.width & 0xff)
- self.send_data(self.height >> 8) # gate 384
- self.send_data(self.height & 0xff)
-
- self.send_command(0xe5) # FLASH MODE
- self.send_data(0x03)
-
- return 0
-
- def getbuffer(self, image):
- # logger.debug("bufsiz = ",int(self.width/8) * self.height)
- buf = [0xFF] * (int(self.width/8) * self.height)
- image_monocolor = image.convert('1')
- imwidth, imheight = image_monocolor.size
- pixels = image_monocolor.load()
- logger.debug('imwidth = %d imheight = %d ',imwidth, imheight)
- if(imwidth == self.width and imheight == self.height):
- logger.debug("Horizontal")
- for y in range(imheight):
- for x in range(imwidth):
- # Set the bits for the column of pixels at the current position.
- if pixels[x, y] == 0:
- buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
- elif(imwidth == self.height and imheight == self.width):
- logger.debug("Vertical")
- for y in range(imheight):
- for x in range(imwidth):
- newx = y
- newy = self.height - x - 1
- if pixels[x, y] == 0:
- buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8))
- return buf
-
- def display(self, imageblack, imagered):
- self.send_command(0x10)
- for i in range(0, int(self.width / 8 * self.height)):
- temp1 = imageblack[i]
- temp2 = imagered[i]
- j = 0
- while (j < 8):
- if ((temp2 & 0x80) == 0x00):
- temp3 = 0x04 #red
- elif ((temp1 & 0x80) == 0x00):
- temp3 = 0x00 #black
- else:
- temp3 = 0x03 #white
-
- temp3 = (temp3 << 4) & 0xFF
- temp1 = (temp1 << 1) & 0xFF
- temp2 = (temp2 << 1) & 0xFF
- j += 1
- if((temp2 & 0x80) == 0x00):
- temp3 |= 0x04 #red
- elif ((temp1 & 0x80) == 0x00):
- temp3 |= 0x00 #black
- else:
- temp3 |= 0x03 #white
- temp1 = (temp1 << 1) & 0xFF
- temp2 = (temp2 << 1) & 0xFF
- self.send_data(temp3)
- j += 1
-
- self.send_command(0x04) # POWER ON
- self.ReadBusy()
- self.send_command(0x12) # display refresh
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def Clear(self):
- self.send_command(0x10)
- for i in range(0, int(self.width / 8 * self.height)):
- self.send_data(0x33)
- self.send_data(0x33)
- self.send_data(0x33)
- self.send_data(0x33)
-
- self.send_command(0x04) # POWER ON
- self.ReadBusy()
- self.send_command(0x12) # display refresh
- epdconfig.delay_ms(100)
- self.ReadBusy()
-
- def sleep(self):
- self.send_command(0x02) # POWER_OFF
- self.ReadBusy()
-
- self.send_command(0x07) # DEEP_SLEEP
- self.send_data(0XA5)
-
- epdconfig.delay_ms(2000)
- epdconfig.module_exit()
-### END OF FILE ###
-
diff --git a/lib/epdconfig.py b/lib/epdconfig.py
deleted file mode 100644
index 6095138..0000000
--- a/lib/epdconfig.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# /*****************************************************************************
-# * | File : epdconfig.py
-# * | Author : Waveshare team
-# * | Function : Hardware underlying interface
-# * | Info :
-# *----------------
-# * | This version: V1.0
-# * | Date : 2019-06-21
-# * | Info :
-# ******************************************************************************
-# 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 os
-import logging
-import sys
-import time
-
-logger = logging.getLogger(__name__)
-
-
-class RaspberryPi:
- # Pin definition
- RST_PIN = 17
- DC_PIN = 25
- CS_PIN = 8
- BUSY_PIN = 24
-
- def __init__(self):
- import spidev
- import RPi.GPIO
-
- self.GPIO = RPi.GPIO
- self.SPI = spidev.SpiDev()
-
- def digital_write(self, pin, value):
- self.GPIO.output(pin, value)
-
- def digital_read(self, pin):
- return self.GPIO.input(pin)
-
- def delay_ms(self, delaytime):
- time.sleep(delaytime / 1000.0)
-
- def spi_writebyte(self, data):
- self.SPI.writebytes(data)
-
- def spi_writebyte2(self, data):
- self.SPI.writebytes2(data)
-
- def module_init(self):
- self.GPIO.setmode(self.GPIO.BCM)
- self.GPIO.setwarnings(False)
- self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
-
- # SPI device, bus = 0, device = 0
- self.SPI.open(0, 0)
- self.SPI.max_speed_hz = 4000000
- self.SPI.mode = 0b00
- return 0
-
- def module_exit(self):
- logger.debug("spi end")
- self.SPI.close()
-
- logger.debug("close 5V, Module enters 0 power consumption ...")
- self.GPIO.output(self.RST_PIN, 0)
- self.GPIO.output(self.DC_PIN, 0)
-
- self.GPIO.cleanup()
-
-
-class JetsonNano:
- # Pin definition
- RST_PIN = 17
- DC_PIN = 25
- CS_PIN = 8
- BUSY_PIN = 24
-
- def __init__(self):
- import ctypes
- find_dirs = [
- os.path.dirname(os.path.realpath(__file__)),
- '/usr/local/lib',
- '/usr/lib',
- ]
- self.SPI = None
- for find_dir in find_dirs:
- so_filename = os.path.join(find_dir, 'sysfs_software_spi.so')
- if os.path.exists(so_filename):
- self.SPI = ctypes.cdll.LoadLibrary(so_filename)
- break
- if self.SPI is None:
- raise RuntimeError('Cannot find sysfs_software_spi.so')
-
- import Jetson.GPIO
- self.GPIO = Jetson.GPIO
-
- def digital_write(self, pin, value):
- self.GPIO.output(pin, value)
-
- def digital_read(self, pin):
- return self.GPIO.input(self.BUSY_PIN)
-
- def delay_ms(self, delaytime):
- time.sleep(delaytime / 1000.0)
-
- def spi_writebyte(self, data):
- self.SPI.SYSFS_software_spi_transfer(data[0])
-
- def module_init(self):
- self.GPIO.setmode(self.GPIO.BCM)
- self.GPIO.setwarnings(False)
- self.GPIO.setup(self.RST_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.DC_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.CS_PIN, self.GPIO.OUT)
- self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN)
- self.SPI.SYSFS_software_spi_begin()
- return 0
-
- def module_exit(self):
- logger.debug("spi end")
- self.SPI.SYSFS_software_spi_end()
-
- logger.debug("close 5V, Module enters 0 power consumption ...")
- self.GPIO.output(self.RST_PIN, 0)
- self.GPIO.output(self.DC_PIN, 0)
-
- self.GPIO.cleanup()
-
-
-if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'):
- implementation = RaspberryPi()
-else:
- implementation = JetsonNano()
-
-for func in [x for x in dir(implementation) if not x.startswith('_')]:
- setattr(sys.modules[__name__], func, getattr(implementation, func))
-
-
-### END OF FILE ###
diff --git a/lib/info.txt b/lib/info.txt
deleted file mode 100644
index f85fd07..0000000
--- a/lib/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-This libary is from waveshare: https://github.com/waveshare/e-Paper/tree/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd
diff --git a/lib/sysfs_gpio.so b/lib/sysfs_gpio.so
deleted file mode 100644
index b8d9cdd..0000000
Binary files a/lib/sysfs_gpio.so and /dev/null differ
diff --git a/lib/sysfs_software_spi.so b/lib/sysfs_software_spi.so
deleted file mode 100644
index f9ff3a6..0000000
Binary files a/lib/sysfs_software_spi.so and /dev/null differ
diff --git a/pictures/battery icons.psd b/pictures/battery icons.psd
new file mode 100644
index 0000000..deb510f
Binary files /dev/null and b/pictures/battery icons.psd differ
diff --git a/pictures/battery-icon-1_3.bmp b/pictures/battery-icon-1_3.bmp
new file mode 100644
index 0000000..b8768dd
Binary files /dev/null and b/pictures/battery-icon-1_3.bmp differ
diff --git a/pictures/battery-icon-2_3.bmp b/pictures/battery-icon-2_3.bmp
new file mode 100644
index 0000000..fbad1b8
Binary files /dev/null and b/pictures/battery-icon-2_3.bmp differ
diff --git a/pictures/battery-icon-3_3.bmp b/pictures/battery-icon-3_3.bmp
new file mode 100644
index 0000000..0bce3b0
Binary files /dev/null and b/pictures/battery-icon-3_3.bmp differ
diff --git a/pictures/battery-icon-charging.bmp b/pictures/battery-icon-charging.bmp
new file mode 100644
index 0000000..fb86287
Binary files /dev/null and b/pictures/battery-icon-charging.bmp differ
diff --git a/pictures/battery-icon-empty.bmp b/pictures/battery-icon-empty.bmp
new file mode 100644
index 0000000..e20019a
Binary files /dev/null and b/pictures/battery-icon-empty.bmp differ
diff --git a/pictures/battery-icons-cable.bmp b/pictures/battery-icons-cable.bmp
new file mode 100644
index 0000000..35b5b6b
Binary files /dev/null and b/pictures/battery-icons-cable.bmp differ
diff --git a/pictures/battery/battery icons.psd b/pictures/battery/battery icons.psd
new file mode 100644
index 0000000..0628842
Binary files /dev/null and b/pictures/battery/battery icons.psd differ
diff --git a/requirements.txt b/requirements.txt
index cd58513..b73729a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,15 @@
icalevents
+holidays
numpy
vobject
lxml
schedule
Pillow
-requests
\ No newline at end of file
+requests
+pigpio
+RPi.GPIO
+lgpio
+gpiozero
+spidev
+requests
+smbus2
\ No newline at end of file
diff --git a/run_calendar.py b/run_calendar.py
index ed011bf..7fb027a 100644
--- a/run_calendar.py
+++ b/run_calendar.py
@@ -4,7 +4,7 @@
import displayRun
-
+#Do not use when using witty pi (to use and schedule in a chron job)
def main():
schedule.every().day.at("00:00").do(displayRun.main)
schedule.every(12).hours.do(displayRun.main)
diff --git a/run_calendar.sh b/run_calendar.sh
index 487376c..8a94908 100755
--- a/run_calendar.sh
+++ b/run_calendar.sh
@@ -1,3 +1,5 @@
#!/bin/bash
cd $(dirname $0)
-python3 ./run_calendar.py
\ No newline at end of file
+source ./venv/bin/activate
+#The path can relative as the activation of the environment will have defined the correct one
+python ./displayRun.py
diff --git a/run_calendar_witty.sh b/run_calendar_witty.sh
new file mode 100755
index 0000000..668a14b
--- /dev/null
+++ b/run_calendar_witty.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+
+#Will run the script for refreshing the screen and then shutdown the system.
+cd $(dirname $0)
+
+./run_calendar.sh
+
+# Check if the startup was due to a schedule in witty pi
+#Get the reason of the startup
+result=$(/usr/sbin/i2cget -y 1 0x08 11)
+#If is 1 is was due to ALARM1 that is the alarm for the scheduled startup
+if [[ "$result" == "0x01" ]]; then
+ echo "Startup due to schelude in witty pi. Will shutdown in 20s"
+ for i in {20..1}
+ do
+ echo "$i"
+ sleep 1
+ done
+ # If the result is 1, run the shutdown command
+ /usr/bin/sudo shutdown -h +1
+else
+ echo "No scheduled startup detected. The system will not be shutting down."
+fi
diff --git a/settings.py.sample b/settings.py.sample
index dfa3674..5462f86 100644
--- a/settings.py.sample
+++ b/settings.py.sample
@@ -1,10 +1,55 @@
LOCALE = "de_DE"
-WEBDAV_CALENDAR_URL = "webcal://..."
-WEBDAV_IS_APPLE = True
+# "pattern_fill" can be BLACK, RED, VERTICALSTRIPES, HORIZONTALSTRIPES, DIAGONALSTRIPESLOWERRIGHT, DIAGONALSTRIPESUPPERRIGHT
+# with "pattern_red_stripes" when true a red color will be used in the striped patterns instead of white.
+WEBDAV_CALENDAR_URLS = [
+ {
+ "url": "webcal://...",
+ "calendar_name": "a name",
+ "is_apple": True,
+ "pattern_fill": "DIAGONALSTRIPESUPPERRIGHT",
+ "pattern_red_stripes": False
+
+ },
+ {
+ "url": "webcal://...2",
+ "calendar_name": "a name2",
+ "is_apple": True,
+ "pattern_fill": "VERTICALSTRIPES",
+ "pattern_red_stripes": False
+
+ },
+]
CALDAV_CONTACT_URL = "https://..."
CALDAV_CONTACT_USER = "username"
CALDAV_CONTACT_PWD = "passw0rd"
-ROTATE_IMAGE = True
\ No newline at end of file
+ROTATE_IMAGE = True
+
+#Aperture Science Decorations
+APERTURE_DECORATIONS = True
+
+#True if the first day of the week is sunday. False to be Monday
+FIRST_WEEKDAY_IS_SUNDAY = True
+
+#For accessing the weather please go to tomorrow.io register for a free account and insert the key here. Empty or commented so to not show the weather.
+TOMORROWIO_API_KEY = "[insert api key here]"
+
+#Location for weather forecast.
+#A latitude-longitude pair of numbers according to ISO 6709, separated by , in query parameters
+#See also https://docs.tomorrow.io/reference/api-formats#locations
+#Sample is for Hamburg DE
+WEATHER_LOCATION = "53.551086,9.993682"
+
+#Temperature Units (can be C for Celsius or F for Fahrenheit), the default is C
+TEMPERATURE_UNIT = "C"
+
+#Will show a random quotes on the bottom of the screen
+SHOW_QUOTES = True
+
+#Voltage were the device should notify for a recharge (consult your battery datasheet).
+RECHARGE_VOlTAGE = 3.5
+
+#Debug mode. It will write to disk the image and not to the screen.
+DEBUG = False
\ No newline at end of file
diff --git a/submodules/waveshare_e-paper b/submodules/waveshare_e-paper
new file mode 160000
index 0000000..aabe2c1
--- /dev/null
+++ b/submodules/waveshare_e-paper
@@ -0,0 +1 @@
+Subproject commit aabe2c1fcafee01b01d9a06ed589ca5d67e52424
diff --git a/weatherCodesEmoji.py b/weatherCodesEmoji.py
new file mode 100644
index 0000000..cf2f344
--- /dev/null
+++ b/weatherCodesEmoji.py
@@ -0,0 +1,291 @@
+wheater_codes_emojis = {
+ 0: "❓",
+ 1000: "☀️",
+ 1100: "🌤️",
+ 1101: "⛅",
+ 1102: "🌥️",
+ 1001: "☁️",
+ 2000: "🌫️",
+ 2100: "🌁",
+ 4000: "🌦️",
+ 4001: "🌧️",
+ 4200: "🌦️",
+ 4201: "🌧️💧",
+ 5000: "❄️",
+ 5001: "🌨️",
+ 5100: "🌨️",
+ 5101: "❄️❄️",
+ 6000: "🌧️❄️",
+ 6001: "🌧️❄️",
+ 6200: "🌧️❄️",
+ 6201: "🌧️❄️",
+ 7000: "🧊❄️",
+ 7101: "🧊❄️❄️",
+ 7102: "🧊🌨️",
+ 8000: "⛈️",
+ # weatherCodeFullDay
+ 1103: "⛅🌤️",
+ 2101: "🌤️🌁",
+ 2102: "⛅🌁",
+ 2103: "🌥️🌁",
+ 2106: "🌤️🌫️",
+ 2107: "⛅🌫️",
+ 2108: "🌥️🌫️",
+ 4204: "⛅🌦️",
+ 4203: "🌤️🌦️",
+ 4205: "🌥️🌦️",
+ 4213: "🌤️🌦️",
+ 4214: "⛅🌦️",
+ 4215: "🌥️🌦️",
+ 4209: "🌤️🌧️",
+ 4208: "⛅🌧️",
+ 4210: "🌥️🌧️",
+ 4211: "🌤️🌧️💧",
+ 4202: "⛅🌧️💧",
+ 4212: "🌥️🌧️💧",
+ 5115: "🌤️🌨️",
+ 5116: "⛅🌨️",
+ 5117: "🌥️🌨️",
+ 5102: "🌤️🌨️",
+ 5103: "⛅🌨️",
+ 5104: "🌥️🌨️",
+ 5122: "🌦️🌨️",
+ 5105: "🌤️❄️",
+ 5106: "⛅❄️",
+ 5107: "🌥️❄️",
+ 5119: "🌤️❄️❄️",
+ 5120: "⛅❄️❄️",
+ 5121: "🌥️❄️❄️",
+ 5110: "🌦️❄️",
+ 5108: "🌧️❄️",
+ 5114: "❄️🌧️",
+ 5112: "❄️🧊",
+ 6000: "🌧️🧊",
+ 6003: "🌤️🌧️🧊",
+ 6002: "⛅🌧️🧊",
+ 6004: "🌥️🌧️🧊",
+ 6204: "🌦️🧊",
+ 6206: "🌧️🧊",
+ 6205: "🌤️🌧️🧊",
+ 6203: "⛅🌧️🧊",
+ 6209: "🌥️🌧️🧊",
+ 6200: "🌧️🧊",
+ 6213: "🌤️🌧️🧊",
+ 6214: "⛅🌧️🧊",
+ 6215: "🌥️🌧️🧊",
+ 6001: "🌧️🧊",
+ 6212: "🌦️🌧️🧊",
+ 6220: "🌧️🧊",
+ 6222: "🌧️🧊",
+ 6207: "🌤️❄️🧊",
+ 6202: "⛅❄️🧊",
+ 6208: "🌥️❄️🧊",
+ 6201: "❄️🧊",
+ 7110: "🌤️🧊",
+ 7111: "⛅🧊",
+ 7112: "🌥️🧊",
+ 7102: "🌨️🧊",
+ 7108: "🌤️🧊",
+ 7107: "⛅🧊",
+ 7109: "🌥️🧊",
+ 7000: "🧊",
+ 7105: "🌦️🧊",
+ 7106: "❄️🧊",
+ 7115: "🌧️🧊",
+ 7117: "🌧️🧊",
+ 7103: "❄️🧊❄️",
+ 7113: "🌤️❄️🧊",
+ 7114: "⛅❄️🧊",
+ 7116: "🌥️❄️🧊",
+ 8001: "🌤️⛈️",
+ 8003: "⛅⛈️",
+ 8002: "🌥️⛈️",
+ #weatherCodeDay
+ 10000: "☀️",
+ 11000: "🌤️",
+ 11010: "⛅",
+ 11020: "🌥️",
+ 10010: "☁️",
+ 11030: "⛅🌤️",
+ 21000: "🌁",
+ 21010: "🌤️🌁",
+ 21020: "⛅🌁",
+ 21030: "🌥️🌁",
+ 21060: "🌤️🌫️",
+ 21070: "⛅🌫️",
+ 21080: "🌥️🌫️",
+ 20000: "🌫️",
+ 42040: "⛅🌦️",
+ 42030: "🌤️🌦️",
+ 42050: "🌥️🌦️",
+ 40000: "🌦️",
+ 42000: "🌦️",
+ 42130: "🌤️🌦️",
+ 42140: "⛅🌦️",
+ 42150: "🌥️🌦️",
+ 42090: "🌤️🌧️",
+ 42080: "⛅🌧️",
+ 42100: "🌥️🌧️",
+ 40010: "🌧️",
+ 42110: "🌤️🌧️💧",
+ 42020: "⛅🌧️💧",
+ 42120: "🌥️🌧️💧",
+ 42010: "🌧️💧",
+ 51150: "🌤️🌨️",
+ 51160: "⛅🌨️",
+ 51170: "🌥️🌨️",
+ 50010: "🌨️",
+ 51000: "🌨️",
+ 51020: "🌤️🌨️",
+ 51030: "⛅🌨️",
+ 51040: "🌥️🌨️",
+ 51220: "🌦️🌨️",
+ 51050: "🌤️❄️",
+ 51060: "⛅❄️",
+ 51070: "🌥️❄️",
+ 50000: "❄️",
+ 51010: "❄️❄️",
+ 51190: "🌤️❄️❄️",
+ 51200: "⛅❄️❄️",
+ 51210: "🌥️❄️❄️",
+ 51100: "🌦️❄️",
+ 51080: "🌧️❄️",
+ 51140: "❄️🌧️",
+ 51120: "❄️🧊",
+ 60000: "🌧️🧊",
+ 60030: "🌤️🌧️🧊",
+ 60020: "⛅🌧️🧊",
+ 60040: "🌥️🌧️🧊",
+ 62040: "🌦️🧊",
+ 62060: "🌧️🧊",
+ 62050: "🌤️🌧️🧊",
+ 62030: "⛅🌧️🧊",
+ 62090: "🌥️🌧️🧊",
+ 62000: "🌧️🧊",
+ 62130: "🌤️🌧️🧊",
+ 62140: "⛅🌧️🧊",
+ 62150: "🌥️🌧️🧊",
+ 60010: "🌧️🧊",
+ 62120: "🌦️🌧️🧊",
+ 62200: "🌧️🧊",
+ 62220: "🌧️🧊",
+ 62070: "🌤️❄️🧊",
+ 62020: "⛅❄️🧊",
+ 62080: "🌥️❄️🧊",
+ 62010: "❄️🧊",
+ 71100: "🌤️🧊",
+ 71110: "⛅🧊",
+ 71120: "🌥️🧊",
+ 71020: "🌨️🧊",
+ 71080: "🌤️🧊",
+ 71070: "⛅🧊",
+ 71090: "🌥️🧊",
+ 70000: "🧊",
+ 71050: "🌦️🧊",
+ 71060: "❄️🧊",
+ 71150: "🌧️🧊",
+ 71170: "🌧️🧊",
+ 71030: "❄️🧊❄️",
+ 71130: "🌤️❄️🧊",
+ 71140: "⛅❄️🧊",
+ 71160: "🌥️❄️🧊",
+ 71010: "🧊❄️❄️",
+ 80010: "🌤️⛈️",
+ 80030: "⛅⛈️",
+ 80020: "🌥️⛈️",
+ 80000: "⛈️",
+ #weatherCodeNight
+ 10001: "🌙",
+ 11001: "🌙🌤️",
+ 11011: "🌙⛅",
+ 11021: "🌙🌥️",
+ 10011: "🌙☁️",
+ 11031: "🌙⛅🌤️",
+ 21001: "🌙🌁",
+ 21011: "🌙🌤️🌁",
+ 21021: "🌙⛅🌁",
+ 21031: "🌙🌥️🌁",
+ 21061: "🌙🌤️🌫️",
+ 21071: "🌙⛅🌫️",
+ 21081: "🌙🌥️🌫️",
+ 20001: "🌙🌫️",
+ 42041: "🌙⛅🌦️",
+ 42031: "🌙🌤️🌦️",
+ 42051: "🌙🌥️🌦️",
+ 40001: "🌙🌦️",
+ 42001: "🌙🌦️",
+ 42131: "🌙🌤️🌦️",
+ 42141: "🌙⛅🌦️",
+ 42151: "🌙🌥️🌦️",
+ 42091: "🌙🌤️🌧️",
+ 42081: "🌙⛅🌧️",
+ 42101: "🌙🌥️🌧️",
+ 40011: "🌙🌧️",
+ 42111: "🌙🌤️🌧️💧",
+ 42021: "🌙⛅🌧️💧",
+ 42121: "🌙🌥️🌧️💧",
+ 42011: "🌙🌧️💧",
+ 51151: "🌙🌤️🌨️",
+ 51161: "🌙⛅🌨️",
+ 51171: "🌙🌥️🌨️",
+ 50011: "🌙🌨️",
+ 51001: "🌙🌨️",
+ 51021: "🌙🌤️🌨️",
+ 51031: "🌙⛅🌨️",
+ 51041: "🌙🌥️🌨️",
+ 51221: "🌙🌦️🌨️",
+ 51051: "🌙🌤️❄️",
+ 51061: "🌙⛅❄️",
+ 51071: "🌙🌥️❄️",
+ 50001: "🌙❄️",
+ 51011: "🌙❄️❄️",
+ 51191: "🌙🌤️❄️❄️",
+ 51201: "🌙⛅❄️❄️",
+ 51211: "🌙🌥️❄️❄️",
+ 51101: "🌙🌦️❄️",
+ 51081: "🌙🌧️❄️",
+ 51141: "🌙❄️🌧️",
+ 51121: "🌙❄️🧊",
+ 60001: "🌙🌧️🧊",
+ 60031: "🌙🌤️🌧️🧊",
+ 60021: "🌙⛅🌧️🧊",
+ 60041: "🌙🌥️🌧️🧊",
+ 62041: "🌙🌦️🧊",
+ 62061: "🌙🌧️🧊",
+ 62051: "🌙🌤️🌧️🧊",
+ 62031: "🌙⛅🌧️🧊",
+ 62091: "🌙🌥️🌧️🧊",
+ 62001: "🌙🌧️🧊",
+ 62131: "🌙🌤️🌧️🧊",
+ 62141: "🌙⛅🌧️🧊",
+ 62151: "🌙🌥️🌧️🧊",
+ 60011: "🌙🌧️🧊",
+ 62121: "🌙🌦️🌧️🧊",
+ 62201: "🌙🌧️🧊",
+ 62221: "🌙🌧️🧊",
+ 62071: "🌙🌤️❄️🧊",
+ 62021: "🌙⛅❄️🧊",
+ 62081: "🌙🌥️❄️🧊",
+ 62011: "🌙❄️🧊",
+ 71101: "🌙🌤️🧊",
+ 71111: "🌙⛅🧊",
+ 71121: "🌙🌥️🧊",
+ 71021: "🌙🌨️🧊",
+ 71081: "🌙🌤️🧊",
+ 71071: "🌙⛅🧊",
+ 71091: "🌙🌥️🧊",
+ 70001: "🌙🧊",
+ 71051: "🌙🌦️🧊",
+ 71061: "🌙❄️🧊",
+ 71151: "🌙🌧️🧊",
+ 71171: "🌙🌧️🧊",
+ 71031: "🌙❄️🧊❄️",
+ 71131: "🌙🌤️❄️🧊",
+ 71141: "🌙⛅❄️🧊",
+ 71161: "🌙🌥️❄️🧊",
+ 71011: "🌙🧊❄️❄️",
+ 80011: "🌙🌤️⛈️",
+ 80031: "🌙⛅⛈️",
+ 80021: "🌙🌥️⛈️",
+ 80001: "🌙⛈️"
+}