Prompt
I'm trying to use a 7.5" e-paper waveshare display with a raspberry pi pico and can't get it to work. please help. Here's my documentation of what I've tried so far
I realized this chip has even more pins than an RP2040 (`ATTINY328P`) so I may as well just use that one. I could also use that [XIAO Seeed RP2040](https://wiki.seeedstudio.com/XIAO-RP2040/) but am worried it won't have enough pins. [This example](https://embeddedcomputing.weebly.com/driving-a-large-e-paper-display-with-a-compact-xiao-rp2040.html) confirms my worries.
![XIAO Seeed to e-Paper](../../img/week9/xiao-seeed-to-epaper.png)
I instead decided to use an [ATTINY328P-AN](https://www.digikey.com/en/products/detail/microchip-technology/ATMEGA328P-AN/2357082). The DigiKey site linked to [this page](https://www.digikey.com/en/models/2357082) where I could download a component that I thought I could import into EagleCAD (I selected the `Eaglecad6 Library` format in the DigiKey download). That format didn't work so I selected `Fusion360 PCB` which gave an LBR file, as needed.
After talking to [Mr. Dubick](http://archive.fabacademy.org/fabacademy2016/charlottelatin/students/999/about.html), I decided to use a [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) which allows for me to more easily use an RP2040 with a lot of pins. I downloaded the EagleCAD library [here](https://github.com/Lobo-T/RPI-Pico-Eagle-lib/blob/main/RpiPico.lbr). I used this of the three components since it was the entire Pico board (not just the RP2040 microprocessor) and is surface mount.
I also found [this schematic](https://www.waveshare.com/w/upload/8/87/E-Paper-Driver-HAT-Schematic.pdf) for an e-paper HAT driver linked on [this page](https://www.waveshare.com/wiki/File:E-Paper-Driver-HAT-Schematic.pdf) from [this website](https://www.waveshare.com/wiki/E-Paper_Driver_HAT). I also found [this post](https://hackaday.io/project/11537-nekocal-an-e-ink-calendar/log/191001-basics-of-driving-e-paper-displays) which compares different methods of operating the e-paper display, and I also skimmed [this article](http://essentialscrap.com/eink/).
[This website](https://www.digikey.be/en/maker/projects/raspberry-pi-pico-rp2040-spi-example-with-micropython-and-cc/9706ea0cf3784ee98e35ff49188ee045) confirmed that SPI communication can be achieved with the Raspberry Pi Pico, and [this tutorial](https://www.youtube.com/watch?v=s7Lud1Gqrqw) eloborates on how to implement it. I also learned that there's a [specific HAT driver](https://www.waveshare.com/wiki/Pico-ePaper-2.9) for a smaller e-paper display designed for the Pico, which is concerned as to whether it's possible to use the Pico to operate a larger display. [This website](https://forum.arduino.cc/t/waveshare-e-paper-displays-with-spi/467865/2768?page=139#:~:text=%2DDiagnostic%20Output%20was,5) suggested a potential wiring for Arduino to talk to the driver. [Here](https://datasheets.raspberrypi.com/pico/Pico-R3-A4-Pinout.pdf) is a detailed pinout sheet for the Pico and [here](https://images.prismic.io/circuito/8e3a980f0f964cc539b4cbbba2654bb660db6f52_arduino-uno-pinout-diagram.png?auto=compress,format) is a detailed pinout sheet for the Arduino Uno.
I then watched [this tutorial](https://www.youtube.com/watch?v=4onIqHClh2s) to gain a better understanding of e-paper displays. This revealed to me that the other wiring I got wasn't correct.
I wasn't sure whether my display was a `7.5"`, `7.5"B`, or `7.5"C` display, so I guessed `7.5"` for now. I then downloaded a zip file of the code. I copied the `epd7in5` folder in the `7.5in` display folder to the Arduino Library folder (`C:\Users\*YOUR_USER*\Documents\Arduino\libraries`). Then it appeared in the Arduino IDE!
I clicked in which added the following to the top of my code.
```cpp
#include <epd7in5.h>
#include <epdif.h>
```
I then went to `File > Examples > epd7in5 > epd7in5-demo` but got an error that the path didn't exist. I then realized that this used a different address (which I accidentally put the library in before) so I wanted to copy the folder there, as well. But before I did that, I tried again, clicking the library under `Examples from Custom Libraries` and the example opened! I uploaded the code but got the following error.
```cmd
:\Users\*USER*\AppData\Local\Temp\.arduinoIDE-unsaved2023223-2744-55l82c.2wca4\epd7in5-demo\imagedata.cpp:27:10: fatal error: avr/pgmspace.h: No such file or directory
#include <avr/pgmspace.h>
^~~~~~~~~~~~~~~~
compilation terminated.
Using library SPI at version 2.0.0 in folder: C:\Users\*USER*\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.7\libraries\SPI
Using library epd7in5 at version 1.0 in folder: C:\Users\*USER*\Documents\Arduino\libraries\epd7in5
exit status 1
Compilation error: avr/pgmspace.h: No such file or directory
```
[This site](https://forum.arduino.cc/t/fatal-error-avr-pgmspace-h-no-such-file-or-directory-error-for-esp8266/538262/3) recommended that I simply commented out this include statement, so I changed the top of `imagedata.cpp` to the following.
```cpp
#include "imagedata.h"
//#include <avr/pgmspace.h>
```
[The same post](https://forum.arduino.cc/t/fatal-error-avr-pgmspace-h-no-such-file-or-directory-error-for-esp8266/538262/5#:~:text=%23if%20defined(AVR)%0A%23include%20%3Cavr/pgmspace.h%3E%0A%23else%C2%A0%20//defined(AVR)%0A%23include%20%3Cpgmspace.h%3E%0A%23endif%C2%A0%20//defined(AVR)) later suggested that I change it to the following, and the compilation was successful, but I got an error that I forgot to select a port. I also changed the board to Arduino Uno.
```cpp
#include "imagedata.h"
//#include <avr/pgmspace.h>
#if defined(AVR)
#include <avr/pgmspace.h>
#else //defined(AVR)
#include <pgmspace.h>
#endif //defined(AVR)
```
I then got an error that the sketch was too large.
```cmd
Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
Sketch uses 33522 bytes (103%) of program storage space. Maximum is 32256 bytes.
Global variables use 185 bytes (9%) of dynamic memory, leaving 1863 bytes for local variables. Maximum is 2048 bytes.
text section exceeds available space in board
Compilation error: text section exceeds available space in board
```
I then tried to use an Arduino Mega 2560 that had more memory. I was able to upload the sketch but nothing happened on the screen. I tried directly connecting the screen to the hat without the long ribbon cable and I tried the B/C and V2 versions of the examples in the [WaveShare E-Paper](https://github.com/waveshare/e-Paper/tree/master/Arduino) library but nothing worked. I tried both the wiring configuration on [this website](https://forum.arduino.cc/t/waveshare-e-paper-displays-with-spi/467865/2982?page=149#) and the one on [this website](https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_Manual) none of which worked!
Based on your documentation, it seems you have tried multiple methods to make the 7.5" e-paper waveshare display work with a Raspberry Pi Pico but have not been successful. The Arduino Mega 2560 tests also did not work.
Response
To help you get the e-paper display working with the Raspberry Pi Pico, I recommend the following steps:
Double-check the display version: Make sure you know the exact version of the e-paper display (7.5", 7.5"B, or 7.5"C). You may find this information on the back of the display or in any accompanying documentation.
Use the correct library: Download the appropriate library for your e-paper display version from the WaveShare GitHub repository and follow the instructions to install it on your Raspberry Pi Pico.
Verify the wiring connections: Double-check the connections between the Raspberry Pi Pico and the e-paper display. Make sure you are using the correct pins for SPI communication, as well as the necessary control pins. You can refer to the Raspberry Pi Pico pinout to verify the correct connections.
Use MicroPython: Since you're using a Raspberry Pi Pico, you may want to consider using MicroPython instead of Arduino for your project. MicroPython is a lean and efficient implementation of the Python programming language, specifically designed for microcontrollers like the Pico. You can find a guide on how to set up MicroPython on a Raspberry Pi Pico here.
Test with example code: Once the library is installed and the wiring connections are verified, upload one of the example codes provided by WaveShare to test the e-paper display. Make sure to select the correct example for your display version.
If you still have issues after trying these steps, there may be a problem with the e-paper display or the Pico itself. In this case, consider reaching out to WaveShare customer support for further assistance.
Prompt
1] please point me to a guide of how to set up the 7.5" e-paper display with the pico;
2] please tell me the correct wiring connections between the pico and the driver hat
Response
I apologize for not providing a specific guide for setting up the 7.5" e-paper display with the Raspberry Pi Pico earlier. While there may not be an exact guide available for the 7.5" e-paper display and Raspberry Pi Pico combination, you can still adapt the steps from guides of similar displays. I'll outline the necessary steps and wiring connections below.
Set up MicroPython on your Raspberry Pi Pico:
Follow the official guide to set up MicroPython on your Raspberry Pi Pico: Getting started with MicroPython on the Raspberry Pi Pico
Install the required libraries:
Download the libraries for the e-paper display from the WaveShare GitHub repository. The library you will need is inside the "lib" folder. Upload the "waveshare_epd" folder to your Raspberry Pi Pico by copying it to the Pico when it is connected to your computer in the MicroPython mode.
Wiring connections between the Raspberry Pi Pico and the e-paper display:
Use the following wiring connections between the Pico and the e-Paper HAT:
Pico 3.3V (Pin 36) -> HAT VCC
Pico GND (Pin 38) -> HAT GND
Pico GP10 (Pin 14) -> HAT DIN (SPI MOSI)
Pico GP11 (Pin 15) -> HAT CLK (SPI SCK)
Pico GP12 (Pin 16) -> HAT CS (SPI Chip Select)
Pico GP13 (Pin 17) -> HAT DC (Data/Command)
Pico GP14 (Pin 20) -> HAT RST (Reset)
Pico GP15 (Pin 21) -> HAT BUSY
Make sure to connect the flat-flex cable from the e-paper display to the HAT correctly, ensuring that the contacts are properly aligned.
Test the display with example code:
Adapt one of the example codes provided by WaveShare for a similar e-paper display to work with your 7.5" e-paper display and Raspberry Pi Pico. Make sure to update the pins in the code to match the wiring connections you made earlier.
Once you have the wiring set up and the necessary libraries installed, you should be able to run the example code on your Raspberry Pi Pico to test the 7.5" e-paper display.
Prompt
whenever I just copy and paste the library code in that folder from the library into the F: drive that appears when I hold the bootloader button when plugging in, it gets deleted soon after and I'm unable to run it
Response
I apologize for the confusion. To upload the library to your Raspberry Pi Pico, you need to use a tool like Thonny, which is a Python IDE that makes it easy to work with MicroPython on the Raspberry Pi Pico. Here's how to do it:
Install Thonny:
Download and install Thonny from the official website: https://thonny.org/. Follow the instructions for your specific operating system.
Connect your Raspberry Pi Pico:
Connect your Raspberry Pi Pico to your computer while holding the BOOTSEL button. Once connected, release the BOOTSEL button. Your Pico should now be in MicroPython mode.
Configure Thonny for the Raspberry Pi Pico:
Open Thonny, and then go to "Tools" > "Options" (or "Thonny" > "Preferences" on macOS). In the "Interpreter" section, choose "MicroPython (Raspberry Pi Pico)" from the list, and select the appropriate port for your Pico. Click "OK" to save the settings.
Upload the library to the Raspberry Pi Pico:
In Thonny, go to "View" > "Files" to open the file explorer pane. You should now see two sections: "This computer" and "MicroPython device". Locate the "waveshare_epd" folder on your computer, and then drag and drop it into the "MicroPython device" section in Thonny. This will upload the library to your Raspberry Pi Pico.
Test the library:
Create a new Python script in Thonny, import the necessary modules from the "waveshare_epd" library, and adapt the example code for your 7.5" e-paper display. Make sure to update the pin assignments in the code to match your wiring connections. Save the script to your Raspberry Pi Pico and run it to test your e-paper display.
By using Thonny, you should be able to upload the library to your Raspberry Pi Pico without it being deleted, and run the example code to test your e-paper display.
Prompt
I'm getting errors with these two imports: import logging
from . import epdconfig
Response
I apologize for the confusion. The error is due to the way the library is structured for use on a Raspberry Pi running Linux, and not directly on a Raspberry Pi Pico running MicroPython. To resolve this issue, you can follow the steps below to modify the library to work with the Pico:
Remove the logging import:
The logging module is not available in MicroPython by default. You can either remove the logging-related lines from the library or replace them with simple print statements for debugging purposes.
For example, replace:
python
Copy code
logging.debug("some message")
with:
python
Copy code
print("some message")
Modify the import statements:
Since you're running the library directly on the Pico, you'll need to modify the import statements in the library files. Change the relative imports like from . import epdconfig to absolute imports like import epdconfig. You'll need to do this for all the files in the waveshare_epd library.
Simplify epdconfig.py:
The epdconfig.py file in the waveshare_epd library contains configuration code for the Raspberry Pi. You'll need to modify this file to work with the Raspberry Pi Pico.
Replace the contents of epdconfig.py with the following code, which configures the necessary SPI and GPIO pins for the Pico:
python
Copy code
import machine
import utime
# SPI and GPIO pins configuration for Raspberry Pi Pico
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 11
SPI_MOSI_PIN = 10
# Configure SPI
spi = machine.SPI(0, baudrate=4000000, sck=machine.Pin(SPI_SCK_PIN), mosi=machine.Pin(SPI_MOSI_PIN))
# Configure GPIO pins
rst = machine.Pin(RST_PIN, machine.Pin.OUT)
dc = machine.Pin(DC_PIN, machine.Pin.OUT)
cs = machine.Pin(CS_PIN, machine.Pin.OUT)
busy = machine.Pin(BUSY_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Delay function
delay_ms = utime.sleep_ms
After making these changes, save the modified library to your Raspberry Pi Pico using Thonny, and update your example code with the correct pin assignments. You should now be able to run the example code on your Pico without encountering import errors.
Prompt
this is the example code - please complete it to display something on the screen
# *****************************************************************************
# * | File : epd7in5.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V4.0
# * | Date : 2019-06-20
# # | Info : python demo
# -----------------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#import logging
import epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
### END OF FILE ###
config.delay_ms(100)
self.ReadBusy()
python
Copy code
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if name == 'main':
from PIL import Image, ImageDraw, ImageFont
css
Copy code
try:
epd = EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
image = Image.new('1', (epd.width, epd.height), 255)
draw = ImageDraw.Draw(image)
print("e-Paper draw text")
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 24)
draw.text((10, 10), 'Hello e-Paper!', font=font, fill=0)
draw.line((10, 60, epd.width - 10, 60), fill=0, width=2)
draw.rectangle((20, 80, epd.width - 20, epd.height - 20), outline=0)
print("e-Paper display")
epd.display(epd.getbuffer(image))
print("e-Paper sleep")
epd.sleep()
except IOError as e:
print(e)
except KeyboardInterrupt:
print("KeyboardInterrupt, exit.")
epdconfig.module_exit()
exit()
Prompt
I got this error even though epdconfig.py is in the same folder
ImportError: no module named 'epdconfig'
Response
If you are encountering an ImportError despite having the epdconfig.py file in the same folder, there are a few possible reasons for this. Here are some troubleshooting steps you can follow:
Check your Python interpreter's working directory:
Make sure that your Python interpreter is running with the correct working directory. You can check the working directory with the following code:
python
Copy code
import os
print(os.getcwd())
Add the current directory to the Python Path:
You can add the current directory to the Python path at runtime by using the following code:
python
Copy code
import sys
import os
sys.path.append(os.getcwd())
import epdconfig
Check for typos and case sensitivity:
Make sure the file name and module name are spelled correctly and that the case matches. Python is case-sensitive, so make sure you are importing the module with the correct case. The file name should be epdconfig.py and the import statement should be import epdconfig.
Verify that you are using the correct Python environment:
If you have multiple Python installations or virtual environments, make sure you are running your script with the intended environment. You can check your Python interpreter by running which python or which python3 in your terminal (or where python for Windows) and verify the Python version with python --version or python3 --version.
Restart your IDE or editor:
In some cases, restarting your IDE or text editor might resolve the issue, as it may have cached the module import incorrectly.
After trying these troubleshooting steps, if you are still encountering issues, please provide more information about your setup, such as your operating system, Python version, and any other relevant details.
**Prompt**
I changed the top to this
import os
print(os.getcwd())
import waveshare_epd.epdconfig
and now I got the following error
Traceback (most recent call last):
File "<stdin>", line 35, in <module>
File "waveshare_epd/epdconfig.py", line 13, in <module>
ValueError: bad SCK pin
It seems that the issue is related to the pin configuration in the epdconfig.py file. The error "ValueError: bad SCK pin" is raised when the specified pin is not valid.
To address this issue, follow these steps:
Inspect the epdconfig.py file to find the pin definitions. You should see lines similar to this:
python
Copy code
RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24
SCK_PIN = ...
MOSI_PIN = ...
Verify the SCK_PIN value:
Check the value assigned to the SCK_PIN variable. Ensure that it matches the actual pin number connected to the Serial Clock (SCK) pin of your e-Paper display. The pin numbering should follow the GPIO (BCM) numbering scheme. You may need to consult the documentation of your specific e-Paper display module to find the correct pin number.
Check the pin validation code:
Look for the part of the code in epdconfig.py where the pins are being validated. The error is likely raised in this section. Make sure that the pin validation logic is correct and does not
**Prompt**
here's what you wrote for epdconfig.py
import machine
import utime
# SPI and GPIO pins configuration for Raspberry Pi Pico
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 11
SPI_MOSI_PIN = 10
# Configure SPI
spi = machine.SPI(0, baudrate=4000000, sck=machine.Pin(SPI_SCK_PIN), mosi=machine.Pin(SPI_MOSI_PIN))
# Configure GPIO pins
rst = machine.Pin(RST_PIN, machine.Pin.OUT)
dc = machine.Pin(DC_PIN, machine.Pin.OUT)
cs = machine.Pin(CS_PIN, machine.Pin.OUT)
busy = machine.Pin(BUSY_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Delay function
delay_ms = utime.sleep_ms
but you told me to wire like this
Pico 3.3V (Pin 36) -> HAT VCC
Pico GND (Pin 38) -> HAT GND
Pico GP10 (Pin 14) -> HAT DIN (SPI MOSI)
Pico GP11 (Pin 15) -> HAT CLK (SPI SCK)
Pico GP12 (Pin 16) -> HAT CS (SPI Chip Select)
Pico GP13 (Pin 17) -> HAT DC (Data/Command)
Pico GP14 (Pin 20) -> HAT RST (Reset)
Pico GP15 (Pin 21) -> HAT BUSY
I apologize for the confusion earlier. Based on the wiring you provided, the epdconfig.py file should have the following pin configuration:
python
Copy code
# SPI and GPIO pins configuration for Raspberry Pi Pico
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 11
SPI_MOSI_PIN = 10
Since the wiring is correct and the pin configuration in epdconfig.py seems to be correct as well, the issue might be related to something else. The error message "ValueError: bad SCK pin" could be a custom error message in the waveshare_epd library that does not match the actual error.
Could you please provide the complete code of the main file you're running, along with the full error traceback? This will help me identify the actual issue and guide you accordingly.
**Prompt**
# *****************************************************************************
# * | File : epd7in5.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V4.0
# * | Date : 2019-06-20
# # | Info : python demo
# -----------------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#import logging
import os
print(os.getcwd())
import waveshare_epd.epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
### END OF FILE ###
config.delay_ms(100)
self.ReadBusy()
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if __name__ == '__main__':
from PIL import Image, ImageDraw, ImageFont
try:
epd = EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
image = Image.new('1', (epd.width, epd.height), 255)
draw = ImageDraw.Draw(image)
print("e-Paper draw text")
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 24)
draw.text((10, 10), 'Hello e-Paper!', font=font, fill=0)
draw.line((10, 60, epd.width - 10, 60), fill=0, width=2)
draw.rectangle((20, 80, epd.width - 20, epd.height - 20), outline=0)
print("e-Paper display")
epd.display(epd.getbuffer(image))
print("e-Paper sleep")
epd.sleep()
except IOError as e:
print(e)
except KeyboardInterrupt:
print("KeyboardInterrupt, exit.")
epdconfig.module_exit()
exit()
/
Traceback (most recent call last):
File "<stdin>", line 35, in <module>
File "waveshare_epd/epdconfig.py", line 13, in <module>
ValueError: bad SCK pin
self.ReadBusy()
ruby
Copy code
def Clear(self):
python
Copy code
self.send_command(0x13)
for i in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5) # check code
def Dev_exit(self):
epdconfig.module_exit()
END OF FILE
**Prompt**
sorry for the confusion. here is the file i'm running
#import logging
import os
print(os.getcwd())
import waveshare_epd.epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
config.delay_ms(100)
self.ReadBusy()
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if __name__ == '__main__':
from PIL import Image, ImageDraw, ImageFont
try:
epd = EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
image = Image.new('1', (epd.width, epd.height), 255)
draw = ImageDraw.Draw(image)
print("e-Paper draw text")
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 24)
draw.text((10, 10), 'Hello e-Paper!', font=font, fill=0)
draw.line((10, 60, epd.width - 10, 60), fill=0, width=2)
draw.rectangle((20, 80, epd.width - 20, epd.height - 20), outline=0)
print("e-Paper display")
epd.display(epd.getbuffer(image))
print("e-Paper sleep")
epd.sleep()
except IOError as e:
print(e)
except KeyboardInterrupt:
print("KeyboardInterrupt, exit.")
epdconfig.module_exit()
exit()
here's edpconfig.py
import machine
import utime
# SPI and GPIO pins configuration for Raspberry Pi Pico
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 11
SPI_MOSI_PIN = 10
# Configure SPI
spi = machine.SPI(0, baudrate=4000000, sck=machine.Pin(SPI_SCK_PIN), mosi=machine.Pin(SPI_MOSI_PIN))
# Configure GPIO pins
rst = machine.Pin(RST_PIN, machine.Pin.OUT)
dc = machine.Pin(DC_PIN, machine.Pin.OUT)
cs = machine.Pin(CS_PIN, machine.Pin.OUT)
busy = machine.Pin(BUSY_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Delay function
delay_ms = utime.sleep_ms
and here's the output
/
Traceback (most recent call last):
File "<stdin>", line 35, in <module>
File "waveshare_epd/epdconfig.py", line 14, in <module>
ValueError: bad SCK pin
It seems like you are using the Waveshare e-Paper display library. The error might be related to the import statement at the beginning of the script, which tries to import the waveshare_epd.epdconfig module. Make sure that you have the Waveshare
**Prompt**
that file is the epdconfig.py because I put it in the waveshare_epd file and the python is running from the "/" directory
Ah, I see. If your Python script is running from the root directory ("/") and you placed the epdconfig.py file inside the waveshare_epd directory, you need to make sure that you import the epdconfig module properly.
To do that, update your import statement in your main script as follows:
python
Copy code
from waveshare_epd import epdconfig
This tells Python to look for the epdconfig module within the waveshare_epd directory.
Make sure that the waveshare_epd directory is in the same directory as your script or within your Python's search path. You can check your Python's search path by running the following code:
python
Copy code
import sys
print(sys.path)
If the waveshare_epd directory is not in the search path, you can add it manually like this:
python
Copy code
import sys
sys.path.append('/path/to/waveshare_epd')
Replace /path/to/waveshare_epd with the actual path to the waveshare_epd directory on your system.
**Prompt**
here is my file structure
waveshare_epd
|
|-*file im running*
|-epdconfig.py
Thank you for clarifying your file structure. In this case, you can use a relative import to import the epdconfig module from the same directory as the file you're running. Here's how you can do that:
In the file you're running, update the import statement as follows:
python
Copy code
from . import epdconfig
The dot . before import indicates a relative import, telling Python to look for the epdconfig module in the same directory as the current script.
If you're running your script as the main module, you might run into issues with relative imports. To avoid this, create a new Python file (e.g., main.py) in the waveshare_epd directory and move your code execution logic to this new file.
For example, if your current file is named my_script.py, you can create a main.py file with the following content:
python
Copy code
from . import my_script
if __name__ == "__main__":
my_script.run()
Then, in your my_script.py file, you can define a run() function that contains the main logic of your script:
python
Copy code
from . import epdconfig
def run():
# Your main script logic here
Now, you can run your script by executing main.py. This approach ensures that relative imports work correctly, and the epdconfig module is imported from the same
**Prompt**
im sorry to interrupt but the problem clearly isn't with the import since my traceback says bad sck pin
I apologize for the confusion. Since the issue seems to be related to the SCK pin configuration, let's focus on that. The error message you provided earlier suggests that the SCK pin you're trying to use might not be supported by the board you're using.
To address this issue, please follow these steps:
Open the epdconfig.py file in the waveshare_epd directory.
Locate the lines where the SCK pin is defined. It should look something like this:
python
Copy code
RST_PIN = 17
DC_PIN = 25
CS_PIN = 8
BUSY_PIN = 24
SCK_PIN = <your_SCK_pin_number_here>
Check the documentation of your specific board to find the correct SCK pin number. The SCK pin number might be labeled as SCLK or CLK on some boards.
Replace the SCK pin number in the epdconfig.py file with the correct one based on your board's documentation.
Save the changes and rerun your script.
By updating the SCK pin number in the epdconfig.py file, you should resolve the "bad SCK pin" error. If you still encounter issues, please provide any additional error messages or details that might help diagnose the problem.
**Prompt**
here's what it looks like, but please update it to match what it should be for spi communication via the raspberry pi pico, and also tell me how to wire my conneciton
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 11
SPI_MOSI_PIN = 10
I apologize for the confusion earlier. Based on your requirement to use SPI communication with the Raspberry Pi Pico, please update your epdconfig.py as follows:
python
Copy code
RST_PIN = 14
DC_PIN = 13
CS_PIN = 12
BUSY_PIN = 15
SPI_SCK_PIN = 10
SPI_MOSI_PIN = 11
Here, I have updated the SPI_SCK_PIN and SPI_MOSI_PIN to match the default SPI pins on the Raspberry Pi Pico.
To wire your e-Paper display to the Raspberry Pi Pico, use the following pin connections:
RST_PIN (14) on the e-Paper display to GP14 on the Raspberry Pi Pico.
DC_PIN (13) on the e-Paper display to GP13 on the Raspberry Pi Pico.
CS_PIN (12) on the e-Paper display to GP12 on the Raspberry Pi Pico.
BUSY_PIN (15) on the e-Paper display to GP15 on the Raspberry Pi Pico.
SPI_SCK_PIN (10) on the e-Paper display to GP10 (SCK) on the Raspberry Pi Pico.
SPI_MOSI_PIN (11) on the e-Paper display to GP11 (MOSI) on the Raspberry Pi Pico.
Additionally, make sure to connect the GND (ground) pin on the e-Paper display to the GND pin on the Raspberry Pi Pico and the VCC (power) pin on the e-Paper display to the 3.3V pin on the Raspberry Pi Pico.
After updating the pin configurations and wiring, try running your script again. The "bad SCK pin" error should be resolved. If you encounter any issues, please provide any additional error messages or details.
**Prompt**
i got the same error again
I apologize for the confusion earlier. It seems that the issue might be related to the MicroPython firmware you are using on the Raspberry Pi Pico. There might be some limitations or differences in the implementation of the machine module.
To resolve this issue, please try using the CircuitPython firmware instead. Follow these steps to install CircuitPython on your Raspberry Pi Pico:
Visit the CircuitPython download page: https://circuitpython.org/board/raspberry_pi_pico/
Download the latest CircuitPython UF2 file for the Raspberry Pi Pico.
Press and hold the BOOTSEL button on your Pico while connecting it to your computer via a USB cable.
Release the BOOTSEL button after connecting the Pico. The Pico should appear as a mass storage device named "RPI-RP2".
Drag and drop the downloaded CircuitPython UF2 file onto the "RPI-RP2" drive. The Pico will reboot and now be running CircuitPython.
Now, you should update your code to use the CircuitPython libraries instead of the MicroPython machine module:
Install the adafruit-circuitpython-busdevice package by downloading it from this link: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/releases and copy the adafruit_bus_device folder to the CIRCUITPY drive that appears when you connect the Raspberry Pi Pico.
Replace the import machine line with the following imports in your epdconfig.py file:
python
Copy code
import board
import digitalio
from adafruit_bus_device.spi_device import SPIDevice
Update the epdconfig.py file to use CircuitPython's SPI and GPIO objects:
python
Copy code
# Pin definitions
RST_PIN = digitalio.DigitalInOut(board.GP14)
DC_PIN = digitalio.DigitalInOut(board.GP13)
CS_PIN = digitalio.DigitalInOut(board.GP12)
BUSY_PIN = digitalio.DigitalInOut(board.GP15)
# SPI definitions
spi = board.SPI()
spi_device = SPIDevice(spi, CS_PIN)
Now, you can use CircuitPython to interact with the e-Paper display. If you are using the Waveshare library, make sure to update the relevant parts of the library to work with CircuitPython as well.
**Prompt**
I completed step 5, should i unplug it then replug it in? if so do I hold down the bootloade rbutton
Once you've completed step 5 and the Pico has rebooted, you don't need to hold down the BOOTSEL button anymore. The Pico should now be running CircuitPython. When you connect the Pico to your computer without holding the BOOTSEL button, it should appear as a mass storage device named "CIRCUITPY" instead of "RPI-RP2".
You can now proceed with copying the required libraries and modifying your code to work with CircuitPython as mentioned in my previous response.
**Prompt**
here's epdconfig.py
import board
import digitalio
from adafruit_bus_device.spi_device import SPIDevice
import utime
# Pin definitions
RST_PIN = digitalio.DigitalInOut(board.GP14)
DC_PIN = digitalio.DigitalInOut(board.GP13)
CS_PIN = digitalio.DigitalInOut(board.GP12)
BUSY_PIN = digitalio.DigitalInOut(board.GP15)
# SPI definitions
spi = board.SPI()
spi_device = SPIDevice(spi, CS_PIN)
# SPI and GPIO pins configuration for Raspberry Pi Pico
#RST_PIN = 14
#DC_PIN = 13
#CS_PIN = 12
#BUSY_PIN = 15
#SPI_SCK_PIN = 10
#SPI_MOSI_PIN = 11
# Configure SPI
#spi = machine.SPI(0, baudrate=4000000, sck=machine.Pin(SPI_SCK_PIN), mosi=machine.Pin(SPI_MOSI_PIN))
# Configure GPIO pins
#rst = machine.Pin(RST_PIN, machine.Pin.OUT)
#dc = machine.Pin(DC_PIN, machine.Pin.OUT)
#cs = machine.Pin(CS_PIN, machine.Pin.OUT)
#busy = machine.Pin(BUSY_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Delay function
delay_ms = utime.sleep_ms
I got an error that utime isn't a thing
My apologies for the confusion. In CircuitPython, the time module is used instead of utime. Please change the import statement and update the delay_ms function definition accordingly:
Replace this line:
python
Copy code
import utime
with:
python
Copy code
import time
And update the delay_ms function definition:
Replace this line:
python
Copy code
delay_ms = utime.sleep_ms
with:
python
Copy code
def delay_ms(milliseconds):
time.sleep(milliseconds / 1000)
Now your epdconfig.py should work without the utime error.
**Prompt**
I now got this error
Traceback (most recent call last):
File "<stdin>", line 32, in <module>
File "epdconfig.py", line 15, in <module>
AttributeError: 'module' object has no attribute 'SPI'
It appears that the board module does not have an SPI attribute in the version of CircuitPython you are using. Instead, let's try importing the busio module and create an SPI object from it.
Replace this line:
python
Copy code
spi = board.SPI()
with:
python
Copy code
import busio
spi = busio.SPI(board.GP10, board.GP11)
This change imports the busio module and initializes the spi variable with an SPI object using the SCK and MOSI pins defined by board.GP10 and board.GP11, respectively.
Here's the updated epdconfig.py:
python
Copy code
import board
import busio
import digitalio
from adafruit_bus_device.spi_device import SPIDevice
import time
# Pin definitions
RST_PIN = digitalio.DigitalInOut(board.GP14)
DC_PIN = digitalio.DigitalInOut(board.GP13)
CS_PIN = digitalio.DigitalInOut(board.GP12)
BUSY_PIN = digitalio.DigitalInOut(board.GP15)
# SPI definitions
spi = busio.SPI(board.GP10, board.GP11)
spi_device = SPIDevice(spi, CS_PIN)
# Delay function
def delay_ms(milliseconds):
time.sleep(milliseconds / 1000)
This should resolve the AttributeError related to the SPI object.
**Prompt**
now i got this error Traceback (most recent call last):
File "<stdin>", line 298, in <module>
ImportError: no module named 'PIL'
The error you're encountering is because the PIL library (Python Imaging Library) is not available in CircuitPython. Instead, you'll want to use the adafruit_imageload library.
First, you need to install the adafruit_imageload library. Download the library from the following link:
adafruit-circuitpython-imageload
Find the latest version (.mpy file) and copy it to your lib folder on your Raspberry Pi Pico.
Next, you'll need to update the code that uses PIL to use adafruit_imageload instead. Locate the section of your code where the PIL library is imported, and replace it with an import statement for the adafruit_imageload library:
python
Copy code
import adafruit_imageload
Then, find the part of the code that loads the image using PIL. It might look like this:
python
Copy code
from PIL import Image
image = Image.open("image.bmp")
Replace it with the following code, which uses adafruit_imageload to load the image:
python
Copy code
with open("image.bmp", "rb") as f:
image, palette = adafruit_imageload.load(f, bitmap=adafruit_imageload.Bitmap, palette=adafruit_imageload.Palette)
You'll need to update any other parts of the code that rely on PIL to use the image object returned by adafruit_imageload. The specific changes depend on how the code is structured and how the PIL library is used. If you need further assistance, please provide the relevant sections of your code that deal with image manipulation.
**Prompt**
here was the old code
pd = EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
image = Image.new('1', (epd.width, epd.height), 255)
draw = ImageDraw.Draw(image)
print("e-Paper draw text")
font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 24)
draw.text((10, 10), 'Hello e-Paper!', font=font, fill=0)
draw.line((10, 60, epd.width - 10, 60), fill=0, width=2)
draw.rectangle((20, 80, epd.width - 20, epd.height - 20), outline=0)
print("e-Paper display")
epd.display(epd.getbuffer(image))
print("e-Paper sleep")
epd.sleep()
To modify the code to work with CircuitPython and the adafruit_imageload library, follow these steps:
Replace the Image import and creation with the adafruit_imageload library.
Replace the font loading and drawing with the adafruit_bitmap_font library.
Update the rest of the code to be compatible with CircuitPython.
First, you'll need to install the adafruit_bitmap_font library. Download it from the following link:
adafruit-circuitpython-bitmap_font
Find the latest version (.mpy file) and copy it to your lib folder on your Raspberry Pi Pico.
Now, update the code as follows:
python
Copy code
from adafruit_epd import epd
from adafruit_bitmap_font import bitmap_font
from adafruit_imageload import bitmap
import displayio
pd = epd.EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
print("e-Paper draw text")
image = displayio.Bitmap(epd.width, epd.height, 2)
palette = displayio.Palette(2)
palette[0] = 0xFFFFFF
palette[1] = 0x000000
image_group = displayio.Group()
image_group.append(displayio.TileGrid(image, pixel_shader=palette))
epd.display.show(image_group)
font = bitmap_font.load_font('/path/to/your/font.bdf')
draw = displayio.Bitmap(epd.width, epd.height, 2)
text_area = bitmap_label.Label(font, text='Hello e-Paper!', color=0x000000)
text_area.x = 10
text_area.y = 10
image_group.append(text_area)
print("e-Paper display")
epd.display.refresh()
print("e-Paper sleep")
epd.sleep()
Replace /path/to/your/font.bdf with the actual path to the BDF font file on your Raspberry Pi Pico.
This updated code will create a displayio.Bitmap with the same dimensions as your e-Paper display, and then draw text, lines, and rectangles using the displayio library.
Please note that this is just a starting point, and you may need to adjust the code depending on your specific e-Paper display and the features you need. Additionally, you may need to convert your TTF font to a BDF font format for use with CircuitPython. You can use tools like FontForge to convert TTF fonts to BDF.
**Prompt**
I can't find an mpy file in either of the lbiraries
I apologize for the confusion. In that case, you can install the libraries from the Adafruit CircuitPython Bundle. The bundle contains all the necessary library files in .mpy format.
Download the Adafruit CircuitPython Bundle from the following link:
adafruit-circuitpython-bundle
Look for the latest version of the bundle, and download the zip file. For example, adafruit-circuitpython-bundle-7.x-mpy-20220321.zip (the date and version number may change).
Extract the zip file.
Find the following library files inside the lib folder of the extracted zip file:
adafruit_bitmap_font
adafruit_imageload
Copy both library folders to the lib folder on your Raspberry Pi Pico.
Once you have the libraries installed, you can proceed with the code changes I suggested in the previous response. Make sure to replace /path/to/your/font.bdf with the actual path to the BDF font file on your Raspberry Pi Pico.
**Prompt**
there's no adafruit_imageload.mpy, only a folder of the same name
Apologies for the confusion. If there's a folder named adafruit_imageload, it's the library itself. Please copy the entire adafruit_imageload folder to the lib directory on your Raspberry Pi Pico. The same applies to the adafruit_bitmap_font folder.
After copying both folders to the lib directory on your Pico, you should be able to import and use the libraries in your code.
**Prompt**
I Got this error
The previous model used in this conversation is unavailable. We've switched you to the latest default model
It seems that the adafruit_display_text library has not been installed properly. You can try reinstalling it by running the following command:
arduino
Copy code
pip3 install adafruit-circuitpython-display-text
If the installation still fails, you can try updating your pip and setuptools packages first by running:
css
Copy code
pip3 install --upgrade pip setuptools
After that, try running the installation command for adafruit_display_text again. If you continue to have issues, please let me know.
**Prompt**
I'm having trouble with the following code on a raspberry pi pico i configured to run circuitpython
# *****************************************************************************
# * | File : epd7in5.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V4.0
# * | Date : 2019-06-20
# # | Info : python demo
# -----------------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#import logging
import epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
config.delay_ms(100)
self.ReadBusy()
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if __name__ == '__main__':
#from PIL import Image, ImageDraw, ImageFont
#from adafruit_epd import epd
import adafruit_epd.epd as epd
import bitmap_font
#from adafruit_imageload import bitmap
import adafruit_imageload
import displayio
pd = epd.EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
print("e-Paper draw text")
image = displayio.Bitmap(epd.width, epd.height, 2)
palette = displayio.Palette(2)
palette[0] = 0xFFFFFF
palette[1] = 0x000000
image_group = displayio.Group()
image_group.append(displayio.TileGrid(image, pixel_shader=palette))
epd.display.show(image_group)
font = bitmap_font.load_font('/path/to/your/font.bdf')
draw = displayio.Bitmap(epd.width, epd.height, 2)
text_area = bitmap_label.Label(font, text='Hello e-Paper!', color=0x000000)
text_area.x = 10
text_area.y = 10
image_group.append(text_area)
print("e-Paper display")
epd.display.refresh()
print("e-Paper sleep")
epd.sleep()
It seems like the code you provided is incomplete as there is an ellipsis (...) at the end. However, based on what you have shared, the issue is likely to be due to the fact that the logger object is not defined. There are several instances where logger is called, but it is not defined anywhere in the code.
To fix this error, you can either define a logger object or comment out the code that uses the logger object. To comment out the code, simply add a # character at the beginning of each line where logger is called.
Here's an example of what the code should look like with the logger commented out:
python
Copy code
# import logging
import epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
# logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0,
**Prompt**
focus on this part of the code
import adafruit_epd.epd as epd
import bitmap_font
#from adafruit_imageload import bitmap
import adafruit_imageload
import displayio
pd = epd.EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
print("e-Paper draw text")
image = displayio.Bitmap(epd.width, epd.height, 2)
palette = displayio.Palette(2)
palette[0] = 0xFFFFFF
This part of the code is importing necessary libraries and initializing the e-Paper display.
adafruit_epd.epd library is used for controlling e-Paper display hardware. bitmap_font library is used for rendering text on the display. adafruit_imageload library is used for loading image files onto the display. displayio is a library for managing displays, and it provides an interface for drawing to the screen.
pd is an instance of the EPD class, which is used for controlling the display.
The epd.init() method initializes the display, and epd.clear() method clears the display.
The displayio.Bitmap creates a bitmap object with a specified width and height, and the displayio.Palette creates a palette object with two colors - black and white, represented by values 0 and 1. The palette[0] = 0xFFFFFF sets the background color of the display to white.
The print statements are used for debugging purposes to check the status of the e-Paper display.
**Prompt**
when i run this code
from adafruit_epd import epd
import bitmap_font
from adafruit_imageload import bitmap
import displayio
pd = epd.EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
print("e-Paper draw text")
image = displayio.Bitmap(epd.width, epd.height, 2)
palette = displayio.Palette(2)
palette[0] = 0xFFFFFF
palette[1] = 0x000000
image_group = displayio.Group()
image_group.append(displayio.TileGrid(image, pixel_shader=palette))
epd.display.show(image_group)
font = bitmap_font.load_font('/path/to/your/font.bdf')
draw = displayio.Bitmap(epd.width, epd.height, 2)
text_area = bitmap_label.Label(font, text='Hello e-Paper!', color=0x000000)
text_area.x = 10
text_area.y = 10
image_group.append(text_area)
print("e-Paper display")
epd.display.refresh()
print("e-Paper sleep")
epd.sleep()
i recieve this error
Traceback (most recent call last):
File "<stdin>", line 307, in <module>
AttributeError: 'module' object has no attribute 'EPD'
This error occurs because the EPD class is not present in the adafruit_epd module. Instead, it is present in the adafruit_epd.epd module. Therefore, you should update the import
**Prompt**
adafruit_epd just has a file called epd.mpy
In that case, you need to modify the import statement for the EPD class. Try changing the line:
javascript
Copy code
from adafruit_epd import epd
to:
javascript
Copy code
from adafruit_epd.epd import EPD
Then modify the line that creates an instance of the EPD class from:
makefile
Copy code
pd = epd.EPD()
to:
scss
Copy code
pd = EPD()
This should resolve the attribute error you encountered.
**Prompt**
I got this error
Traceback (most recent call last):
File "<stdin>", line 300, in <module>
ImportError: cannot import name EPD
It's possible that the EPD class is not defined in the adafruit_epd.epd module you are trying to import. You can try updating the adafruit_epd library to the latest version, or double-checking that you have the correct version installed.
Alternatively, you can try importing the EPD class directly from the adafruit_epd module like this:
javascript
Copy code
from adafruit_epd import EPD
Then you can create an instance of the EPD class like this:
scss
Copy code
pd = EPD()
This should avoid any issues with the EPD class not being defined in the adafruit_epd.epd module.
**Prompt**
now i got this error
Traceback (most recent call last):
File "<stdin>", line 302, in <module>
ImportError: no module named 'adafruit_imageload.bitmap'
and the adafrit_imageload library has a bunch of mpy files (none of them bitmap.mpy) and a bmp and pnm folder
It seems like the adafruit_imageload module is missing the bitmap module. You can try to install this module by running:
Copy code
pip install adafruit-circuitpython-imageload
If the installation is successful, you should be able to import the bitmap module using:
javascript
Copy code
from adafruit_imageload import bitmap
If you still get an error, you may need to double-check that the adafruit-circuitpython-imageload library is installed in your Python environment.
**Prompt**
I can't use pip - i'm running it on a raspberry pi pico
If you are running MicroPython on a Raspberry Pi Pico, you cannot use pip to install libraries. Instead, you will need to manually copy the required library files to the Pico.
In this case, since you are getting an error that adafruit_imageload.bitmap module is missing, you can download the library from the Adafruit Github repository at this link: https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.
Once you have downloaded the library, copy the adafruit_imageload folder to the root directory of your Pico. You should then be able to run your code without any issues.
**Prompt**
now with this code
from adafruit_epd import EPD
import bitmap_font
import adafruit_imageload
import displayio
pd = EPD()
i got this error
Traceback (most recent call last):
File "<stdin>", line 305, in <module>
TypeError: 'module' object is not callable
>>>
The error message suggests that the EPD() function is not found in the adafruit_epd module. Try changing EPD() to adafruit_epd.epd() as shown below:
java
Copy code
import adafruit_epd.epd as epd
import bitmap_font
import adafruit_imageload
import displayio
pd = epd.epd()
This should instantiate an EPD object and store it in the pd variable.
**Prompt**
here's an example from the documentation
import digitalio
import busio
import board
from adafruit_epd.epd import Adafruit_EPD
from adafruit_epd.il0373 import Adafruit_IL0373
# create the spi device and pins we will need
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
ecs = digitalio.DigitalInOut(board.D12)
dc = digitalio.DigitalInOut(board.D11)
srcs = digitalio.DigitalInOut(board.D10) # can be None to use internal memory
rst = digitalio.DigitalInOut(board.D9) # can be None to not use this pin
busy = digitalio.DigitalInOut(board.D5) # can be None to not use this pin
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display
cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs,
rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_EPD.WHITE)
display.pixel(10, 100, Adafruit_EPD.BLACK)
print("Draw Rectangles")
display.fill_rect(5, 5, 10, 10, Adafruit_EPD.RED)
display.rect(0, 0, 20, 30, Adafruit_EPD.BLACK)
print("Draw lines")
display.line(0, 0, display.width-1, display.height-1, Adafruit_EPD.BLACK)
display.line(0, display.height-1, display.width-1, 0, Adafruit_EPD.RED)
print("Draw text")
display.text('hello world', 25, 10, Adafruit_EPD.BLACK)
display.display()
here's some more documentation
CircuitPython driver for Adafruit ePaper display breakouts * Author(s): Dean Miller
classadafruit_epd.epd.Adafruit_EPD(width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin)
Base class for EPD displays
command(cmd, data=None, end=True)
Send command byte to display.
display()
show the contents of the display buffer
fill(color)
fill the screen with the passed color
fill_rect(x, y, width, height, color)
fill a rectangle with the passed color
hardware_reset()
If we have a reset pin, do a hardware reset by toggling it
propertyheight
The height of the display, accounting for rotation
hline(x, y, width, color)
draw a horizontal line
image(image)
Set buffer to value of Python Imaging Library image. The image should be in RGB mode and a size equal to the display size.
line(x_0, y_0, x_1, y_1, color)
Draw a line from (x_0, y_0) to (x_1, y_1) in passed color
pixel(x, y, color)
draw a single pixel in the display buffer
power_down()
Power down the display, must be implemented in subclass
power_up()
Power up the display in preparation for writing RAM and updating. must be implemented in subclass
rect(x, y, width, height, color)
draw a rectangle
propertyrotation
The rotation of the display, can be one of (0, 1, 2, 3)
set_black_buffer(index, inverted)
Set the index for the black buffer data (0 or 1) and whether its inverted
set_color_buffer(index, inverted)
Set the index for the color buffer data (0 or 1) and whether its inverted
set_ram_address(x, y)
Set the RAM address location, must be implemented in subclass
text(string, x, y, color, *, font_name='font5x8.bin', size=1)
Write text string at location (x, y) in given color, using font file
update()
Update the display from internal memory, must be implemented in subclass
vline(x, y, height, color)
draw a vertical line
propertywidth
The width of the display, accounting for rotation
write_ram(index)
Send the one byte command for starting the RAM write process. Returns the byte read at the same time over SPI. index is the RAM buf
It seems that the code you posted is trying to import a module called adafruit_imageload.bitmap which does not exist in the adafruit_imageload library. Instead, you can use the adafruit_imageload module to load image files and create displayio.Bitmap objects from them.
Here's an example:
python
Copy code
import board
import busio
import displayio
from adafruit_epd.epd import Adafruit_EPD
from adafruit_epd.il0373 import Adafruit_IL0373
import adafruit_imageload
import bitmap_font
# Initialize SPI bus
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Initialize ePaper display
display = Adafruit_IL0373(
104, 212, spi,
cs_pin=board.D10,
dc_pin=board.D9,
sramcs_pin=board.D6,
rst_pin=board.D7,
busy_pin=board.D5
)
# Create a new displayio group
group = displayio.Group()
# Load image from file and create a Bitmap object
with open("image.bmp", "rb") as f:
image_data = bytearray(f.read())
image, palette = adafruit_imageload.load(image_data)
# Create a TileGrid from the Bitmap and Palette
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
# Add the TileGrid to the displayio group
group.append(tile_grid)
# Load a font and create a Bitmap for the text
font = bitmap_font.load_font("/path/to/your/font.bdf")
text_bitmap = displayio.Bitmap(display.width, display.height, 2)
# Create a label with the font and text
label = bitmap_font.BitmapLabel(font, text="Hello e-Paper!", color=0x000000)
label.x = 10
label.y = 10
# Draw the label onto the text Bitmap
label.draw(text_bitmap)
# Create a TileGrid from the text Bitmap and add it to the group
text_tile_grid = displayio.TileGrid(text_bitmap, pixel_shader=palette)
group.append(text_tile_grid)
# Add the group to the display
display.show(group)
# Refresh the display
display.refresh()
# Put the display to sleep
display.sleep()
This code loads an image from a file called "image.bmp", creates a displayio.TileGrid from it, adds the TileGrid to a new displayio.Group, loads a font, creates a displayio.Bitmap for the text, creates a bitmap_font.BitmapLabel with the font and text, draws the label onto the text Bitmap, creates a TileGrid from the text Bitmap, adds it to the group, shows the group on the display, refreshes the display, and puts it to sleep.
You'll need to replace "/path/to/your/font.bdf" with the path to your own font file.
**Prompt**
now modify it to use a 7.5"in e-paper display
Sure, here's an example modified to use a 7.5" e-paper display:
python
Copy code
import digitalio
import busio
import board
from adafruit_epd.epd import Adafruit_EPD
from adafruit_epd.il0373 import Adafruit_IL0373
# create the spi device and pins we will need
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
ecs = digitalio.DigitalInOut(board.D12)
dc = digitalio.DigitalInOut(board.D11)
srcs = digitalio.DigitalInOut(board.D10) # can be None to use internal memory
rst = digitalio.DigitalInOut(board.D9) # can be None to not use this pin
busy = digitalio.DigitalInOut(board.D5) # can be None to not use this pin
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(640, 384, spi, # 7.5" Tri-color display
cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs,
rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_EPD.WHITE)
display.pixel(10, 100, Adafruit_EPD.BLACK)
print("Draw Rectangles")
display.fill_rect(5, 5, 10, 10, Adafruit_EPD.RED)
display.rect(0, 0, 20, 30, Adafruit_EPD.BLACK)
print("Draw lines")
display.line(0, 0, display.width-1, display.height-1, Adafruit_EPD.BLACK)
display.line(0, display.height-1, display.width-1, 0, Adafruit_EPD.RED)
print("Draw text")
display.text('hello world', 25, 10, Adafruit_EPD.BLACK)
display.display()
Note that the main change is to update the width and height parameters to match those of the 7.5" e-paper display, which in this case are 640 pixels wide and 384 pixels tall.
**Prompt**
I don't believe mine is tri-color
Alright, in that case, you can modify the code to use the Adafruit_IL0373 class, which is used for black and white displays. Here's an example code that you can use as a starting point:
python
Copy code
import digitalio
import busio
import board
from adafruit_epd.il0373 import Adafruit_IL0373
# create the spi device and pins we will need
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
ecs = digitalio.DigitalInOut(board.D12)
dc = digitalio.DigitalInOut(board.D11)
srcs = digitalio.DigitalInOut(board.D10) # can be None to use internal memory
rst = digitalio.DigitalInOut(board.D9) # can be None to not use this pin
busy = digitalio.DigitalInOut(board.D5) # can be None to not use this pin
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(640, 384, spi, # 7.5" monochrome display
cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs,
rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_IL0373.WHITE)
print("Draw text")
display.text('Hello ePaper!', 25, 10, Adafruit_IL0373.BLACK)
display.display()
# put the device to sleep
print("Sleep")
display.sleep()
You may need to adjust the pins and the rotation value to match your hardware.
**Prompt**
i don't have ecs, dc, srcs pins, etc - i have busy, rst, dc, cs, clk, din, gnd ,vcc
The pins you mentioned are the SPI pins for your e-paper display. To use your display with the Raspberry Pi Pico, you will need to connect these pins to the corresponding SPI pins on the Pico.
Here is a mapping of the SPI pins on the Pico to their physical pins:
SCK (clock): Pin 2 (GP2)
MOSI (data out): Pin 3 (GP3)
MISO (data in): Pin 4 (GP4)
CS (chip select): You can choose any GPIO pin for this. For example, you can use Pin 5 (GP5).
You will also need to connect the other pins on your display to the Pico:
BUSY: Any GPIO pin on the Pico. For example, you can use Pin 6 (GP6).
RST: Any GPIO pin on the Pico. For example, you can use Pin 7 (GP7).
DC: Any GPIO pin on the Pico. For example, you can use Pin 8 (GP8).
VCC and GND: Connect these pins to a 3.3V and ground pins on the Pico, respectively.
Once you have connected all the pins, you can modify the code I provided earlier to use the correct pins for your display. You can also adjust the display dimensions in the Adafruit_IL0373 class constructor to match the size of your display.
**Prompt**
please modify the code
Sure, here's an example code that uses the pins you mentioned and sets up the display for a 7.5 inch e-paper display:
python
Copy code
import board
import digitalio
import busio
import adafruit_epd.epd7in5 as epd7in5
import adafruit_imageload
import displayio
# Set up SPI communication
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Set up display pins
cs = digitalio.DigitalInOut(board.D10)
dc = digitalio.DigitalInOut(board.D8)
rst = digitalio.DigitalInOut(board.D9)
busy = digitalio.DigitalInOut(board.D7)
# Initialize the display
display = epd7in5.EPD(spi, cs, dc, rst, busy)
# Clear the display
display.fill(epd7in5.WHITE)
display.show()
# Load and display an image
image, palette = adafruit_imageload.load("/path/to/your/image.bmp")
bitmap = displayio.Bitmap(display.width, display.height, len(palette))
palette = displayio.Palette(len(palette))
for idx, color in enumerate(palette):
palette[idx] = color
for x in range(display.width):
for y in range(display.height):
color_index = image[x + y * display.width]
bitmap[x, y] = color_index
display.pixel(x, y, color_index)
display.show()
# Display some text
font = bitmap_font.load_font('/path/to/your/font.bdf')
text_group = displayio.Group()
text_area = bitmap_label.Label(font, text='Hello e-Paper!', color=0x000000)
text_area.x = 10
text_area.y = 10
text_group.append(text_area)
display.show(text_group)
Make sure to replace "/path/to/your/image.bmp" and "/path/to/your/font.bdf" with the actual file paths on your Raspberry Pi Pico.
**Prompt**
please do it where you generate the image in the code as opposed to importing one, liek you did before
Sure, here's an example code that generates an image using the Python Imaging Library and displays it on a 7.5" e-paper display using the Adafruit CircuitPython library:
python
Copy code
import busio
import digitalio
import board
from adafruit_epd.ssd1675 import Adafruit_SSD1675
from PIL import Image, ImageDraw, ImageFont
# Initialize the SPI bus and pins we will need
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.CE0)
dc = digitalio.DigitalInOut(board.D22)
rst = digitalio.DigitalInOut(board.D27)
busy = digitalio.DigitalInOut(board.D17)
# Give them all to our driver
display = Adafruit_SSD1675(122, 250, spi, cs, dc, rst, busy)
# Clear the display buffer
display.fill(Adafruit_SSD1675.WHITE)
# Create a PIL ImageDraw object to draw on the display buffer
image = Image.new("RGB", (display.width, display.height), Adafruit_SSD1675.WHITE)
draw = ImageDraw.Draw(image)
# Draw a rectangle in the center of the display buffer
draw.rectangle((10, 10, display.width - 10, display.height - 10), fill=Adafruit_SSD1675.BLACK)
# Draw some text in the center of the rectangle
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 36)
text = "Hello, world!"
text_size = draw.textsize(text, font=font)
text_x = (display.width - text_size[0]) // 2
text_y = (display.height - text_size[1]) // 2
draw.text((text_x, text_y), text, fill=Adafruit_SSD1675.WHITE, font=font)
# Display the image on the e-paper display
display.image(image)
display.display()
# Put the display to sleep
display.sleep()
This code should work for a 7.5" e-paper display with the SSD1675 controller, assuming the pins are connected correctly and you have installed the necessary libraries. You may need to adjust the font path and other parameters depending on your setup.
**Prompt**
do this usign teh adafruit_imageload library - circuit pytho ncan't use pil
Sure, here's an example code that uses adafruit_imageload library to load an image and display it on a 7.5" e-paper display.
python
Copy code
import digitalio
import busio
import board
import adafruit_epd.epd7in5 as epd7in5
import adafruit_imageload
import displayio
# Initialize SPI bus and control pins
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
busy = digitalio.DigitalInOut(board.D5)
cs = digitalio.DigitalInOut(board.D6)
dc = digitalio.DigitalInOut(board.D9)
rst = digitalio.DigitalInOut(board.D10)
# Initialize e-paper display
epd = epd7in5.EPD(spi, cs, dc, rst, busy)
# Create a displayio group to hold the image
image_group = displayio.Group()
# Load the image from file
with open('/path/to/image.bmp', 'rb') as f:
image = adafruit_imageload.load(f, bitmap=displayio.Bitmap, palette=displayio.Palette)
# Add the image to the displayio group
image_grid = displayio.TileGrid(image, pixel_shader=image.palette)
image_group.append(image_grid)
# Show the image on the e-paper display
epd.display(image_group)
# Put the display to sleep
epd.sleep()
Make sure to replace the path to the image file in the with open() statement with the actual path of your image file.
**Prompt**
ImportError: no module named 'adafruit_epd.epd7in5'
It looks like the Adafruit EPD library you have installed does not include the EPD7in5 driver. You may need to install a newer version of the library or manually add the driver file to your project.
One way to manually add the driver file is to download the driver file from the Adafruit GitHub repository and place it in the same directory as your code. Here's an example of how you can do that:
Go to the GitHub repository for the Adafruit CircuitPython EPD library: https://github.com/adafruit/Adafruit_CircuitPython_EPD
Click on the "epd7in5" directory.
Click on the file "adafruit_epd7in5.py" to view its contents.
Copy the entire contents of the file.
In your text editor, create a new file and paste the contents of the "adafruit_epd7in5.py" file into it.
Save the new file in the same directory as your code.
In your code, change the import statement to the following:
javascript
Copy code
from adafruit_epd7in5 import EPD7in5
This should allow you to use the EPD7in5 driver in your code.
**Prompt**
AttributeError: 'module' object has no attribute 'D10'
It seems like the board module doesn't have a D10 attribute. You can try to use the actual pin number instead of the board name:
python
Copy code
srcs = digitalio.DigitalInOut(board.GP10)
Alternatively, you can use the find_device method of the busio module to look for a particular SPI device by name or by the chip select (CS) pin number:
python
Copy code
spi = busio.SPI(board.GP18, board.GP19)
ecs = digitalio.DigitalInOut(board.GP21)
dc = digitalio.DigitalInOut(board.GP20)
rst = digitalio.DigitalInOut(board.GP16)
busy = digitalio.DigitalInOut(board.GP17)
# find the display on the SPI bus
display = Adafruit_IL0373(104, 212, spi, cs_pin=ecs, dc_pin=dc, rst_pin=rst, busy_pin=busy, baudrate=1000000)
**Prompt**
modify this to be that way
cs = digitalio.DigitalInOut(board.D10)
dc = digitalio.DigitalInOut(board.D8)
rst = digitalio.DigitalInOut(board.D9)
busy = digitalio.DigitalInOut(board.D7)
Sure, here's the modified code:
arduino
Copy code
import digitalio
import busio
**Prompt**
but with GP instead of D
Sure! Here's the modified code with GP pins:
python
Copy code
import digitalio
import busio
import board
from adafruit_epd.epd import Adafruit_EPD
from adafruit_epd.epd7in5 import Adafruit_IL0373
# create the spi device and pins we will need
spi = busio.SPI(board.GP18, MOSI=board.GP19, MISO=board.GP16)
cs = digitalio.DigitalInOut(board.GP10)
dc = digitalio.DigitalInOut(board.GP8)
rst = digitalio.DigitalInOut(board.GP9)
busy = digitalio.DigitalInOut(board.GP7)
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(800, 480, spi, # 7.5" Tri-color display
cs_pin=cs, dc_pin=dc,
rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_EPD.WHITE)
display.pixel(10, 100, Adafruit_EPD.BLACK)
# load image
print("Load image")
with open("image.bmp", "rb") as f:
bmp = adafruit_imageload.load(f)
# set up group and tile grid
image_group =
**Prompt**
what should i set as sramcs_pin=?
You can set sramcs_pin=None since the Adafruit_EPD class constructor specifies that this parameter is optional and has a default value of None.
**Prompt**
i decuded to use il0373
Okay, here's an updated code using IL0373 and the pins you specified:
python
Copy code
import digitalio
import busio
import board
import adafruit_imageload
from adafruit_epd.il0373 import Adafruit_IL0373
# create the spi device and pins we will need
spi = busio.SPI(board.GP18, MOSI=board.GP19, MISO=board.GP16)
cs = digitalio.DigitalInOut(board.GP10)
dc = digitalio.DigitalInOut(board.GP8)
rst = digitalio.DigitalInOut(board.GP9)
busy = digitalio.DigitalInOut(board.GP7)
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(128, 480, spi, cs_pin=cs, dc_pin=dc, rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_IL0373.WHITE)
display.pixel(10, 100, Adafruit_IL0373.BLACK)
print("Draw Rectangles")
display.fill_rect(5, 5, 10, 10, Adafruit_IL0373.RED)
display.rect(0, 0, 20, 30, Adafruit_IL0373.BLACK)
print("Draw lines")
display.line(0, 0, display.width-1, display.height-1, Adafruit_IL0373.BLACK)
display.line(0, display.height-1, display.width-1, 0, Adafruit_IL0373.RED)
# load an image and display it
print("Load image")
with open("/path/to/image.bmp", "rb") as f:
bmp, palette = adafruit_imageload.load(f, bitmap=adafruit_imageload.Bitmap)
display.image(bmp)
print("Display")
display.display()
print("Sleep")
display.sleep()
You will need to change the file path for the image to the actual file path in your system. Let me know if you have any issues or questions!
**Prompt**
I got this error
Traceback (most recent call last):
File "<stdin>", line 312, in <module>
AttributeError: 'module' object has no attribute 'SCRAMCS_PIN'
I apologize for the mistake. It should be sramcs_pin instead of SCRAMCS_PIN. Please try modifying the following line of code:
scss
Copy code
display = Adafruit_IL0373(640, 384, spi, cs_pin=cs, dc_pin=dc, sramcs_pin=sramcs, rst_pin=rst, busy_pin=busy)
to
scss
Copy code
display = Adafruit_IL0373(640, 384, spi, cs_pin=cs, dc_pin=dc, sramcs_pin=sramcs_pin, rst_pin=rst, busy_pin=busy)
**Prompt**
sracms isn't defined
I apologize for the confusion, it appears that sramcs_pin is a parameter that is not used in the Adafruit_IL0373 constructor. Instead, the sramcs_pin is set by calling the set_black_buffer and set_color_buffer methods of the Adafruit_IL0373 object. Here's a modified version of the code that should work:
python
Copy code
import digitalio
import busio
import board
import adafruit_il0373
import adafruit_imageload
import displayio
spi = busio.SPI(board.GP2, MOSI=board.GP3, MISO=board.GP4)
cs = digitalio.DigitalInOut(board.GP5)
dc = digitalio.DigitalInOut(board.GP6)
rst = digitalio.DigitalInOut(board.GP7)
busy = digitalio.DigitalInOut(board.GP8)
display = adafruit_il0373.IL0373(104, 212, spi, cs, dc, rst, busy)
# Clear the buffer
display.fill(adafruit_il0373.WHITE)
# Load the image
with open('/path/to/image.bmp', 'rb') as f:
bmp, _, _ = adafruit_imageload.load(f, bitmap=displayio.Bitmap, palette=displayio.Palette)
# Create a TileGrid to display the image
grid = displayio.TileGrid(bmp, pixel_shader=displayio.ColorConverter())
# Create a Group to hold the TileGrid
group = displayio.Group()
# Add the TileGrid to the Group
group.append(grid)
# Add the Group to the Display
display.show(group)
# Set the black buffer
display.set_black_buffer(0, False)
# Set the color buffer
display.set_color_buffer(1, False)
# Refresh the display
display.refresh()
# Put the display to sleep
display.sleep()
Here are some iterations of my code:
```py
# *****************************************************************************
# * | File : epd7in5.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V4.0
# * | Date : 2019-06-20
# # | Info : python demo
# -----------------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#import logging
import epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
config.delay_ms(100)
self.ReadBusy()
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if __name__ == '__main__':
#from PIL import Image, ImageDraw, ImageFont
from adafruit_epd import EPD
import bitmap_font
#import adafruit_imageload
from adafruit_epd.epd import Adafruit_EPD
import displayio
pd = Adafruit_EPD()
print("e-Paper init")
epd.init()
print("e-Paper clear")
epd.clear()
print("e-Paper draw text")
image = displayio.Bitmap(epd.width, epd.height, 2)
palette = displayio.Palette(2)
palette[0] = 0xFFFFFF
palette[1] = 0x000000
image_group = displayio.Group()
image_group.append(displayio.TileGrid(image, pixel_shader=palette))
epd.display.show(image_group)
font = bitmap_font.load_font('/path/to/your/font.bdf')
draw = displayio.Bitmap(epd.width, epd.height, 2)
text_area = bitmap_label.Label(font, text='Hello e-Paper!', color=0x000000)
text_area.x = 10
text_area.y = 10
image_group.append(text_area)
print("e-Paper display")
epd.display.refresh()
print("e-Paper sleep")
epd.sleep()
import board
import digitalio
from adafruit_bus_device.spi_device import SPIDevice
#import utime
import time
# Pin definitions
RST_PIN = digitalio.DigitalInOut(board.GP14)
DC_PIN = digitalio.DigitalInOut(board.GP13)
CS_PIN = digitalio.DigitalInOut(board.GP12)
BUSY_PIN = digitalio.DigitalInOut(board.GP15)
# SPI definitions
#spi = board.SPI()
import busio
spi = busio.SPI(board.GP10, board.GP11)
spi_device = SPIDevice(spi, CS_PIN)
# SPI and GPIO pins configuration for Raspberry Pi Pico
#RST_PIN = 14
#DC_PIN = 13
#CS_PIN = 12
#BUSY_PIN = 15
#SPI_SCK_PIN = 10
#SPI_MOSI_PIN = 11
# Configure SPI
#spi = machine.SPI(0, baudrate=4000000, sck=machine.Pin(SPI_SCK_PIN), mosi=machine.Pin(SPI_MOSI_PIN))
# Configure GPIO pins
#rst = machine.Pin(RST_PIN, machine.Pin.OUT)
#dc = machine.Pin(DC_PIN, machine.Pin.OUT)
#cs = machine.Pin(CS_PIN, machine.Pin.OUT)
#busy = machine.Pin(BUSY_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN)
# Delay function
def delay_ms(milliseconds):
time.sleep(milliseconds / 1000)
# *****************************************************************************
# * | File : epd7in5.py
# * | Author : Waveshare team
# * | Function : Electronic paper driver
# * | Info :
# *----------------
# * | This version: V4.0
# * | Date : 2019-06-20
# # | Info : python demo
# -----------------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documnetation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
#import logging
import epdconfig
# Display resolution
EPD_WIDTH = 800
EPD_HEIGHT = 480
#logger = logging.getLogger(__name__)
class EPD:
def __init__(self):
self.reset_pin = epdconfig.RST_PIN
self.dc_pin = epdconfig.DC_PIN
self.busy_pin = epdconfig.BUSY_PIN
self.cs_pin = epdconfig.CS_PIN
self.width = EPD_WIDTH
self.height = EPD_HEIGHT
Voltage_Frame_7IN5_V2 = [
0x6, 0x3F, 0x3F, 0x11, 0x24, 0x7, 0x17,
]
LUT_VCOM_7IN5_V2 = [
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0xF, 0x1, 0xF, 0x1, 0x2,
0x0, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BW_7IN5_V2 = [
0x10, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x20, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_WB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
LUT_BB_7IN5_V2 = [
0x80, 0xF, 0xF, 0x0, 0x0, 0x1,
0x84, 0xF, 0x1, 0xF, 0x1, 0x2,
0x40, 0xF, 0xF, 0x0, 0x0, 0x1,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
]
# Hardware reset
def reset(self):
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
epdconfig.digital_write(self.reset_pin, 0)
epdconfig.delay_ms(2)
epdconfig.digital_write(self.reset_pin, 1)
epdconfig.delay_ms(20)
def send_command(self, command):
epdconfig.digital_write(self.dc_pin, 0)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([command])
epdconfig.digital_write(self.cs_pin, 1)
def send_data(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte([data])
epdconfig.digital_write(self.cs_pin, 1)
def send_data2(self, data):
epdconfig.digital_write(self.dc_pin, 1)
epdconfig.digital_write(self.cs_pin, 0)
epdconfig.spi_writebyte2(data)
epdconfig.digital_write(self.cs_pin, 1)
def ReadBusy(self):
logger.debug("e-Paper busy")
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
while(busy == 0):
self.send_command(0x71)
busy = epdconfig.digital_read(self.busy_pin)
epdconfig.delay_ms(20)
logger.debug("e-Paper busy release")
def SetLut(self, lut_vcom, lut_ww, lut_bw, lut_wb, lut_bb):
self.send_command(0x20)
for count in range(0, 42):
self.send_data(lut_vcom[count])
self.send_command(0x21)
for count in range(0, 42):
self.send_data(lut_ww[count])
self.send_command(0x22)
for count in range(0, 42):
self.send_data(lut_bw[count])
self.send_command(0x23)
for count in range(0, 42):
self.send_data(lut_wb[count])
self.send_command(0x24)
for count in range(0, 42):
self.send_data(lut_bb[count])
def init(self):
if (epdconfig.module_init() != 0):
return -1
# EPD hardware init start
self.reset()
# self.send_command(0x06) # btst
# self.send_data(0x17)
# self.send_data(0x17)
# self.send_data(0x28) # If an exception is displayed, try using 0x38
# self.send_data(0x17)
# self.send_command(0x01) #POWER SETTING
# self.send_data(0x07)
# self.send_data(0x07) #VGH=20V,VGL=-20V
# self.send_data(0x3f) #VDH=15V
# self.send_data(0x3f) #VDL=-15V
self.send_command(0x01) # power setting
self.send_data(0x17) # 1-0=11: internal power
self.send_data(self.Voltage_Frame_7IN5_V2[6]) # VGH&VGL
self.send_data(self.Voltage_Frame_7IN5_V2[1]) # VSH
self.send_data(self.Voltage_Frame_7IN5_V2[2]) # VSL
self.send_data(self.Voltage_Frame_7IN5_V2[3]) # VSHR
self.send_command(0x82) # VCOM DC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[4]) # VCOM
self.send_command(0x06) # Booster Setting
self.send_data(0x27)
self.send_data(0x27)
self.send_data(0x2F)
self.send_data(0x17)
self.send_command(0x30) # OSC Setting
self.send_data(self.Voltage_Frame_7IN5_V2[0]) # 3C=50Hz, 3A=100HZ
self.send_command(0x04) # POWER ON
epdconfig.delay_ms(100)
self.ReadBusy()
self.send_command(0X00) # PANNEL SETTING
self.send_data(0x3F) # KW-3f KWR-2F BWROTP-0f BWOTP-1f
self.send_command(0x61) # tres
self.send_data(0x03) # source 800
self.send_data(0x20)
self.send_data(0x01) # gate 480
self.send_data(0xE0)
self.send_command(0X15)
self.send_data(0x00)
self.send_command(0X50) # VCOM AND DATA INTERVAL SETTING
self.send_data(0x10)
self.send_data(0x07)
self.send_command(0X60) # TCON SETTING
self.send_data(0x22)
self.send_command(0x65) # Resolution setting
self.send_data(0x00)
self.send_data(0x00) # 800*480
self.send_data(0x00)
self.send_data(0x00)
self.SetLut(self.LUT_VCOM_7IN5_V2, self.LUT_WW_7IN5_V2, self.LUT_BW_7IN5_V2, self.LUT_WB_7IN5_V2, self.LUT_BB_7IN5_V2)
# EPD hardware init end
return 0
def getbuffer(self, image):
img = image
imwidth, imheight = img.size
if(imwidth == self.width and imheight == self.height):
img = img.convert('1')
elif(imwidth == self.height and imheight == self.width):
# image has correct dimensions, but needs to be rotated
img = img.rotate(90, expand=True).convert('1')
else:
logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height))
# return a blank buffer
return [0x00] * (int(self.width/8) * self.height)
buf = bytearray(img.tobytes('raw'))
# The bytes need to be inverted, because in the PIL world 0=black and 1=white, but
# in the e-paper world 0=white and 1=black.
for i in range(len(buf)):
buf[i] ^= 0xFF
return buf
def display(self, image):
self.send_command(0x13)
self.send_data2(image)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def Clear(self):
buf = [0x00] * (int(self.width/8) * self.height)
self.send_command(0x10)
self.send_data2(buf)
self.send_command(0x13)
self.send_data2(buf)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0XA5)
epdconfig.delay_ms(2000)
epdconfig.module_exit()
config.delay_ms(100)
self.ReadBusy()
def clear(self):
self.send_command(0x13)
for _ in range(0, int(self.width * self.height / 8)):
self.send_data(0xFF)
self.send_command(0x12)
epdconfig.delay_ms(100)
self.ReadBusy()
def sleep(self):
self.send_command(0x02) # POWER_OFF
self.ReadBusy()
self.send_command(0x07) # DEEP_SLEEP
self.send_data(0xA5)
def __del__(self):
epdconfig.module_exit()
if __name__ == '__main__':
#from PIL import Image, ImageDraw, ImageFont
import digitalio
import busio
import board
from adafruit_epd.il0373 import Adafruit_IL0373
# create the spi device and pins we will need
spi = epdconfig.spi
ecs = digitalio.DigitalInOut(board.D12)
dc = digitalio.DigitalInOut(board.D11)
srcs = digitalio.DigitalInOut(board.D10) # can be None to use internal memory
rst = digitalio.DigitalInOut(board.D9) # can be None to not use this pin
busy = digitalio.DigitalInOut(board.D5) # can be None to not use this pin
# give them all to our driver
print("Creating display")
display = Adafruit_IL0373(640, 384, spi, # 7.5" monochrome display
cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs,
rst_pin=rst, busy_pin=busy)
display.rotation = 1
# clear the buffer
print("Clear buffer")
display.fill(Adafruit_IL0373.WHITE)
print("Draw text")
display.text('Hello ePaper!', 25, 10, Adafruit_IL0373.BLACK)
display.display()
# put the device to sleep
print("Sleep")
display.sleep()