Created
April 15, 2019 21:56
-
-
Save ntavish/6f96b3c97068556687a89d84803e0de9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import board | |
import digitalio | |
import time | |
import busio | |
from adafruit_bus_device.spi_device import SPIDevice | |
EPD_WIDTH = 200 | |
EPD_HEIGHT = 200 | |
PANEL_SETTING = 0x00 | |
POWER_SETTING = 0x01 | |
POWER_OFF = 0x02 | |
POWER_OFF_SEQUENCE_SETTING = 0x03 | |
POWER_ON = 0x04 | |
POWER_ON_MEASURE = 0x05 | |
BOOSTER_SOFT_START = 0x06 | |
DEEP_SLEEP = 0x07 | |
DATA_START_TRANSMISSION_1 = 0x10 | |
DATA_STOP = 0x11 | |
DISPLAY_REFRESH = 0x12 | |
DATA_START_TRANSMISSION_2 = 0x13 | |
PLL_CONTROL = 0x30 | |
TEMPERATURE_SENSOR_COMMAND = 0x40 | |
TEMPERATURE_SENSOR_CALIBRATION = 0x41 | |
TEMPERATURE_SENSOR_WRITE = 0x42 | |
TEMPERATURE_SENSOR_READ = 0x43 | |
VCOM_AND_DATA_INTERVAL_SETTING = 0x50 | |
LOW_POWER_DETECTION = 0x51 | |
TCON_SETTING = 0x60 | |
TCON_RESOLUTION = 0x61 | |
SOURCE_AND_GATE_START_SETTING = 0x62 | |
GET_STATUS = 0x71 | |
AUTO_MEASURE_VCOM = 0x80 | |
VCOM_VALUE = 0x81 | |
VCM_DC_SETTING_REGISTER = 0x82 | |
PROGRAM_MODE = 0xA0 | |
ACTIVE_PROGRAM = 0xA1 | |
READ_OTP_DATA = 0xA2 | |
lut_vcom0 = bytearray([ | |
0x0E, 0x14, 0x01, 0x0A, 0x06, 0x04, 0x0A, 0x0A, | |
0x0F, 0x03, 0x03, 0x0C, 0x06, 0x0A, 0x00 | |
]) | |
lut_w = bytearray([ | |
0x0E, 0x14, 0x01, 0x0A, 0x46, 0x04, 0x8A, 0x4A, | |
0x0F, 0x83, 0x43, 0x0C, 0x86, 0x0A, 0x04 | |
]) | |
lut_b = bytearray([ | |
0x0E, 0x14, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, | |
0x0F, 0x83, 0x43, 0x0C, 0x06, 0x4A, 0x04 | |
]) | |
lut_g1 = bytearray([ | |
0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, | |
0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04 | |
]) | |
lut_g2 = bytearray([ | |
0x8E, 0x94, 0x01, 0x8A, 0x06, 0x04, 0x8A, 0x4A, | |
0x0F, 0x83, 0x43, 0x0C, 0x06, 0x0A, 0x04 | |
]) | |
lut_vcom1 = bytearray([ | |
0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, | |
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
]) | |
lut_red0 = bytearray([ | |
0x83, 0x5D, 0x01, 0x81, 0x48, 0x23, 0x77, 0x77, | |
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
]) | |
lut_red1 = bytearray([ | |
0x03, 0x1D, 0x01, 0x01, 0x08, 0x23, 0x37, 0x37, | |
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
]) | |
led = digitalio.DigitalInOut(board.L) | |
led.direction = digitalio.Direction.OUTPUT | |
busy = digitalio.DigitalInOut(board.BUSY) | |
res = digitalio.DigitalInOut(board.RES) | |
dc = digitalio.DigitalInOut(board.DC) | |
eink_en = digitalio.DigitalInOut(board.EINK_EN) | |
cs = digitalio.DigitalInOut(board.CS) | |
comm_port = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) | |
device = SPIDevice(comm_port, cs) | |
# for framebuffer | |
frame_black = bytearray(round(EPD_WIDTH * EPD_HEIGHT / 8)) | |
frame_red = bytearray(round(EPD_WIDTH * EPD_HEIGHT / 8)) | |
def epd_send_cmd(cmd): | |
dc.value = 0 | |
with device as bus_device: | |
bus_device.write(bytes([cmd])) | |
def epd_send_data(data): | |
dc.value = 1 | |
with device as bus_device: | |
bus_device.write(bytes([data])) | |
def epd_wait_until_idle(): | |
while True: | |
if busy.value != 0: | |
break | |
time.sleep(0.1) | |
led.value = ~led.value | |
def epd_set_lut_bw(): | |
epd_send_cmd(0x20) #g vcom | |
for count in range(15): | |
epd_send_data(lut_vcom0[count]) | |
epd_send_cmd(0x21) #g ww -- | |
for count in range(15): | |
epd_send_data(lut_w[count]) | |
epd_send_cmd(0x22) #g bw r | |
for count in range(15): | |
epd_send_data(lut_b[count]) | |
epd_send_cmd(0x23) #g wb w | |
for count in range(15): | |
epd_send_data(lut_g1[count]) | |
epd_send_cmd(0x24) #g bb b | |
for count in range(15): | |
epd_send_data(lut_g2[count]) | |
def epd_set_lut_red(): | |
epd_send_cmd(0x25) | |
for count in range(15): | |
epd_send_data(lut_vcom1[count]) | |
epd_send_cmd(0x26) | |
for count in range(15): | |
epd_send_data(lut_red0[count]) | |
epd_send_cmd(0x27) | |
for count in range(15): | |
epd_send_data(lut_red1[count]) | |
def epd_reset(): | |
res.value = 0 | |
time.sleep(0.2) | |
res.value = 1 | |
time.sleep(0.2) | |
def epd_display_frame(): | |
epd_send_cmd(DATA_START_TRANSMISSION_1) | |
time.sleep(0.2) | |
for i in range(EPD_HEIGHT * EPD_WIDTH / 8): | |
temp = 0x00 | |
for bit in range(4): | |
if ((frame_black[i] & (0x80 >> bit)) != 0): | |
temp |= 0xC0 >> (bit * 2) | |
epd_send_data(temp) | |
temp = 0x00 | |
for bit in range(4, 8): | |
if ((frame_black[i] & (0x80 >> bit)) != 0): | |
temp |= 0xC0 >> ((bit - 4) * 2) | |
epd_send_data(temp) | |
time.sleep(0.2) | |
epd_send_cmd(DATA_START_TRANSMISSION_2) | |
time.sleep(0.2) | |
for i in range(EPD_HEIGHT * EPD_WIDTH / 8): | |
epd_send_data(frame_red[i]) | |
time.sleep(0.2) | |
epd_send_cmd(DISPLAY_REFRESH) | |
epd_wait_until_idle() | |
def epd_init(): | |
epd_reset() | |
epd_send_cmd(POWER_SETTING) | |
epd_send_data(0x07) | |
epd_send_data(0x00) | |
epd_send_data(0x08) | |
epd_send_data(0x00) | |
epd_send_cmd(BOOSTER_SOFT_START) | |
epd_send_data(0x07) | |
epd_send_data(0x07) | |
epd_send_data(0x07) | |
epd_send_cmd(POWER_ON) | |
epd_wait_until_idle() | |
epd_send_cmd(PANEL_SETTING) | |
epd_send_data(0xcf) | |
epd_send_cmd(VCOM_AND_DATA_INTERVAL_SETTING) | |
epd_send_data(0x17) | |
epd_send_cmd(PLL_CONTROL) | |
epd_send_data(0x39) | |
epd_send_cmd(TCON_RESOLUTION) | |
epd_send_data(0xC8) | |
epd_send_data(0x00) | |
epd_send_data(0xC8) | |
epd_send_cmd(VCM_DC_SETTING_REGISTER) | |
epd_send_data(0x30) | |
epd_set_lut_bw() | |
epd_set_lut_red() | |
time.sleep(0.2) | |
def paint_clear(fb, colored): | |
if colored: | |
val = 0x00 | |
else: | |
val = 0xff | |
for i in range(len(fb)): | |
fb[i] = val | |
def epd_sleep(): | |
epd_send_cmd(VCOM_AND_DATA_INTERVAL_SETTING) | |
epd_send_data(0x17) | |
epd_send_cmd(VCM_DC_SETTING_REGISTER) #to solve Vcom drop | |
epd_send_data(0x00) | |
epd_send_cmd(POWER_SETTING) #power setting | |
epd_send_data(0x02) #gate switch to external | |
epd_send_data(0x00) | |
epd_send_data(0x00) | |
epd_send_data(0x00) | |
epd_wait_until_idle() | |
epd_send_cmd(POWER_OFF) | |
def epaper_pins_off(): | |
busy.direction = digitalio.Direction.OUTPUT | |
res.direction = digitalio.Direction.OUTPUT | |
dc.direction = digitalio.Direction.OUTPUT | |
cs.direction = digitalio.Direction.OUTPUT | |
eink_en.direction = digitalio.Direction.OUTPUT | |
res.value = 0 | |
dc.value = 0 | |
cs.value = 0 | |
eink_en.value = 1 | |
def epaper_pins_init(): | |
busy.direction = digitalio.Direction.INPUT | |
res.direction = digitalio.Direction.OUTPUT | |
res.value = 0 | |
dc.direction = digitalio.Direction.OUTPUT | |
dc.value = 0 | |
cs.direction = digitalio.Direction.OUTPUT | |
cs.value = 0 | |
time.sleep(0.1) | |
eink_en.direction = digitalio.Direction.OUTPUT | |
eink_en.value = 1 | |
def epaper_on(): | |
time.sleep(0.5) | |
eink_en.value = 0 | |
time.sleep(0.5) | |
def epaper_off(): | |
time.sleep(0.5) | |
eink_en.value = 1 | |
def paint_draw_pixel(fb, x, y, colored): | |
if (x < 0 or x >= EPD_WIDTH or y < 0 or y >= EPD_HEIGHT): | |
return | |
if (colored): | |
fb[int((x + y * EPD_WIDTH) / 8)] &= ~(0x80 >> (x % 8)) | |
else: | |
fb[int((x + y * EPD_WIDTH) / 8)] |= 0x80 >> (x % 8) | |
def paint_circle(fb, x, y, radius, colored): | |
# Bresenham algorithm | |
x_pos = -radius | |
y_pos = 0 | |
err = 2 - 2 * radius | |
e2 = 0 | |
while True: | |
paint_draw_pixel(fb, x - x_pos, y + y_pos, colored) | |
paint_draw_pixel(fb, x + x_pos, y + y_pos, colored) | |
paint_draw_pixel(fb, x + x_pos, y - y_pos, colored) | |
paint_draw_pixel(fb, x - x_pos, y - y_pos, colored) | |
e2 = err | |
if (e2 <= y_pos): | |
y_pos = y_pos + 1 | |
err = err + y_pos * 2 + 1 | |
if(-x_pos == y_pos and e2 <= x_pos): | |
e2 = 0 | |
if (e2 > x_pos): | |
x_pos = x_pos + 1 | |
err = err + x_pos * 2 + 1 | |
if x_pos > 0: | |
break | |
epaper_pins_init() | |
epaper_on() | |
epd_init() | |
paint_clear(frame_black, False) | |
paint_clear(frame_red, False) | |
for i in range(0, 100, 8): | |
paint_circle(frame_black, 100, 100, i, True) | |
paint_circle(frame_red, 100, 100, i+4, True) | |
epd_display_frame() | |
epd_sleep() | |
while True: | |
led.value = True | |
time.sleep(0.5) | |
led.value = False | |
time.sleep(0.01) | |
print("Hello, world!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment