epaper

package module
v0.0.0-...-d870bc7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2023 License: GPL-3.0 Imports: 22 Imported by: 0

README

go-epaper-lib

A golang lib to use with Waveshare(tm) e-Paper HAT for Raspberry Pi.

The current version is developed/tested only for the 2.7 inches, black-and-white HAT.
Hopefully, new models will be available in the future, but, at the moment,
keep in mind that all info in this repo is related exclusively to the 2.7" model.

Intro for the uninitiated

This is a library to help you use Waveshare(tm)'s e-paper display in Go. If you are looking for libs in other languages (like Python or C, check the official Waveshare website!).

This lib is still on its initial pre-release version. That means, it is still under development, no guarantees of retrocompatibility between commits. Still, pushed commits should be functional.

IMPORTANT NOTICE FOR RASPBERRY PI USERS

If you want to use the e-paper with Raspberry Pi, you need to enable the SPI kernel modules.

  • Run the command sudo raspi-config (notice that you need root access).
  • Access menu 3 Interface Options, then P4 SPI and finally, select Yes.
  • Reboot the Raspberry PI
If you don't follow these commands, you may see an error when running the lib similar to:

spireg: no port found. Did you run Init()?

The basics

This is the minimum code to have something printed on the display. For more details, check the documentation and/or the demo codes at examples/.

package main

import (
	"fmt"
	"image"
	"os"
	"time"

	"github.com/mcules/go-epaper-lib"
)

func main() {
	// New EPaperDisplay handler for model 2.7 inches, black-and-white..
	epd, err := epaper.New(epaper.Model2in7bw)
	if err != nil {
		panic(err)
	}

	// Run mandatory initialization.
	epd.Init()

	// Clear screen to avoid undesired meshes.
	epd.ClearScreen()

	// Parse the string and process it with TTF font.
  m := epd.Write(text, fontSize, fontFile)

  // Add the resulting image into the buffer.
  epd.AddLayer(m, 0, 0, false)

  // Print the buffer onto the display..
  epd.Display()

  // Just a timeout before clearing the screen.
	time.Sleep(10000 * time.Millisecond)
	epd.ClearScreen()

  // Always put the screen to sleep when it will not be refreshed shortly.
	epd.Sleep()
}

Functionalities

All of these functionalities are demonstrated in the example programs at examples/.

  • Write text: Write a string in the display. Tabs and newline chars are not recognized, nor bold, italic, underline etc.
  • Write text, rotated: the text is written rotated 90 degrees clockwise.
  • Display image: the image is cropped if it is larger than the display size. Only black-and-white PNG files allowed.
  • Display image, rotated: the image is rotated 90 degrees clockwise and it will be cropped if larger than display.

Coordinate system

  +-----------------------------------------------+
  | O ::::::::::::::::::::::::: O                 |
  |   +-----------------------------------+  K4[] |
  | 2 | (176,0)                 (176,264) |       |
  | 7 |                                   |  K3[] |
  | H |                                   |       |
  | A |                                   |  K2[] |
  | T | (0,0)                    (0, 264) |       |
  |   +-----------------------------------+  K1[] |
  +-----------------------------------------------+

  The schematics of the display above show the coordinates on the screen and orientation.

Each byte sent fills 8 pixels on line (X), so always group the pixels in sets of 8 before sending them to be printed. Bit value 0 means "black", while 1 means "white".

So, we need to convert an image represented as a matrix where each element is a pixel, to an array where each element represented 8 pixels on X and the lines are concatenated.

Image matrix:
| 0 1 2 3 4 a b c d e f g h i j 9 |
| A B C D E k l m n o p q r s t F |

becomes :
[01234abc defghij9 ABCDEklm nopqrstF]

If the image is larger than the display, the image is cropped.

IMPORTANT! The image is cropped during rotate AND translation, so the order of the commands are relevant!

How the output is composed

Image

The PNG image is read into a image.Image object. This object can be manipulated (e.g., rotated) and then turned into a matrix where each element represents a pixel.

The matrix is then converted into an byte array where each element represents 8 pixels (i.e., each bit of the element is a pixel, where 0 is black and 1 is white). The lines of the matrix are concatenated after each other in the array.

So, for example, considering x(1,2) as the element on the image matrix X, at line 1 and column 2, the resulting array would be:

