Touchscreen driver POC

Example documentation
This commit is contained in:
2026-05-07 16:28:08 -07:00
parent c0ad8306a7
commit a125f45b34
201 changed files with 19783 additions and 34 deletions
@@ -0,0 +1,236 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic/2in13')
fontdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
from TP_lib import gt1151
from TP_lib import epd2in13_V3
import time
import logging
from PIL import Image,ImageDraw,ImageFont
import traceback
import threading
logging.basicConfig(level=logging.DEBUG)
flag_t = 1
def pthread_irq() :
print("pthread running")
while flag_t == 1 :
if(gt.digital_read(gt.INT) == 0) :
GT_Dev.Touch = 1
else :
GT_Dev.Touch = 0
print("thread:exit")
def Show_Photo_Small(image, small):
for t in range(1, 5):
if(small*2+t > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_S[0]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_S[small*2+t]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
def Show_Photo_Large(image, large):
if(large > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_L[0]))
image.paste(newimage, (2, 2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_L[large]))
image.paste(newimage, (2, 2))
def Read_BMP(File, x, y):
newimage = Image.open(os.path.join(picdir, File))
image.paste(newimage, (x, y))
try:
logging.info("epd2in13_V3 Touch Demo")
epd = epd2in13_V3.EPD()
gt = gt1151.GT1151()
GT_Dev = gt1151.GT_Development()
GT_Old = gt1151.GT_Development()
logging.info("init and Clear")
epd.init(epd.FULL_UPDATE)
gt.GT_Init()
epd.Clear(0xFF)
t = threading.Thread(target = pthread_irq)
t.daemon = True
t.start()
# Drawing on the image
font15 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 15)
font24 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 24)
image = Image.open(os.path.join(picdir, 'Menu.bmp'))
epd.displayPartBaseImage(epd.getbuffer(image))
DrawImage = ImageDraw.Draw(image)
epd.init(epd.PART_UPDATE)
i = j = k = ReFlag = SelfFlag = Page = Photo_L = Photo_S = 0
PhotoPath_S = [ "Photo_1_0.bmp",
"Photo_1_1.bmp", "Photo_1_2.bmp", "Photo_1_3.bmp", "Photo_1_4.bmp",
"Photo_1_5.bmp", "Photo_1_6.bmp",
]
PhotoPath_L = [ "Photo_2_0.bmp",
"Photo_2_1.bmp", "Photo_2_2.bmp", "Photo_2_3.bmp", "Photo_2_4.bmp",
"Photo_2_5.bmp", "Photo_2_6.bmp",
]
PagePath = ["Menu.bmp", "White_board.bmp", "Photo_1.bmp", "Photo_2.bmp"]
while(1):
if(i > 12 or ReFlag == 1):
if(Page == 1 and SelfFlag == 0):
epd.displayPartial(epd.getbuffer(image))
else:
epd.displayPartial_Wait(epd.getbuffer(image))
i = 0
k = 0
j += 1
ReFlag = 0
print("*** Draw Refresh ***\r\n")
elif(k>50000 and i>0 and Page == 1):
epd.displayPartial(epd.getbuffer(image))
i = 0
k = 0
j += 1
print("*** Overtime Refresh ***\r\n")
elif(j > 50 or SelfFlag):
SelfFlag = 0
j = 0
epd.init(epd.FULL_UPDATE)
epd.displayPartBaseImage(epd.getbuffer(image))
epd.init(epd.PART_UPDATE)
print("--- Self Refresh ---\r\n")
else:
k += 1
# Read the touch input
gt.GT_Scan(GT_Dev, GT_Old)
if(GT_Old.X[0] == GT_Dev.X[0] and GT_Old.Y[0] == GT_Dev.Y[0] and GT_Old.S[0] == GT_Dev.S[0]):
continue
if(GT_Dev.TouchpointFlag):
i += 1
GT_Dev.TouchpointFlag = 0
if(Page == 0 and ReFlag == 0): #main menu
if(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 56 and GT_Dev.Y[0] < 95):
print("Photo ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 153 and GT_Dev.Y[0] < 193):
print("Draw ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
if(Page == 1 and ReFlag == 0): #white board
DrawImage.rectangle([(GT_Dev.X[0], GT_Dev.Y[0]), (GT_Dev.X[0] + GT_Dev.S[0]/8 + 1, GT_Dev.Y[0] + GT_Dev.S[0]/8 + 1)], fill=0)
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 6 and GT_Dev.Y[0] < 30):
print("Home ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Clear ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
if(Page == 2 and ReFlag == 0): #photo menu
if(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next page ...\r\n")
Photo_S += 1
if(Photo_S > 2): # 6 photos is a maximum of three pages
Photo_S=0
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_S == 0):
print("Top page ...\r\n")
else:
Photo_S -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
elif(GT_Dev.X[0] > 2 and GT_Dev.X[0] < 90 and GT_Dev.Y[0] > 2 and GT_Dev.Y[0] < 248 and ReFlag == 0):
print("Select photo ...\r\n")
Page = 3
Read_BMP(PagePath[Page], 0, 0)
Photo_L = int(GT_Dev.X[0]/46*2 + 2-GT_Dev.Y[0]/124 + Photo_S*2)
Show_Photo_Large(image, Photo_L)
ReFlag = 1
if(ReFlag == 2): # Refresh small photo
ReFlag = 1
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S) # show small photo
if(Page == 3 and ReFlag == 0): #view the photo
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 4 and GT_Dev.Y[0] < 25):
print("Photo menu ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next photo ...\r\n")
Photo_L += 1
if(Photo_L > 6):
Photo_L = 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_L == 1):
print("Top photo ...\r\n")
else:
Photo_L -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh photo ...\r\n")
SelfFlag = 1
ReFlag = 1
if(ReFlag == 2): # Refresh large photo
ReFlag = 1
Show_Photo_Large(image, Photo_L)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
flag_t = 0
epd.sleep()
time.sleep(2)
t.join()
epd.Dev_exit()
exit()
@@ -0,0 +1,236 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic/2in13')
fontdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
from TP_lib import gt1151
from TP_lib import epd2in13_V4
import time
import logging
from PIL import Image,ImageDraw,ImageFont
import traceback
import threading
logging.basicConfig(level=logging.DEBUG)
flag_t = 1
def pthread_irq() :
print("pthread running")
while flag_t == 1 :
if(gt.digital_read(gt.INT) == 0) :
GT_Dev.Touch = 1
else :
GT_Dev.Touch = 0
print("thread:exit")
def Show_Photo_Small(image, small):
for t in range(1, 5):
if(small*2+t > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_S[0]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_S[small*2+t]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
def Show_Photo_Large(image, large):
if(large > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_L[0]))
image.paste(newimage, (2, 2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_L[large]))
image.paste(newimage, (2, 2))
def Read_BMP(File, x, y):
newimage = Image.open(os.path.join(picdir, File))
image.paste(newimage, (x, y))
try:
logging.info("epd2in13_V4 Touch Demo")
epd = epd2in13_V4.EPD()
gt = gt1151.GT1151()
GT_Dev = gt1151.GT_Development()
GT_Old = gt1151.GT_Development()
logging.info("init and Clear")
epd.init(epd.FULL_UPDATE)
gt.GT_Init()
epd.Clear(0xFF)
t = threading.Thread(target = pthread_irq)
t.setDaemon(True)
t.start()
# Drawing on the image
font15 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 15)
font24 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 24)
image = Image.open(os.path.join(picdir, 'Menu.bmp'))
epd.displayPartBaseImage(epd.getbuffer(image))
DrawImage = ImageDraw.Draw(image)
epd.init(epd.PART_UPDATE)
i = j = k = ReFlag = SelfFlag = Page = Photo_L = Photo_S = 0
PhotoPath_S = [ "Photo_1_0.bmp",
"Photo_1_1.bmp", "Photo_1_2.bmp", "Photo_1_3.bmp", "Photo_1_4.bmp",
"Photo_1_5.bmp", "Photo_1_6.bmp",
]
PhotoPath_L = [ "Photo_2_0.bmp",
"Photo_2_1.bmp", "Photo_2_2.bmp", "Photo_2_3.bmp", "Photo_2_4.bmp",
"Photo_2_5.bmp", "Photo_2_6.bmp",
]
PagePath = ["Menu.bmp", "White_board.bmp", "Photo_1.bmp", "Photo_2.bmp"]
while(1):
if(i > 12 or ReFlag == 1):
if(Page == 1 and SelfFlag == 0):
epd.displayPartial(epd.getbuffer(image))
else:
epd.displayPartial_Wait(epd.getbuffer(image))
i = 0
k = 0
j += 1
ReFlag = 0
print("*** Draw Refresh ***\r\n")
elif(k>50000 and i>0 and Page == 1):
epd.displayPartial(epd.getbuffer(image))
i = 0
k = 0
j += 1
print("*** Overtime Refresh ***\r\n")
elif(j > 50 or SelfFlag):
SelfFlag = 0
j = 0
epd.init(epd.FULL_UPDATE)
epd.displayPartBaseImage(epd.getbuffer(image))
epd.init(epd.PART_UPDATE)
print("--- Self Refresh ---\r\n")
else:
k += 1
# Read the touch input
gt.GT_Scan(GT_Dev, GT_Old)
if(GT_Old.X[0] == GT_Dev.X[0] and GT_Old.Y[0] == GT_Dev.Y[0] and GT_Old.S[0] == GT_Dev.S[0]):
continue
if(GT_Dev.TouchpointFlag):
i += 1
GT_Dev.TouchpointFlag = 0
if(Page == 0 and ReFlag == 0): #main menu
if(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 56 and GT_Dev.Y[0] < 95):
print("Photo ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 153 and GT_Dev.Y[0] < 193):
print("Draw ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
if(Page == 1 and ReFlag == 0): #white board
DrawImage.rectangle([(GT_Dev.X[0], GT_Dev.Y[0]), (GT_Dev.X[0] + GT_Dev.S[0]/8 + 1, GT_Dev.Y[0] + GT_Dev.S[0]/8 + 1)], fill=0)
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 6 and GT_Dev.Y[0] < 30):
print("Home ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Clear ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
if(Page == 2 and ReFlag == 0): #photo menu
if(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next page ...\r\n")
Photo_S += 1
if(Photo_S > 2): # 6 photos is a maximum of three pages
Photo_S=0
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_S == 0):
print("Top page ...\r\n")
else:
Photo_S -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
elif(GT_Dev.X[0] > 2 and GT_Dev.X[0] < 90 and GT_Dev.Y[0] > 2 and GT_Dev.Y[0] < 248 and ReFlag == 0):
print("Select photo ...\r\n")
Page = 3
Read_BMP(PagePath[Page], 0, 0)
Photo_L = int(GT_Dev.X[0]/46*2 + 2-GT_Dev.Y[0]/124 + Photo_S*2)
Show_Photo_Large(image, Photo_L)
ReFlag = 1
if(ReFlag == 2): # Refresh small photo
ReFlag = 1
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S) # show small photo
if(Page == 3 and ReFlag == 0): #view the photo
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 4 and GT_Dev.Y[0] < 25):
print("Photo menu ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next photo ...\r\n")
Photo_L += 1
if(Photo_L > 6):
Photo_L = 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_L == 1):
print("Top photo ...\r\n")
else:
Photo_L -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh photo ...\r\n")
SelfFlag = 1
ReFlag = 1
if(ReFlag == 2): # Refresh large photo
ReFlag = 1
Show_Photo_Large(image, Photo_L)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
flag_t = 0
epd.sleep()
time.sleep(2)
t.join()
epd.Dev_exit()
exit()
@@ -0,0 +1,235 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic/2in13')
fontdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
from TP_lib import gt1151
from TP_lib import epd2in13_V2
import time
import logging
from PIL import Image,ImageDraw,ImageFont
import traceback
import threading
logging.basicConfig(level=logging.DEBUG)
flag_t = 1
def pthread_irq() :
print("pthread running")
while flag_t == 1 :
if(gt.digital_read(gt.INT) == 0) :
GT_Dev.Touch = 1
else :
GT_Dev.Touch = 0
print("thread:exit")
def Show_Photo_Small(image, small):
for t in range(1, 5):
if(small*2+t > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_S[0]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_S[small*2+t]))
image.paste(newimage, ((t-1)//2*45+2, (t%2)*124+2))
def Show_Photo_Large(image, large):
if(large > 6):
newimage = Image.open(os.path.join(picdir, PhotoPath_L[0]))
image.paste(newimage, (2, 2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_L[large]))
image.paste(newimage, (2, 2))
def Read_BMP(File, x, y):
newimage = Image.open(os.path.join(picdir, File))
image.paste(newimage, (x, y))
try:
logging.info("epd2in13_V2 Touch Demo")
epd = epd2in13_V2.EPD_2IN13_V2()
gt = gt1151.GT1151()
GT_Dev = gt1151.GT_Development()
GT_Old = gt1151.GT_Development()
logging.info("init and Clear")
epd.init(epd.FULL_UPDATE)
gt.GT_Init()
epd.Clear(0xFF)
t = threading.Thread(target = pthread_irq)
t.setDaemon(True)
t.start()
# Drawing on the image
font15 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 15)
font24 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 24)
image = Image.open(os.path.join(picdir, 'Menu.bmp'))
epd.displayPartBaseImage(epd.getbuffer(image))
DrawImage = ImageDraw.Draw(image)
epd.init(epd.PART_UPDATE)
i = j = k = ReFlag = SelfFlag = Page = Photo_L = Photo_S = 0
PhotoPath_S = [ "Photo_1_0.bmp",
"Photo_1_1.bmp", "Photo_1_2.bmp", "Photo_1_3.bmp", "Photo_1_4.bmp",
"Photo_1_5.bmp", "Photo_1_6.bmp",
]
PhotoPath_L = [ "Photo_2_0.bmp",
"Photo_2_1.bmp", "Photo_2_2.bmp", "Photo_2_3.bmp", "Photo_2_4.bmp",
"Photo_2_5.bmp", "Photo_2_6.bmp",
]
PagePath = ["Menu.bmp", "White_board.bmp", "Photo_1.bmp", "Photo_2.bmp"]
while(1):
if(i > 12 or ReFlag == 1):
if(Page == 1 and SelfFlag == 0):
epd.displayPartial(epd.getbuffer(image))
else:
epd.displayPartial_Wait(epd.getbuffer(image))
i = 0
k = 0
j += 1
ReFlag = 0
print("*** Draw Refresh ***\r\n")
elif(k>50000 and i>0 and Page == 1):
epd.displayPartial(epd.getbuffer(image))
i = 0
k = 0
j += 1
print("*** Overtime Refresh ***\r\n")
elif(j > 50 or SelfFlag):
SelfFlag = 0
j = 0
epd.init(epd.FULL_UPDATE)
epd.displayPartBaseImage(epd.getbuffer(image))
epd.init(epd.PART_UPDATE)
print("--- Self Refresh ---\r\n")
else:
k += 1
# Read the touch input
gt.GT_Scan(GT_Dev, GT_Old)
if(GT_Old.X[0] == GT_Dev.X[0] and GT_Old.Y[0] == GT_Dev.Y[0] and GT_Old.S[0] == GT_Dev.S[0]):
continue
if(GT_Dev.TouchpointFlag):
i += 1
GT_Dev.TouchpointFlag = 0
if(Page == 0 and ReFlag == 0): #main menu
if(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 56 and GT_Dev.Y[0] < 95):
print("Photo ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 29 and GT_Dev.X[0] < 92 and GT_Dev.Y[0] > 153 and GT_Dev.Y[0] < 193):
print("Draw ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
if(Page == 1 and ReFlag == 0): #white board
DrawImage.rectangle([(GT_Dev.X[0], GT_Dev.Y[0]), (GT_Dev.X[0] + GT_Dev.S[0]/8 + 1, GT_Dev.Y[0] + GT_Dev.S[0]/8 + 1)], fill=0)
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 6 and GT_Dev.Y[0] < 30):
print("Home ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Clear ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 118 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
if(Page == 2 and ReFlag == 0): #photo menu
if(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next page ...\r\n")
Photo_S += 1
if(Photo_S > 2): # 6 photos is a maximum of three pages
Photo_S=0
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_S == 0):
print("Top page ...\r\n")
else:
Photo_S -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 97 and GT_Dev.X[0] < 119 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
elif(GT_Dev.X[0] > 2 and GT_Dev.X[0] < 90 and GT_Dev.Y[0] > 2 and GT_Dev.Y[0] < 248 and ReFlag == 0):
print("Select photo ...\r\n")
Page = 3
Read_BMP(PagePath[Page], 0, 0)
Photo_L = int(GT_Dev.X[0]/46*2 + 2-GT_Dev.Y[0]/124 + Photo_S*2)
Show_Photo_Large(image, Photo_L)
ReFlag = 1
if(ReFlag == 2): # Refresh small photo
ReFlag = 1
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S) # show small photo
if(Page == 3 and ReFlag == 0): #view the photo
if(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 4 and GT_Dev.Y[0] < 25):
print("Photo menu ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 57 and GT_Dev.Y[0] < 78):
print("Next photo ...\r\n")
Photo_L += 1
if(Photo_L > 6):
Photo_L = 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 113 and GT_Dev.Y[0] < 136):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 169 and GT_Dev.Y[0] < 190):
print("Last page ...\r\n")
if(Photo_L == 1):
print("Top photo ...\r\n")
else:
Photo_L -= 1
ReFlag = 2
elif(GT_Dev.X[0] > 96 and GT_Dev.X[0] < 117 and GT_Dev.Y[0] > 220 and GT_Dev.Y[0] < 242):
print("Refresh photo ...\r\n")
SelfFlag = 1
ReFlag = 1
if(ReFlag == 2): # Refresh large photo
ReFlag = 1
Show_Photo_Large(image, Photo_L)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
flag_t = 0
epd.sleep()
time.sleep(2)
t.join()
epd.Dev_exit()
exit()
@@ -0,0 +1,268 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic/2in9')
fontdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'pic')
libdir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'lib')
if os.path.exists(libdir):
sys.path.append(libdir)
from TP_lib import icnt86
from TP_lib import epd2in9_V2
from TP_lib import weather_2in9_V2
import time
import logging
from PIL import Image, ImageDraw, ImageFont
import traceback
import threading
logging.basicConfig(level=logging.DEBUG)
flag_t = 1
def pthread_irq() :
print("pthread irq running")
while flag_t == 1 :
if(tp.digital_read(tp.INT) == 0) :
ICNT_Dev.Touch = 1
else :
ICNT_Dev.Touch = 0
time.sleep(0.01)
print("thread irq: exit")
def Show_Photo_Small(image, small):
for t in range(1, 7):
if(small*3+t > 9):
newimage = Image.open(os.path.join(picdir, PhotoPath_S[0]))
image.paste(newimage, ((t-1)%3*98+2, (t-1)//3*48+2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_S[small*3+t]))
image.paste(newimage, ((t-1)%3*98+2, (t-1)//3*48+2))
def Show_Photo_Large(image, large):
if(large > 9):
newimage = Image.open(os.path.join(picdir, PhotoPath_L[0]))
image.paste(newimage, (2, 2))
else:
newimage = Image.open(os.path.join(picdir, PhotoPath_L[large]))
image.paste(newimage, (2, 2))
def Read_BMP(File, x, y):
newimage = Image.open(os.path.join(picdir, File))
image.paste(newimage, (x, y))
def Draw_Time(image, x, y, font1, font2):
Time = time.strftime("%H : %M", time.localtime())
Date = time.strftime("%Y - %m - %d", time.localtime())
imagefill=255
if image.mode!="1":
imagefill = (255, 255, 255, 255)
image.text((x, y), Time, font = font1, fill = imagefill)
image.text((x-9, y+35), Date, font = font2, fill = imagefill)
try:
logging.info("epd2in9_V2 Touch Demo")
epd = epd2in9_V2.EPD_2IN9_V2()
tp = icnt86.INCT86()
ICNT_Dev = icnt86.ICNT_Development()
ICNT_Old = icnt86.ICNT_Development()
'''
Because the touch display requires a relatively fast refresh speed, the default
needs to use partial refresh, and four gray levels cannot be used in this mode.
Here, only four gray level picture refresh demonstration is used
'''
# epd.Init_4Gray()
# Himage = Image.open(os.path.join(picdir, '2in9_Scale.bmp'))
# epd.display_4Gray(epd.getbuffer_4Gray(Himage))
# time.sleep(2)
logging.info("init and Clear")
epd.init()
tp.ICNT_Init()
epd.Clear(0xFF)
t1 = threading.Thread(target = pthread_irq)
t1.setDaemon(True)
t1.start()
# Drawing on the image
font15 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 15)
font24 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 24)
image = Image.open(os.path.join(picdir, 'Menu.bmp'))
DrawImage = ImageDraw.Draw(image)
Draw_Time(DrawImage, 209, 40, font24, font15)
epd.display_Base(epd.getbuffer(image))
i = j = k = ReFlag = SelfFlag = Page = Photo_L = Photo_S = 0
PhotoPath_S = [ "Photo_1_0.bmp",
"Photo_1_1.bmp", "Photo_1_2.bmp", "Photo_1_3.bmp", "Photo_1_4.bmp",
"Photo_1_5.bmp", "Photo_1_6.bmp", "Photo_1_7.bmp", "Photo_1_8.bmp",
"Photo_1_9.bmp",
]
PhotoPath_L = [ "Photo_2_0.bmp",
"Photo_2_1.bmp", "Photo_2_2.bmp", "Photo_2_3.bmp", "Photo_2_4.bmp",
"Photo_2_5.bmp", "Photo_2_6.bmp", "Photo_2_7.bmp", "Photo_2_8.bmp",
"Photo_2_9.bmp",
]
PagePath = ["Menu.bmp", "screen_output.png", "Photo_1.bmp", "Photo_2.bmp"]
while(1):
if(i > 20 or ReFlag == 1):
if(Page == 0):
DrawImage.rectangle((209, 40, 290, 120), fill = 0)
Draw_Time(DrawImage, 209, 40, font24, font15)
# print("*** Time Refresh ***\r\n")
if(Page == 1):
weather_2in9_V2.get_weather_png()
Read_BMP(PagePath[Page], 0, 0)
epd.display_Partial_Wait(epd.getbuffer(image))
print("*** Touch Refresh ***\r\n")
i = 0
k = 0
j += 1
ReFlag = 0
elif(k>50000 and i>0 and Page == 1):
epd.display_Partial_Wait(epd.getbuffer(image))
i = 0
k = 0
j += 1
print("*** Overtime Refresh ***\r\n")
elif(j > 50 or SelfFlag):
SelfFlag = 0
j = 0
epd.init()
epd.display_Base(epd.getbuffer(image))
print("--- Self Refresh ---\r\n")
else:
k += 1
if(Page==0 and k>5000000):
ReFlag = 1
tp.ICNT_Scan(ICNT_Dev, ICNT_Old)
if(ICNT_Old.X[0] == ICNT_Dev.X[0] and ICNT_Old.Y[0] == ICNT_Dev.Y[0]):
continue
if(ICNT_Dev.TouchCount):
ICNT_Dev.TouchCount = 0
i += 1
if(Page == 0 and ReFlag == 0): #main menu
if(ICNT_Dev.X[0] > 119 and ICNT_Dev.X[0] < 152 and ICNT_Dev.Y[0] > 31 and ICNT_Dev.Y[0] < 96):
print("Photo ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(ICNT_Dev.X[0] > 39 and ICNT_Dev.X[0] < 80 and ICNT_Dev.Y[0] > 31 and ICNT_Dev.Y[0] < 96):
print("Weather ...\r\n")
Page = 1
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
if(Page == 1 and ReFlag == 0): #weather
if(ICNT_Dev.X[0] > 136 and ICNT_Dev.X[0] < 159 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(ICNT_Dev.X[0] > 5 and ICNT_Dev.X[0] < 27 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
if(Page == 2 and ReFlag == 0): #photo menu
if(ICNT_Dev.X[0] > 135 and ICNT_Dev.X[0] < 160 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(ICNT_Dev.X[0] > 203 and ICNT_Dev.X[0] < 224 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Next page ...\r\n")
Photo_S += 1
if(Photo_S > 2): # 9 photos is a maximum of three pages
Photo_S=0
ReFlag = 2
elif(ICNT_Dev.X[0] > 71 and ICNT_Dev.X[0] < 92 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Last page ...\r\n")
if(Photo_S == 0):
print("Top page ...\r\n")
else:
Photo_S -= 1
ReFlag = 2
elif(ICNT_Dev.X[0] > 5 and ICNT_Dev.X[0] < 27 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Refresh ...\r\n")
SelfFlag = 1
ReFlag = 1
elif(ICNT_Dev.X[0] > 2 and ICNT_Dev.X[0] < 293 and ICNT_Dev.Y[0] > 2 and ICNT_Dev.Y[0] < 96 and ReFlag == 0):
print("Select photo ...\r\n")
Page = 3
Read_BMP(PagePath[Page], 0, 0)
Photo_L = ICNT_Dev.X[0]//96 + ICNT_Dev.Y[0]//48*3 + Photo_S*3 + 1
Show_Photo_Large(image, Photo_L)
ReFlag = 1
if(ReFlag == 2): # Refresh small photo
ReFlag = 1
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S) # show small photo
if(Page == 3 and ReFlag == 0): #view the photo
if(ICNT_Dev.X[0] > 268 and ICNT_Dev.X[0] < 289 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Photo menu ...\r\n")
Page = 2
Read_BMP(PagePath[Page], 0, 0)
Show_Photo_Small(image, Photo_S)
ReFlag = 1
elif(ICNT_Dev.X[0] > 203 and ICNT_Dev.X[0] < 224 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Next photo ...\r\n")
Photo_L += 1
if(Photo_L > 9):
Photo_L = 1
ReFlag = 2
elif(ICNT_Dev.X[0] > 135 and ICNT_Dev.X[0] < 160 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Home ...\r\n")
Page = 0
Read_BMP(PagePath[Page], 0, 0)
ReFlag = 1
elif(ICNT_Dev.X[0] > 71 and ICNT_Dev.X[0] < 92 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Last page ...\r\n")
if(Photo_L == 1):
print("Top photo ...\r\n")
else:
Photo_L -= 1
ReFlag = 2
elif(ICNT_Dev.X[0] > 5 and ICNT_Dev.X[0] < 27 and ICNT_Dev.Y[0] > 101 and ICNT_Dev.Y[0] < 124):
print("Refresh photo ...\r\n")
SelfFlag = 1
ReFlag = 1
if(ReFlag == 2): # Refresh large photo
ReFlag = 1
Show_Photo_Large(image, Photo_L)
except IOError as e:
logging.info(e)
except KeyboardInterrupt:
logging.info("ctrl + c:")
flag_t = 0
epd.sleep()
time.sleep(2)
t1.join()
epd.Dev_exit()
exit()
@@ -0,0 +1,339 @@
# *****************************************************************************
# * | 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
class EPD_2IN13_V2:
def __init__(self):
self.reset_pin = epdconfig.EPD_RST_PIN
self.dc_pin = epdconfig.EPD_DC_PIN
self.busy_pin = epdconfig.EPD_BUSY_PIN
self.cs_pin = epdconfig.EPD_CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
epdconfig.address = 0x14
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 send_data2(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(10)
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 TurnOnDisplayPart_Wait(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):
# logging.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):
# logging.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.send_data2(image)
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_data2(image)
self.TurnOnDisplayPart()
def displayPartial_Wait(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.TurnOnDisplayPart_Wait()
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
self.send_command(0x24)
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(100)
def Dev_exit(self):
epdconfig.module_exit()
### END OF FILE ###
@@ -0,0 +1,436 @@
# *****************************************************************************
# * | 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.EPD_RST_PIN
self.dc_pin = epdconfig.EPD_DC_PIN
self.busy_pin = epdconfig.EPD_BUSY_PIN
self.cs_pin = epdconfig.EPD_CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
epdconfig.address = 0x14
FULL_UPDATE = 0
PART_UPDATE = 1
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,
0x10,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)
def send_data2(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(0x0c) # fast:0x0c, quality:0x0f, 0xcf
self.send_command(0x20) # Activate Display Update Sequence
# self.ReadBusy()
def TurnOnDisplayPart_Wait(self):
self.send_command(0x22) # Display Update Control
self.send_data(0x0c) # 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, update):
if (epdconfig.module_init() != 0):
return -1
if update == self.FULL_UPDATE:
# 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)
else:
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)
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.rotate(180, expand=True).convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(270, 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.send_data2(image)
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
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.send_data2(image)
self.TurnOnDisplayPart()
def displayPartial_Wait(self, image):
if self.width%8 == 0:
linewidth = int(self.width/8)
else:
linewidth = int(self.width/8) + 1
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.send_data2(image)
self.TurnOnDisplayPart_Wait()
'''
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)
def Dev_exit(self):
epdconfig.module_exit()
### END OF FILE ###
@@ -0,0 +1,370 @@
# *****************************************************************************
# * | File : epd2in13_V4.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2023-08-14
# # | 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.EPD_RST_PIN
self.dc_pin = epdconfig.EPD_DC_PIN
self.busy_pin = epdconfig.EPD_BUSY_PIN
self.cs_pin = epdconfig.EPD_CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
epdconfig.address = 0x14
FULL_UPDATE = 0
PART_UPDATE = 1
'''
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)
def send_data2(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(0xF7)
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(0xFF) # fast:0x0c, quality:0x0f, 0xcf
self.send_command(0x20) # Activate Display Update Sequence
# self.ReadBusy()
def TurnOnDisplayPart_Wait(self):
self.send_command(0x22) # Display Update Control
self.send_data(0xFF) # fast:0x0c, quality:0x0f, 0xcf
self.send_command(0x20) # Activate Display Update Sequence
self.ReadBusy()
'''
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, update):
if (epdconfig.module_init() != 0):
return -1
if update == self.FULL_UPDATE:
# 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()
else:
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(1)
epdconfig.digital_write(self.reset_pin, 1)
self.send_command(0x01) #Driver output control
self.send_data(0xf9)
self.send_data(0x00)
self.send_data(0x00)
self.send_command(0x3C) #BorderWavefrom
self.send_data(0x80)
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)
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.rotate(180, expand=True).convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(270, 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.send_data2(image)
self.TurnOnDisplay()
'''
function : Sends the image buffer in RAM to e-Paper and partial refresh
parameter:
image : Image data
'''
def displayPartial(self, image):
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(1)
epdconfig.digital_write(self.reset_pin, 1)
self.send_command(0x01) #Driver output control
self.send_data(0xf9)
self.send_data(0x00)
self.send_data(0x00)
self.send_command(0x3C) #BorderWavefrom
self.send_data(0x80)
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(0x24) # WRITE_RAM
self.send_data2(image)
self.TurnOnDisplayPart()
def displayPartial_Wait(self, image):
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(1)
epdconfig.digital_write(self.reset_pin, 1)
self.send_command(0x01) #Driver output control
self.send_data(0xf9)
self.send_data(0x00)
self.send_data(0x00)
self.send_command(0x3C) #BorderWavefrom
self.send_data(0x80)
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(0x24) # WRITE_RAM
self.send_data2(image)
self.TurnOnDisplayPart_Wait()
'''
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)
def Dev_exit(self):
epdconfig.module_exit()
### END OF FILE ###
@@ -0,0 +1,586 @@
# *****************************************************************************
# * | 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
import numpy as np
# Display resolution
EPD_WIDTH = 128
EPD_HEIGHT = 296
class EPD_2IN9_V2:
def __init__(self):
self.reset_pin = epdconfig.EPD_RST_PIN
self.dc_pin = epdconfig.EPD_DC_PIN
self.busy_pin = epdconfig.EPD_BUSY_PIN
self.cs_pin = epdconfig.EPD_CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
epdconfig.address = 0x48
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,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,0xB0,0x32,0x36,
]
WF_PARTIAL_2IN9_Wait = [
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,0x2,
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,
]
Gray4 = [
0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2A, 0x60, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00,
0x1E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x22, 0x22, 0x22, 0x23, 0x32, 0x00, 0x00, 0x00,
0x22, 0x17, 0x41, 0xAE, 0x32, 0x28,
]
WF_FULL = [
0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x19, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x24, 0x42, 0x22, 0x22, 0x23, 0x32, 0x00, 0x00, 0x00,
0x22, 0x17, 0x41, 0xAE, 0x32, 0x38]
# 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_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
# logging.debug("e-Paper busy")
while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
epdconfig.delay_ms(0.1)
# logging.debug("e-Paper busy release")
def TurnOnDisplay(self):
self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
self.send_data(0xF7)
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 TurnOnDisplay_Partial_Wait(self):
self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
self.send_data(0x0F)
self.send_command(0x20) # MASTER_ACTIVATION
self.ReadBusy()
def TurnOnDisplay_4Gray(self):
self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2
self.send_data(0xC7)
self.send_command(0x20) # MASTER_ACTIVATION
self.ReadBusy()
def SendLut(self, lut):
self.send_command(0x32)
# for i in range(0, 153):
# self.send_data(self.WF_PARTIAL_2IN9[i])
if(lut):
self.send_data2(self.WF_PARTIAL_2IN9)
else:
self.send_data2(self.WF_PARTIAL_2IN9_Wait)
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)
self.ReadBusy()
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()
# EPD hardware init end
return 0
def init_Fast(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(0x3C)
self.send_data(0x05)
self.send_command(0x21) # Display update control
self.send_data(0x00)
self.send_data(0x80)
self.SetCursor(0, 0)
self.ReadBusy()
self.SetLut(self.WF_FULL)
# EPD hardware init end
return 0
def Init_4Gray(self):
if (epdconfig.module_init() != 0):
return -1
self.reset()
epdconfig.delay_ms(100)
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(8, 0, self.width, self.height-1)
self.send_command(0x3C)
self.send_data(0x04)
self.SetCursor(1, 0)
self.ReadBusy()
self.SetLut(self.Gray4)
# EPD hardware init end
return 0
def getbuffer(self, image):
# logging.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()
# logging.debug("imwidth = %d, imheight = %d",imwidth,imheight)
if(imwidth == self.width and imheight == self.height):
# logging.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):
# logging.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):
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_data2(image)
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_data2(image)
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.send_data2(image)
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.SendLut(1)
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.send_data2(image)
self.TurnOnDisplay_Partial()
def display_Partial_Wait(self, image):
if (image == None):
return
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(1)
epdconfig.digital_write(self.reset_pin, 1)
# epdconfig.delay_ms(2)
self.SendLut(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()
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.send_data2(image)
self.TurnOnDisplay_Partial_Wait()
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 display_4Gray(self, image):
self.send_command(0x24)
for i in range(0, 4736):
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 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x01
else: #0x40
temp3 |= 0x00
temp3 <<= 1
temp1 <<= 2
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x01
else : #0x40
temp3 |= 0x00
if(j!=1 or k!=1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.send_command(0x26)
for i in range(0, 4736):
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 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x00
else: #0x40
temp3 |= 0x01
temp3 <<= 1
temp1 <<= 2
temp2 = temp1&0xC0
if(temp2 == 0xC0):
temp3 |= 0x00
elif(temp2 == 0x00):
temp3 |= 0x01
elif(temp2 == 0x80):
temp3 |= 0x00
else: #0x40
temp3 |= 0x01
if(j!=1 or k!=1):
temp3 <<= 1
temp1 <<= 2
self.send_data(temp3)
self.TurnOnDisplay_4Gray()
def sleep(self):
self.send_command(0x10) # DEEP_SLEEP_MODE
self.send_data(0x01)
def Dev_exit(self):
epdconfig.module_exit()
### END OF FILE ###
@@ -0,0 +1,140 @@
# /*****************************************************************************
# * | File : epdconfig.py
# * | Author : Waveshare team
# * | Function : Hardware underlying interface
# * | Info :
# *----------------
# * | This version: V1.0
# * | Date : 2020-12-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 gpiozero
import time
from smbus import SMBus
import spidev
import ctypes
import logging
# e-Paper
EPD_RST_PIN = 17
EPD_DC_PIN = 25
EPD_CS_PIN = 8
EPD_BUSY_PIN = 24
# TP
TRST = 22
INT = 27
spi = spidev.SpiDev(0, 0)
address = 0x0
# address = 0x14
# address = 0x48
bus = SMBus(1)
GPIO_RST_PIN = gpiozero.LED(EPD_RST_PIN)
GPIO_DC_PIN = gpiozero.LED(EPD_DC_PIN)
# GPIO_CS_PIN = gpiozero.LED(EPD_CS_PIN)
GPIO_TRST = gpiozero.LED(TRST)
GPIO_BUSY_PIN = gpiozero.Button(EPD_BUSY_PIN, pull_up = False)
GPIO_INT = gpiozero.Button(INT, pull_up = False)
def digital_write(pin, value):
if pin == EPD_RST_PIN:
if value:
GPIO_RST_PIN.on()
else:
GPIO_RST_PIN.off()
elif pin == EPD_DC_PIN:
if value:
GPIO_DC_PIN.on()
else:
GPIO_DC_PIN.off()
# elif pin == EPD_CS_PIN:
# if value:
# GPIO_CS_PIN.on()
# else:
# GPIO_CS_PIN.off()
elif pin == TRST:
if value:
GPIO_TRST.on()
else:
GPIO_TRST.off()
def digital_read(pin):
if pin == EPD_BUSY_PIN:
return GPIO_BUSY_PIN.value
elif pin == INT:
return GPIO_INT.value
def delay_ms(delaytime):
time.sleep(delaytime / 1000.0)
def spi_writebyte(data):
spi.writebytes(data)
def spi_writebyte2(data):
spi.writebytes2(data)
def i2c_writebyte(reg, value):
bus.write_word_data(address, (reg>>8) & 0xff, (reg & 0xff) | ((value & 0xff) << 8))
def i2c_write(reg):
bus.write_byte_data(address, (reg>>8) & 0xff, reg & 0xff)
def i2c_readbyte(reg, len):
i2c_write(reg)
rbuf = []
for i in range(len):
rbuf.append(int(bus.read_byte(address)))
return rbuf
def module_init():
spi.max_speed_hz = 10000000
spi.mode = 0b00
return 0
def module_exit():
logging.debug("spi end")
spi.close()
bus.close()
logging.debug("close 5V, Module enters 0 power consumption ...")
GPIO_RST_PIN.off()
GPIO_DC_PIN.off()
# GPIO_CS_PIN.off()
GPIO_TRST.off()
GPIO_RST_PIN.close()
GPIO_DC_PIN.close()
# GPIO_CS_PIN.close()
GPIO_TRST.close()
GPIO_BUSY_PIN.close()
GPIO_INT.close()
### END OF FILE ###
@@ -0,0 +1,84 @@
import logging
from . import epdconfig as config
class GT_Development:
def __init__(self):
self.Touch = 0
self.TouchpointFlag = 0
self.TouchCount = 0
self.Touchkeytrackid = [0, 1, 2, 3, 4]
self.X = [0, 1, 2, 3, 4]
self.Y = [0, 1, 2, 3, 4]
self.S = [0, 1, 2, 3, 4]
class GT1151:
def __init__(self):
# e-Paper
self.ERST = config.EPD_RST_PIN
self.DC = config.EPD_DC_PIN
self.CS = config.EPD_CS_PIN
self.BUSY = config.EPD_BUSY_PIN
# TP
self.TRST = config.TRST
self.INT = config.INT
def digital_read(self, pin):
return config.digital_read(pin)
def GT_Reset(self):
config.digital_write(self.TRST, 1)
config.delay_ms(100)
config.digital_write(self.TRST, 0)
config.delay_ms(100)
config.digital_write(self.TRST, 1)
config.delay_ms(100)
def GT_Write(self, Reg, Data):
config.i2c_writebyte(Reg, Data)
def GT_Read(self, Reg, len):
return config.i2c_readbyte(Reg, len)
def GT_ReadVersion(self):
buf = self.GT_Read(0x8140, 4)
print(buf)
def GT_Init(self):
self.GT_Reset()
self.GT_ReadVersion()
def GT_Scan(self, GT_Dev, GT_Old):
buf = []
mask = 0x00
if(GT_Dev.Touch == 1):
GT_Dev.Touch = 0
buf = self.GT_Read(0x814E, 1)
if(buf[0]&0x80 == 0x00):
self.GT_Write(0x814E, mask)
config.delay_ms(10)
else:
GT_Dev.TouchpointFlag = buf[0]&0x80
GT_Dev.TouchCount = buf[0]&0x0f
if(GT_Dev.TouchCount > 5 or GT_Dev.TouchCount < 1):
self.GT_Write(0x814E, mask)
return
buf = self.GT_Read(0x814F, GT_Dev.TouchCount*8)
self.GT_Write(0x814E, mask)
GT_Old.X[0] = GT_Dev.X[0];
GT_Old.Y[0] = GT_Dev.Y[0];
GT_Old.S[0] = GT_Dev.S[0];
for i in range(0, GT_Dev.TouchCount, 1):
GT_Dev.Touchkeytrackid[i] = buf[0 + 8*i]
GT_Dev.X[i] = (buf[2 + 8*i] << 8) + buf[1 + 8*i]
GT_Dev.Y[i] = (buf[4 + 8*i] << 8) + buf[3 + 8*i]
GT_Dev.S[i] = (buf[6 + 8*i] << 8) + buf[5 + 8*i]
print(GT_Dev.X[0], GT_Dev.Y[0], GT_Dev.S[0])
@@ -0,0 +1,89 @@
import logging
from . import epdconfig as config
class ICNT_Development:
def __init__(self):
self.Touch = 0
self.TouchGestureid = 0
self.TouchCount = 0
self.TouchEvenid = [0, 1, 2, 3, 4]
self.X = [0, 1, 2, 3, 4]
self.Y = [0, 1, 2, 3, 4]
self.P = [0, 1, 2, 3, 4]
class INCT86:
def __init__(self):
# e-Paper
self.ERST = config.EPD_RST_PIN
self.DC = config.EPD_DC_PIN
self.CS = config.EPD_CS_PIN
self.BUSY = config.EPD_BUSY_PIN
# TP
self.TRST = config.TRST
self.INT = config.INT
def digital_read(self, pin):
return config.digital_read(pin)
def ICNT_Reset(self):
config.digital_write(self.TRST, 1)
config.delay_ms(100)
config.digital_write(self.TRST, 0)
config.delay_ms(100)
config.digital_write(self.TRST, 1)
config.delay_ms(100)
def ICNT_Write(self, Reg, Data):
config.i2c_writebyte(Reg, Data)
def ICNT_Read(self, Reg, len):
return config.i2c_readbyte(Reg, len)
def ICNT_ReadVersion(self):
buf = self.ICNT_Read(0x000a, 4)
print(buf)
def ICNT_Init(self):
self.ICNT_Reset()
self.ICNT_ReadVersion()
def ICNT_Scan(self, ICNT_Dev, ICNT_Old):
buf = []
mask = 0x00
if(ICNT_Dev.Touch == 1):
# ICNT_Dev.Touch = 0
buf = self.ICNT_Read(0x1001, 1)
if(buf[0] == 0x00):
self.ICNT_Write(0x1001, mask)
config.delay_ms(1)
# print("buffers status is 0")
return
else:
ICNT_Dev.TouchCount = buf[0]
if(ICNT_Dev.TouchCount > 5 or ICNT_Dev.TouchCount < 1):
self.ICNT_Write(0x1001, mask)
ICNT_Dev.TouchCount = 0
# print("TouchCount number is wrong")
return
buf = self.ICNT_Read(0x1002, ICNT_Dev.TouchCount*7)
self.ICNT_Write(0x1001, mask)
ICNT_Old.X[0] = ICNT_Dev.X[0];
ICNT_Old.Y[0] = ICNT_Dev.Y[0];
ICNT_Old.P[0] = ICNT_Dev.P[0];
for i in range(0, ICNT_Dev.TouchCount, 1):
ICNT_Dev.TouchEvenid[i] = buf[6 + 7*i]
ICNT_Dev.X[i] = 295 - ((buf[2 + 7*i] << 8) + buf[1 + 7*i])
ICNT_Dev.Y[i] = 127 - ((buf[4 + 7*i] << 8) + buf[3 + 7*i])
ICNT_Dev.P[i] = buf[5 + 7*i]
print(ICNT_Dev.X[0], ICNT_Dev.Y[0], ICNT_Dev.P[0])
return
return
@@ -0,0 +1,261 @@
# This little program is for the Waveshare 2.9
# inch Version 2 black and white only epaper display
# It uses OpenWeatherMap API to display weather info
import sys
import os
picdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../pic/2in9')
icondir = os.path.join(picdir, 'icon')
fontdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../../pic')
# Search lib folder for display driver modules
sys.path.append('lib')
from . import epd2in9_V2
epd = epd2in9_V2.EPD_2IN9_V2()
from datetime import datetime
import time
from PIL import Image,ImageDraw,ImageFont
import traceback
import requests, json
from io import BytesIO
import csv
# define funciton for writing image and sleeping for 5 min.
def write_to_screen(image, sleep_seconds):
print('Writing to screen.')
# Write to screen
h_image = Image.new('1', (epd.height, epd.width), 255)
# Open the template
screen_output_file = Image.open(os.path.join(picdir, image))
# Initialize the drawing context with template as background
h_image.paste(screen_output_file, (0, 0))
epd.display(epd.getbuffer(h_image))
# Sleep
print('Sleeping for ' + str(sleep_seconds) +'.')
time.sleep(sleep_seconds)
# define function for displaying error
def display_error(error_source):
# Display an error
print('Error in the', error_source, 'request.')
# Initialize drawing
error_image = Image.new('1', (epd.height, epd.width), 255)
# Initialize the drawing
draw = ImageDraw.Draw(error_image)
draw.text((5, 5), error_source +' ERROR', font=font20, fill=black)
draw.text((5, 30), 'Retrying in 30 seconds', font=font20, fill=black)
current_time = datetime.now().strftime('%H:%M')
draw.text((5, 55), 'Last Refresh: ' + str(current_time), font = font20, fill=black)
# Save the error image
error_image_file = 'error.png'
error_image.save(os.path.join(picdir, error_image_file))
# Close error image
error_image.close()
# Write error to screen
write_to_screen(error_image_file, 30)
# Set the fonts
font12 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 12)
font16 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 16)
font20 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 20)
font24 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 24)
font30 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 30)
font35 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 35)
font50 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 50)
font60 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 60)
font100 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 100)
font160 = ImageFont.truetype(os.path.join(fontdir, 'Font.ttc'), 160)
# Set the special fonts
font18_Roboto_Bold = ImageFont.truetype(os.path.join(fontdir, 'Roboto-Bold.ttf'), 18)
font20_Roboto_Bold = ImageFont.truetype(os.path.join(fontdir, 'Roboto-Bold.ttf'), 20)
font20_Roboto_Regular = ImageFont.truetype(os.path.join(fontdir, 'Roboto-Regular.ttf'), 20)
font34_Roboto_Black = ImageFont.truetype(os.path.join(fontdir, 'Roboto-Black.ttf'), 34)
# Set the colors
black = 'rgb(0,0,0)'
white = 'rgb(255,255,255)'
grey = 'rgb(235,235,235)'
# Initialize and clear screen
# print('Initializing and clearing screen.')
# epd.init()
# epd.Clear()
# I provide my API_KEY for you to test: 82ec63bb0530e31e0ef9042786d195cc, Please try to use your own API_KEY
API_KEY = '******API KEY*******'
LOCATION = 'Shenzhen'
LATITUDE = '22.543097'
LONGITUDE = '114.057861'
UNITS = 'imperial'
CSV_OPTION = False # if csv_option == True, a weather data will be appended to 'record.csv'
BASE_URL = 'http://api.openweathermap.org/data/2.5/onecall?'
URL = BASE_URL + 'lat=' + LATITUDE + '&lon=' + LONGITUDE + '&units=' + UNITS +'&appid=' + API_KEY
def get_weather_png():
# Ensure there are no errors with connection
error_connect = True
while error_connect == True:
try:
# HTTP request
print('Attempting to connect to OWM.')
response = requests.get(URL)
print('Connection to OWM successful.')
error_connect = None
except:
# Call function to display connection error
print('Connection error.')
display_error('CONNECTION')
error = None
while error == None:
# Check status of code request
if response.status_code == 200:
print('Connection to Open Weather successful.')
# get data in jason format
data = response.json()
# get current dict block
current = data['current']
# get current
temp_current = current['temp']
# get feels like
feels_like = current['feels_like']
# get humidity
humidity = current['humidity']
# get pressure
wind = current['wind_speed']
# get description
weather = current['weather']
report = weather[0]['description']
# get icon url
icon_code = weather[0]['icon']
#icon_URL = 'http://openweathermap.org/img/wn/'+ icon_code +'@4x.png'
# get daily dict block
daily = data['daily']
# get daily precip
daily_precip_float = daily[0]['pop']
#format daily precip
daily_precip_percent = daily_precip_float * 100
# get min and max temp
daily_temp = daily[0]['temp']
temp_max = daily_temp['max']
temp_min = daily_temp['min']
# Append weather data to CSV if csv_option == True
if CSV_OPTION == True:
# Get current year, month, date, and time
current_year = datetime.now().strftime('%Y')
current_month = datetime.now().strftime('%m')
current_date = datetime.now().strftime('%d')
current_time = datetime.now().strftime('%H:%M')
#open the CSV and append weather data
with open('records.csv', 'a', newline='') as csv_file:
writer = csv.writer(csv_file, delimiter=',')
writer.writerow([current_year, current_month, current_date, current_time,
LOCATION,temp_current, feels_like, temp_max, temp_min,
humidity, daily_precip_float, wind])
print('Weather data appended to CSV.')
# Set strings to be printed to screen
string_location = 'City: ' + LOCATION
string_temp_current = format(temp_current, '.0f') + u'\N{DEGREE SIGN}F'
string_temp_current_C = format((temp_current-32)/1.8, '.0f') + u'\N{DEGREE SIGN}C'
string_temp = string_temp_current + ' / ' + string_temp_current_C
string_feels_like = 'Feels like: ' + format(feels_like, '.0f') + u'\N{DEGREE SIGN}F'
string_humidity = 'Humidity: ' + str(humidity) + '%'
string_wind = 'Wind: ' + format(wind, '.1f') + ' MPH'
# string_report = 'Now: ' + report.title()
string_report = report.title()
string_temp_max = 'High: ' + format(temp_max, '>.0f') + u'\N{DEGREE SIGN}F'
string_temp_min = 'Low: ' + format(temp_min, '>.0f') + u'\N{DEGREE SIGN}F'
string_precip_percent = 'Precip: ' + str(format(daily_precip_percent, '.0f')) + '%'
# Set error code to false
error = False
'''
print('Location:', LOCATION)
print('Temperature:', format(temp_current, '.0f'), u'\N{DEGREE SIGN}F')
print('Feels Like:', format(feels_like, '.0f'), 'F')
print('Humidity:', humidity)
print('Wind Speed:', format(wind_speed, '.1f'), 'MPH')
print('Report:', report.title())
print('High:', format(temp_max, '.0f'), 'F')
print('Low:', format(temp_min, '.0f'), 'F')
print('Probabilty of Precipitation: ' + str(format(daily_precip_percent, '.0f')) + '%')
'''
else:
# Call function to display HTTP error
display_error('HTTP')
# Open template file
template = Image.open(os.path.join(picdir, 'template.bmp'))
# Initialize the drawing context with template as background
draw = ImageDraw.Draw(template)
draw.rectangle((0, 0, 295, 67), fill=white)
# Draw top left box
## Open icon file
icon_file = icon_code + '.png'
icon_image = Image.open(os.path.join(icondir, icon_file))
icon_image_resize = icon_image.resize((68, 68))
### Paste the image
template.paste(icon_image_resize, (0, 0))
## Place a black rectangle outline
# draw.rectangle((15, 5, 80, 60), outline=black)
## Draw text
font_report = font20_Roboto_Bold
font_report_size = 20
while(font_report.getsize(string_report)[0] > 120):
font_report_size -= 2
font_report = ImageFont.truetype(os.path.join(fontdir, 'Roboto-Bold.ttf'), font_report_size)
draw.text((70, 12), string_report, font=font_report, fill=black)
draw.text((70, 34), string_precip_percent, font=font20_Roboto_Bold, fill=black)
# Draw top right box
draw.text((12, 72), string_temp, font=font18_Roboto_Bold, fill=white)
# draw.text((60, 30), string_feels_like, font=font20, fill=white)
# Draw bottom left box
# draw.text((15, 85), string_temp_max, font=font20, fill=black)
# draw.rectangle((15, 108, 265, 110), fill=black)
# draw.text((15, 105), string_temp_min, font=font20, fill=black)
# Draw bottom middle box
# draw.text((120, 85), string_humidity, font=font20, fill=black)
# draw.text((120, 105), string_wind, font=font20, fill=black)
# Draw bottom right box
draw.text((295-11-font20_Roboto_Regular.getsize('UPDATED')[0], 7), 'UPDATED', font=font20_Roboto_Regular, fill=black, align='right')
current_time = datetime.now().strftime('%H:%M')
draw.text((295-11-font34_Roboto_Black.getsize(current_time)[0], 25), current_time, font = font34_Roboto_Black, fill=black, align='right')
# draw.rectangle((193, 35, 288, 85), outline=black)
draw.text((295-11-font18_Roboto_Bold.getsize(string_location)[0], 72), string_location, font = font18_Roboto_Bold, fill=white, align='right')
## Add a reminder to take out trash on Mon and Thurs
# weekday = datetime.today().weekday()
# if weekday == 0 or weekday == 3:
# draw.rectangle((345, 13, 705, 55), fill =black)
# draw.text((355, 15), 'TAKE OUT TRASH TODAY!', font=font18, fill=white)
# Save the image for display as PNG
screen_output_file = os.path.join(picdir, 'screen_output.png')
template.save(screen_output_file)
# Close the template file
template.close()
# Refresh clear screen to avoid burn-in at 3:00 AM
# if datetime.now().strftime('%H') == '03':
# print('Clearning screen to avoid burn-in.')
# epd.Clear()
# Write to screen
# write_to_screen(screen_output_file, 600)
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,59 @@
/*****************************************************************************
* | File : Readme_CN.txt
* | Author : Waveshare team
* | Function : Help with use
* | Info :
*----------------
* | This version: V1.0
* | Date : 2021-06-05
* | Info : 在这里提供一个中文版本的使用文档,以便你的快速使用
******************************************************************************/
这个文件是帮助您使用本例程。
在这里简略的描述本工程的使用:
1.基本信息:
本例程使用 xxxinch e-Paper HAT 模块 在 Raspbe Pi 4B 进行了验证,你可以在工程的examples\中查看对应的测试例程;
2.管脚连接:
管脚连接你可以在\lib\epdconfig.py中查看,这里也再重述一次:
EPD => Jetson Nano/RPI(BCM)
VCC -> 3.3
GND -> GND
DIN -> 10(SPI0_MOSI)
CLK -> 11(SPI0_SCK)
CS -> 8(SPI0_CS0)
DC -> 25
ERST -> 17
BUSY -> 24
INT -> 27
TRST -> 22
SDA -> SDA1
SCL -> SCL1
3.安装库:
python2
sudo apt-get update
sudo apt-get install python-pip
sudo apt-get install python-pil
sudo apt-get install python-numpy
sudo pip install RPi.GPIO
sudo pip install spidev
python3
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo pip3 install RPi.GPIO
sudo pip3 install spidev
4.基本使用:
由于本工程是一个综合工程,对于使用而言,你可能需要阅读以下内容:
你可以在main.c中看到已经进行了注释的函数,
请注意你购买的是哪一款的墨水屏。
栗子1
如果你购买的 2.9inch Touch e-Paper HAT,那么你应该执行命令:
sudo python TP2in9_test.py
sudo python3 TP2in9_test.py
@@ -0,0 +1,60 @@
/*****************************************************************************
* | File : Readme_CN.txt
* | Author : Waveshare team
* | Function : Help with use
* | Info :
*----------------
* | This version: V1.0
* | Date : 2021-06-05
* | Info : Here is an English version of the documentation for your quick use.
******************************************************************************/
This file is to help you use this Demo.
A brief description of the use of this project is here:
1. Basic information:
This routine was verified on Raspbe Pi 4B using the XXXinch e-paper HAT module.
You can view the corresponding test routines in the \lib\Examples\ of the project.
2. Pin connection:
Pin connections can be viewed in \lib\epdconfig.py and will be repeated here:
EPD => Jetson Nano/RPI(BCM)
VCC -> 3.3
GND -> GND
DIN -> 10(SPI0_MOSI)
CLK -> 11(SPI0_SCK)
CS -> 8(SPI0_CS0)
DC -> 25
ERST -> 17
BUSY -> 24
INT -> 27
TRST -> 22
SDA -> SDA1
SCL -> SCL1
3.Installation library
python2
sudo apt-get update
sudo apt-get install python-pip
sudo apt-get install python-pil
sudo apt-get install python-numpy
sudo pip install RPi.GPIO
sudo pip install spidev
python3
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo pip3 install RPi.GPIO
sudo pip3 install spidev
4. Basic use:
Since this project is a comprehensive project, you may need to read the following for use:
You can view the test program in the examples\ directory.
Please note which ink screen you purchased.
Chestnut 1:
    If you purchased 2.9inch Touch e-Paper HAT, then you should execute the command:
sudo python TP2in9_test.py
or
sudo python3 TP2in9_test.py
+10
View File
@@ -0,0 +1,10 @@
import sys
from setuptools import setup
setup(
name='waveshare-ETP',
description='Waveshare e-Paper Touch Display',
author='Waveshare',
package_dir={'': 'lib'},
packages=['TP_lib'],
)