A lib to handle a E-Paper display from Pervasive Displays. There is a interface board from Embedded Artists. The lib can handle graphic and text drawing and is using external fonts.

Dependents:   epaper_mbed_130411_KL25Z epaper_mbed_test epaper_KL25Z_2 test_he10 ... more

/media/uploads/dreschpe/epaper.jpg

The E-Paper display from Pervasive Displays with a interface board is available from Embedded Artists : http://www.embeddedartists.com/products/displays/lcd_27_epaper.php The 2.7 inch display have 264*176 pixel, monochrome.

Technology

You can look at the webside from Pervasive to see how the display works. http://www.pervasivedisplays.com/technology/home

This type of display have ultra low power consumption - due to its bi-stable nature. It requires only very little power to update the display and needs no power to maintain an image. You can disconnect the display - the image is still there. The viewing angle is like real paper - near 180°.

There are also some disadvantages of this technology. To change the image, we have to rewrite the full display in 4 steps. Invert, clear, invert new, new image. This process is visible and take a while -2s at room temperature. If it gets colder the display reacts slower and the interface timing has to be slow down. To compensate this, there is a LM75 temp sensor on the interface board. We also need ram to double buffer the display. 264 * 176 / 8 = 5808 Byte. To double buffer we need 11616 byte of ram. This is no problem for most mbed devices, but it will not run on the LPC11U24 or LPC800-MAX.

Interface

The graphic data is transferred to the display via spi. The maximum speed is 12Mhz. There are also some control signal and the I2C for the temperature sensor. Together we need 12 signals.

Displaymbed LPC1768mbed KL25Zsignal type
1 GNDGNDGNDGND
2 3V3VOUTP3V33.3 V power
3 SCKp7PTD1SCK
4 MOSIp5PTD2MOSI
5 MISOp6PTD3MISO
6 SSELp8PTC17GPIO
7 Busyp13PTA16GPIO
8 Borderp10PTD6GPIO
9 SCLp27PTE1SCL
10 SDAp28PTE0SDA
11 PWMp26PTD4PWM
12 Resetp12PTA17GPIO
13 Power controlp9PTD7GPIO
14 Dischargep11PTE31GPIO

Software

Fonts

How to get nice looking fonts ?

To print characters to a graphic screen we need a font. To code a font by paper is ok for a small lcd, but for a 264*176 pixel display we need bigger fonts. A 12*12 pixel font is readable, but it a lot of work to construct it by hand.

Fonts can be made with the GLCD Font Creator also from http://www.mikroe.com .

With this program you can load a window font and convert it into a c-array. To use this Font with my lib you have to add 4 parameter at the beginning of the font array. - the number of byte / char - the vertial size in pixel - the horizontal size in pixel - the number of byte per vertical line (it is vertical size / 8 ) You also have to change the type of array to char[]. After that you can switch between different fonts with set_font(unsigned char* font); The horizontal size of each character is also stored in the font. It look better if you use bigger fonts or italic. The letter M is wider than a l.

Here are some Fonts from me : http://mbed.org/users/dreschpe/code/TFT_fonts/

The small made for the mbed lab board can also be used : http://mbed.org/users/dreschpe/code/LCD_fonts/

And from Peter Holzleitner : http://mbed.org/users/pholzleitner/code/SourceCodePro31-SB/

Text commands :

You can use the claim() function to redirect the output to stdout or stderr to the display. After claim(stdout) you can simply use the printf function without the classname to print to the display. All other printf from other libs are also redirected to the display if you use this.

  • printf(...); print text and variables to the buffer with format options.
  • locate(x,y); function is used to setup the cursor position. x,y are the pixel position.

Graphics

Graphic commands :

  • cls(); Fill the screen with background color
  • pixel(x,y,color); set a single pixel at x,y with 1 : black or 0 : white
  • line(x0,y0,x1,y1,color); draw a line from x0,y0 to x1,y1 with color
  • rect(x0,y0,x1,y1,color); draw a rectangle x0,y0 to x1,y1 with color
  • fillrect(x0,y0,x1,y1,color); draw a filled rectangle
  • circle( x0,y0,radius ,color); draw a circle around x0,y0 with radius
  • fillcircle(x0,y0,radius ,color); draw a filled circle around x0,y0 with radius
  • setmode(mode); Set the drawing mode for all functions. mode can be NORMAL -> 0 is white and 1 is black or XOR -> the new pixel is a xor between the old display and the new. This mode will invert if a black pixel is draw over a black pixel.
  • print_bm(Bitmap ,x0,x0); Print a monochrome bitmap array. This graphic is defined by a Bitmap struct :

The pixel date array :

static char arm_logo[]={
0x00,0x00...
};

and a Bitmap struct:

Bitmap bitmARM = {
  48, // XSize
  48, // YSize 
  6,  // Bytes in Line
  arm_logo // Pointer to picture data 
};

To convert a graphic into a byte array we can use the tool Picture Converter 1bpp from http://www.embedded-tools.de.vu/ With this tool we load a image, press the convert button and save it as C-Header file. We have to save with horizontal orientation, so we have to press "No". Inside this file we find the data array which we can copy into a header file.

All this commands are writing to the frame buffer only ! To change the active display we have to call

  • write_disp(); This will refresh the display.

Sample code

test code for the LPC1768: http://mbed.org/users/dreschpe/code/epaper_mbed_test/

test code for KL25Z: http://mbed.org/users/dreschpe/code/epaper_mbed_130411_KL25Z/

#include "mbed.h"
#include "EaEpaper.h"
#include "Arial28x28.h"
#include "Arial12x12.h"
#include "font_big.h"
#include "graphics.h"

EaEpaper epaper(
                PTD7,            // PWR_CTRL
                PTD6,            // BORDER
                PTE31,           // DISCHARGE
                PTA17,           // RESET_DISP
                PTA16,           // BUSY
                PTC17,           // SSEL
                PTD4,            // PWM
                PTD2,PTD3,PTD1,  // MOSI,MISO,SCLK
                PTE0,PTE1);      // SDA,SDL 
 
int main() {

    epaper.cls();                                      // clear screen
    epaper.set_font((unsigned char*) Arial28x28);  // select the font
    epaper.locate(5,20);                           // set cursor
    epaper.printf("Hello Mbed");                  // print  text
    epaper.rect(3,15,150,50,1);                  // print a frame 
     
    epaper.set_font((unsigned char*) Arial12x12);  // change font
    epaper.locate(5,60);                               // set cursor
    epaper.printf("small Font");                    // print text
    epaper.set_font((unsigned char*) Neu42x35);  // change font
    epaper.locate(5,70);                               //set cursor
    epaper.printf("big Font");                        // change font
    
    epaper.write_disp(); // update screen       // update display
    
    wait(5);                                           // wait 5 s
    epaper.fillcircle(180,30,22,1);              // paint filled circle
    epaper.circle(160,150,20,1);               // paint circle
    epaper.write_disp(); // update screen      // update display
    
}
  

EaEpaper.h

Committer:
dreschpe
Date:
2014-06-25
Revision:
3:1371614703cd
Parent:
2:1f3672176ca3

File content as of revision 3:1371614703cd:

/* mbed library for 264*176 pixel 2.7 INCH E-PAPER DISPLAY from Pervasive Displays
 * Copyright (c) 2013 Peter Drescher - DC2PD
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR 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.
 */


// 09.11.2013   initial Version

#ifndef EAEPAPER_H
#define EAEPAPER_H

/**
 * Includes
 */
#include "mbed.h"
#include "EPD.h"
#include "GraphicsDisplay.h"

// we have to double buffer the display  
#define EA_IMG_BUF_SZ (5808) // 264 x 176 / 8 = 5808

/** Draw mode
  * NORMAl
  * XOR set pixel by xor of the screen
  */
enum {NORMAL,XOR};

/** Bitmap
 */
struct Bitmap{
    int xSize;
    int ySize;
    int Byte_in_Line;
    char* data;
    };

/* color definitions   */
#define Black           0x0
#define White           0x1   

/** Display control class, based on GraphicsDisplay and TextDisplay
 *
 * Example with pinning for KL25Z:
 * @code
 * #include "mbed.h"
 * #include "EaEpaper.h"
 * #include "Arial28x28.h" 
 * #include "Arial12x12.h"
 * #include "font_big.h"
 * #include "graphics.h"

 * // the E-Paper board from embedded artists has a LM75 temp sensor to compensate the temperature effect. If it is cold the display reacts slower.
 * // The LM75 need a I2C -> 2 pins : sda and scl 
 * // The display data is written via SPI -> 3 pins : mosi,miso,sck
 * // There are also some control signals 
 * // The pwm pin has to be connected to a PWM enabled pin : pwm
 * // The other signals are connected to normal IO`s
 * //              
 * EaEpaper epaper(PTD7,            // PWR_CTRL
 *                 PTD6,            // BORDER
 *                 PTE31,           // DISCHARGE
 *                 PTA17,           // RESET_DISP
 *                 PTA16,           // BUSY
 *                 PTC17,           // SSEL
 *                 PTD4,            // PWM
 *                 PTD2,PTD3,PTD1,  // MOSI,MISO,SCLK
 *                 PTE0,PTE1);      // SDA,SCL 
 *
 * int main() {
 *
 *   epaper.cls();                                  // clear screen                        
 *   epaper.set_font((unsigned char*) Arial28x28);  // select the font
 *   epaper.locate(5,20);                           // set cursor
 *   epaper.printf("Hello Mbed");                   // print text
 *   epaper.rect(3,15,150,50,1);                    // draw frame
 *   epaper.write_disp();                           // update screen
 *
 * @endcode
 */
 

class EaEpaper : public GraphicsDisplay  {

public:

    /**
     * Constructor.
     */ 
    EaEpaper(PinName p_on, PinName border, PinName discharge, PinName reset, PinName busy, PinName cs,  // IO-Pins
             PinName pwm,                                                                               // PWM Pin        
             PinName mosi, PinName miso, PinName sck,                                                   // SPI
             PinName sda, PinName scl,                                                                  // I2C
             const char* name ="E_Paper");
    
    /** Get the width of the screen in pixel
      *
      * @param
      * @returns width of screen in pixel
      *
      */
    virtual int width();

    /** Get the height of the screen in pixel
     *
     * @returns height of screen in pixel
     *
     */
    virtual int height();
    
    
    /**
     * Clear the display
     */    
    void clear();
    
    /**
     * Write image buffer to display
     */    
    void write_disp(void);
    
    /**
     * set or reset a single pixel
     *
     * @param x horizontal position
     * @param y vertical position
     * @param color : 0 white, 1 black
     */ 
    virtual void pixel(int x, int y, int color);
    
    /** Fill the screen with white
     *
     */ 
    virtual void cls(void);
    
    /** draw a 1 pixel line
     *
     * @param x0,y0 start point
     * @param x1,y1 stop point
     * @param color  : 0 white, 1 black
     */  
    void line(int x0, int y0, int x1, int y1, int color);
    
    /** draw a rect
     *
     * @param x0,y0 top left corner
     * @param x1,y1 down right corner
     * @param color : 0 white, 1 black
     */    
    void rect(int x0, int y0, int x1, int y1, int color);
    
    /** draw a filled rect
     *
     * @param x0,y0 top left corner
     * @param x1,y1 down right corner
     * @param color : 0 white, 1 black
     */  
    void fillrect(int x0, int y0, int x1, int y1, int color);
    
    /** draw a circle
     *
     * @param x0,y0 center
     * @param r radius
     * @param color : 0 white, 1 black                                                          *
     */    
    void circle(int x0, int y0, int r, int color);
    
    /** draw a filled circle
     *
     * @param x0,y0 center
     * @param r radius
     * @param color : 0 white, 1 black                                                                 *
     */  
    void fillcircle(int x0, int y0, int r, int color);
    
    /** set drawing mode
     *  @param NORMAL : paint normal color, XOR : paint XOR of current pixels
     */
    void setmode(int mode);
    
    /** setup cursor position
     *
     * @param x x-position (top left)
     * @param y y-position 
     */   
    virtual void locate(int x, int y);
    
    /** calculate the max number of char in a line
     *
     * @returns max columns
     * depends on actual font size
     */ 
    virtual int columns();
    
    /** calculate the max number of columns
     *
     * @returns max column
     * depends on actual font size
     */   
    virtual int rows();
    
    /** put a char on the screen
     *
     * @param value char to print
     * @returns printed char
     */
    virtual int _putc(int value);
    
    /** paint a character on given position out of the active font to the screen buffer
     *
     * @param x x-position (top left)
     * @param y y-position 
     * @param c char code
     */
    virtual void character(int x, int y, int c);
    
    /** select the font to use
     *
     * @param f pointer to font array 
     *                                                                              
     *   font array can created with GLCD Font Creator from http://www.mikroe.com
     *   you have to add 4 parameter at the beginning of the font array to use: 
     *   - the number of byte / char
     *   - the vertial size in pixel
     *   - the horizontal size in pixel
     *   - the number of byte per vertical line
     *   you also have to change the array to char[]
     */  
    void set_font(unsigned char* f);
    
    /** print bitmap to buffer
      *
      * @param bm struct Bitmap in flash
      * @param x  x start
      * @param y  y start 
      *
      */
    void print_bm(Bitmap bm, int x, int y);
    
    
    unsigned char* font;
    unsigned int draw_mode;
    
 private:
    
    EPD_Class epd_;
    I2C i2c_;
    unsigned int char_x;
    unsigned int char_y;
    int32_t readTemperature();
    
};
 
 #endif /* EAEPAPER_H */