[ x(0,0), x(1,0), x(2,0), ..., x(174,0), x(175,0), x(0,1), x(1,1), x(2,1), ..., x(175,1), x(0,2), ..., x(174, 263), x(175, 263) ]

Text

The string is rendered with the TTF file defined and turned into an image. From this point on, text is handled the same way as an ordinary image.

There are a few details on how functions WriteRotate() and Rotate() work on texts:

  • WriteRotate() will consider the line length as the height of the display, instead of the width, making the line longer;
  • You can use Rotate() on a string after it has been converted into an image, but keep in mind that the length of the text was already determined as the width of the display, so most likely the text will not take the entire display;

Next features / Fixes

These are some idea I'd like to implement:

  • Prints image (cropping if necessary)

  • Prints text (custom font, custom font size)

  • Rotate image / text

  • Position text and image on display

  • Write text with attributes (bold, italic)

  • Compose screen (overlays)

  • Print negative (if black, print as white and vice-versa)

  • Program functionalities for buttons (key1 to key4 on e-Paper HAT)

  • Partial refresh (i.e., update just a region of the display, instead of the whole display)

  • Improve clearscreen time

  • Text seems to be fading the closer it gets to the end of the "line"...

Other Notes

The images and fonts used on the examples are for demonstration purposes only, and unfortunately, I don't have the details about them anymore. To the best of my knowledge these are all free-to-use resources available on the internet - if that is not true, please let me know and I'll remove them.

Also, even if these are indeed free-to-use but you are the author, drop a note and I'll be glad to add the credits here.

  • Font used in the demo code is called "Pastel Colors". Source and author unknown...
  • Image used in the demo code had no title or author defined...

Documentation

Index

Constants

View Source
const (
	// ResetPin is the default pin where RST pin is connected.
	ResetPin string = "17"

	// DataCommandPin is the default pin where DC pin is connected.
	DataCommandPin string = "25"

	// ChipSelectionPin is the default pin where CS pin is connected.
	ChipSelectionPin string = "8"

	// BusyPin is the default pin where BUSY pin is connected.
	BusyPin string = "24"

	// CmdBoosterSoftStart is used during initialization.
	CmdBoosterSoftStart byte = 0x06

	// CmdDataStartTransimission1 TODO ?
	CmdDataStartTransimission1 byte = 0x10

	// CMdDeepSleep puts the screen on a low-power consumption. This should be done when the screen is not expected to be updated for a long time.
	CMdDeepSleep byte = 0x07

	// CmdDisplayRefresh TODO ?
	CmdDisplayRefresh byte = 0x12

	// CmdLutForVcom sets the LUT for VCOM.
	CmdLutForVcom byte = 0x20

	// CmdLutBlue sets the LUT for White-to-White.
	CmdLutBlue byte = 0x21

	// CmdLutWhite sets the LUT for Black-to-White.
	CmdLutWhite byte = 0x22

	// CmdLutGray1 sets the LUT for White-to-Black.
	CmdLutGray1 byte = 0x23

	// CmdLutGray2 sets the LUT for Black-to-Black.
	CmdLutGray2 byte = 0x24

	// CmdLutRed0 ??
	CmdLutRed0 byte = 0x25

	// CmdLutRed1 ??
	CmdLutRed1 byte = 0x26

	// CmdLutRed2 ??
	CmdLutRed2 byte = 0x27

	// CmdLutRed3 ??
	CmdLutRed3 byte = 0x28

	// CmdPanelSetting is the code for PSR command.
	CmdPanelSetting byte = 0x00

	// CmdPartialDisplayRefresh is the code for PDRF command.
	CmdPartialDisplayRefresh byte = 0x16

	// CmdPllControl is the code for PLL command.
	CmdPllControl byte = 0x30

	// CmdPowerOff is the code for POF command.
	CmdPowerOff byte = 0x02

	// CmdPowerOn is the code for PON command.
	CmdPowerOn byte = 0x04

	// CmdPowerOptimization is the code for power optimization (not a documented command).
	CmdPowerOptimization = 0xf8

	// CmdPowerSetting is the code for PSR command.
	CmdPowerSetting byte = 0x01

	// CmdTconResolution is the code for TRES command.
	CmdTconResolution byte = 0x61

	// CmdTconSetting is the code for TCON command.
	CmdTconSetting byte = 0x60

	// CmdTemperatureCalibration is the code for TSE command.
	CmdTemperatureCalibration byte = 0x41

	// CmdVcmDcSetting is the code for VDCS command.
	CmdVcmDcSetting byte = 0x82

	// CmdVcomDataIntervalSet is the code for CDI command.
	CmdVcomDataIntervalSet byte = 0x50
)

Variables

View Source
var (
	// Model2in7bw represents the black-and-white EPD 2.7 inches display
	Model2in7bw = Model{Width: 176, Height: 264, StartTransmission: 0x13}

	// Model7in5 represents the EPD 7.5 inches display
	Model7in5 = Model{Width: 384, Height: 640}
)
View Source
var (
	// Model2in7LutVcomDc bla.
	Model2in7LutVcomDc []byte = []byte{
		0x00, 0x00,
		0x00, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x32, 0x32, 0x00, 0x00, 0x02,
		0x00, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	// Model2in7LutWw = R21H
	Model2in7LutWw []byte = []byte{
		0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x60, 0x32, 0x32, 0x00, 0x00, 0x02,
		0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	// Model2in7LutBw = R22H    r
	Model2in7LutBw []byte = []byte{
		0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x60, 0x32, 0x32, 0x00, 0x00, 0x02,
		0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	// Model2in7LutBb = R24H    b
	Model2in7LutBb []byte = []byte{
		0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x60, 0x32, 0x32, 0x00, 0x00, 0x02,
		0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	// Model2in7LutWb = R23H    w
	Model2in7LutWb []byte = []byte{
		0xA0, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x60, 0x32, 0x32, 0x00, 0x00, 0x02,
		0x50, 0x0F, 0x0F, 0x00, 0x00, 0x05,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}
)

Functions

This section is empty.

Types

type EPaper

type EPaper struct {
	DataCommandSelection gpio.PinOut // High: Data, Low: Command
	ChipSelection        gpio.PinOut // Low: active

	Busy gpio.PinIO // Low: active

	Display draw.Image // This is the image that will be printed to screen
	// contains filtered or unexported fields
}

EPaper represents the e-papaer device.

func New

func New(model Model) (*EPaper, error)

New creates a new instance of EPaper with default parameters.

func NewCustom

func NewCustom(dcPin, csPin, rstPin, busyPin string, model Model, simulation bool, debug io.Writer) (*EPaper, error)

NewCustom creates a new instance of EPaper with custom parameters. If you have the HAT module, you can use the New() function.

func (*EPaper) AddLayer

func (e *EPaper) AddLayer(img image.Image, startX, startY int, transparent bool)

AddLayer puts img on top of the previous layers prepared to be printed. Function Clearscreen() will also delete any prepared layer.

func (*EPaper) ClearScreen

func (e *EPaper) ClearScreen()

ClearScreen erases anything that is on screen.

func (*EPaper) Init

func (e *EPaper) Init()

Init initializes the display config. It should be only used when you put the device to sleep and need to re-init the device.

func (*EPaper) PrintDisplay

func (e *EPaper) PrintDisplay()

PrintDisplay updates the screen with the contents of EPaper.Display.

func (*EPaper) Reset

func (e *EPaper) Reset()

Reset clear the display (it can also awaken the device).

func (*EPaper) Rotate

func (e *EPaper) Rotate(img image.Image) image.Image

Rotate will rotate the image 90 degrees clockwise. Use it before calling convert, because convert will insert the image in the display representation matrix.

func (*EPaper) Sleep

func (e *EPaper) Sleep()

Sleep put the display in power-saving mode. You can use Reset() to awaken and Init() to re-initialize the display.

func (*EPaper) Write

func (e *EPaper) Write(text string, fontSize float64, fontFile string) image.Image

Write is used to prepare text to be printed on the display. It turns a string in an image, then calls the returned value as a parameter of Convert(), and later, call Display().

func (*EPaper) WriteRotate

func (e *EPaper) WriteRotate(text string, fontSize float64, fontFile string, rotate bool) image.Image

WriteRotate is used to prepare text to be printed on the display. It turns a string in an image, then calls the returned value as a parameter of Convert(), and later, call Display(). If rotate is TRUE, the text will be rotate 90 degree clockwise.

type Model

type Model struct {
	Width             int
	Height            int
	StartTransmission byte
}

Model contains the definitions of the device being used.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL