Closed JamesNewton closed 6 years ago
I'm trying to get the Floyd_Steinberg demo to work. Here is my code esp_ePaper.zip I get error: Floyd_Steinberg.ino:55:0: EPD_Support.h:88: error: 'blackFramePtr' was not declared in this scope void updateDisplay(uint8_t blackFrame = blackFramePtr, uint8_t redFrame = redFramePtr) EPD_Support.h:88: error: 'redFramePtr' was not declared in this scope void updateDisplay(uint8_t blackFrame = blackFramePtr, uint8_t redFrame = redFramePtr)
If I remove those default values, I get: In function 'void rotateTest()': Floyd_Steinberg:189: error: too few arguments to function 'void updateDisplay(uint8_t, uint8_t)' updateDisplay(); // Update display
I'm using the epd1in54b driver. The demo in that folder DOES work when modified as you suggested.
I admit that I have not updated the TFT_eSPI library to the latest version, but I don't see any definitions in the current version either. I always hate to do the update because I have to fix the ILI9341 setup back to overlap mode.
I guess I just want to check that you've run this code lately? Is it just that I need to update the TFT-eSPI library again?
I had a look and the support libraries for the different displays do not have a consistent set of functions and the example Floyd_Steinberg example was written for the 2.7in display. I will need to think on this further...
That works, with a couple of (minor) limitations:
I don't see the tiger image at all. Just a blank screen, then the "cross hairs" then the "Rotation" text. Which is really exciting for us!
It's only a single color (black) on the white background, and this is a color display.
Of the two, we care far more about the color.
Have you uploaded the tiger image to SPIFFS using the IDEs upload menu option? The image is already in the sketch data folder.
Add you code for the red frame graphics by selecting frame buffer 2 and then drawing/printing what you want, then use the display update function.
I will create an example later today.
Use INK or PAPER only for the graphics colours. INK will end up black in a black frame or red in a red frame.
Doh! Of course. Works perfectly now. If it helps, here is the demo program I made:
// Test sketch for 1.54 two colour display using library modified for ESP8266 overlap mode
// Display grey-scale images on a Monchrome ePaper display using
// Floyd-Steinberg dithering
// https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dithering
// Example created by Bodmer 31/3/18 for TFT_eSPI library:
// https://github.com/Bodmer/TFT_eSPI
// Select the ePaper setup in library's "User_Setup_Select.h" file
// This sketch supports Waveshare 2 colour ePaper displays
// https://www.waveshare.com/product/modules/oleds-lcds/e-paper.htm
// Test images are in the Data folder with sketch (press Ctrl+k)
// Upload using the Tools menu "ESP8266 Sketch Data Upload" option
// READ THIS READ THIS READ THIS READ THIS READ THIS READ THIS
// Install the ePaper library for your own display size and type
// from here:
// https://github.com/Bodmer/EPD_Libraries
// The following is for the Waveshare 2.7" colour ePaper display
// include <epd?in?.h> where ?.?? is screen size in inches
//#include <epd2in7.h> // Screen specific library
#include <epd1in54b.h> // Screen specific library
Epd ePaper; // Create an instance ePaper
#include <TFT_eSPI.h> // Graphics library and Sprite class
TFT_eSPI glc = TFT_eSPI(); // Invoke the graphics library class
TFT_eSprite frame = TFT_eSprite(&glc); // Invoke the Sprite class for the image frame buffer
#define INK COLORED // Black ink
#define PAPER UNCOLORED // 'paper' background colour
uint16_t epd_width = EPD_WIDTH; // Set the initial values, these are swapped
uint16_t epd_height = EPD_HEIGHT; // in different landscape/portrait rotations
// so call frame.width() or frame.height() to get new values
#define EPD_BUFFER 1 // Label for the black frame buffer 1
uint8_t* framePtr = NULL; // Pointer for the black frame buffer
uint8_t* redFramePtr = NULL; // Pointer for the red frame buffer
#include "EPD_Support.h" // Include sketch EPD support functions last!
int8_t limit = 5; // Limit the number of loops before halting
//------------------------------------------------------------------------------------
// Setup
//------------------------------------------------------------------------------------
void setup() {
// Invoke overlap mode
// CLK SD0 SD1 D3 NodeMCU pin names
// SCLK MISO MOSI SS SPI signal names
// CLK DIN CS ePaper signal names (MISO not connected)
// 6 7 8 0 ESP8266 GPIO numbers
SPI.pins( 6, 7, 8, 0);
Serial.begin(250000); // Used for messages
// Initialise the ePaper library
if (ePaper.Init() != 0) {
Serial.print("ePaper init failed");
while (1) yield(); // Wait here until re-boot
}
Serial.println("\r\n ePaper initialisation OK");
// Initialise the SPIFFS filing system
if (!SPIFFS.begin()) {
Serial.println("SPIFFS initialisation failed!");
while (1) yield(); // Stay here twiddling thumbs
}
Serial.println(" SPIFFS initialisation OK");
frame.setColorDepth(1); // Must set the bits per pixel to 1 for ePaper displays
// Set bit depth BEFORE creating Sprite, default is 16!
// Create a frame buffer in RAM of defined size and save the pointer to it
// RAM needed is about (EPD_WIDTH * EPD_HEIGHT)/8 , ~5000 bytes for 200 x 200 pixels
// Note: always create the Sprite before setting the Sprite rotation
framePtr = (uint8_t*) frame.createSprite(EPD_WIDTH, EPD_HEIGHT, 2); // Create sprite with 2 frame buffers
redFramePtr = (uint8_t*) frame.frameBuffer(2); // Pointer to frame buffer 2
// Clear the two frame buffers
frame.frameBuffer(1);
frame.fillSprite(PAPER);
frame.frameBuffer(2);
frame.fillSprite(PAPER);
Serial.println("\r\nInitialisation done.");
listFiles(); // List all the files in the SPIFFS
}
//------------------------------------------------------------------------------------
// Loop
//------------------------------------------------------------------------------------
void loop() {
// Select frame buffer 1 for the graphics
frame.frameBuffer(1);
frame.fillSprite(PAPER); // Fill frame with white
frame.frameBuffer(2);
frame.fillSprite(PAPER); // Fill frame with white
frame.setRotation(random(4)); // Set the rotation to 0, 1, 2 or 3 ( 1 & 3 = landscape)
frame.frameBuffer(1);
// Draw 8 bit grey-scale bitmap using Floyd-Steinberg dithering at x,y
// /File name x y
//drawFSBmp("/TestCard.bmp", 0, 0); // 176 x 264 pixels
drawFSBmp("/Tiger.bmp", (frame.width()-176)/2, (frame.height()-234)/2); // 176 x 234 pixels
updateDisplay(); // Send image to display and refresh
delay(10000);
frame.fillSprite(PAPER); // Fill frame with white
// Draw circle in frame buffer (x, y, r, color) in center of screen
frame.frameBuffer(1);
frame.drawCircle(frame.width()/2, frame.height()/2, frame.width()/6, INK);
frame.frameBuffer(2);
frame.drawCircle(frame.width()/2, frame.height()/2, frame.width()/8, INK);
// Draw diagonal lines
frame.frameBuffer(1);
frame.drawLine(0 , 0, frame.width()-1, frame.height()-1, INK);
frame.frameBuffer(2);
frame.drawLine(0 , frame.height()-1, frame.width()-1, 0, INK);
updateDisplay(); // Send image to display and refresh
delay(10000);
// Run a rotation test
rotateTest();
delay(10000);
// Put screen to sleep to save power (if wanted)
ePaper.Sleep();
if (--limit <= 0) while(1) yield(); // Wait here
delay(10000); // Wait here for 10s
// Wake up ePaper display so we can talk to it
Serial.println("Waking up!");
ePaper.Init();
} // end of loop()
//------------------------------------------------------------------------------------
// setRotation() actually rotates the drawing coordinates, not the whole display frame
// buffer so we can use this to draw text at right angles or upside down
//------------------------------------------------------------------------------------
void rotateTest(void)
{
//frame.fillSprite(PAPER); // Fill buffer with white to clear old graphics
// Draw some text in frame buffer
frame.setTextFont(4); // Select font 4
frame.setTextColor(INK); // Set colour to ink
frame.setTextDatum(TC_DATUM); // Middle centre text datum
frame.setRotation(0); // Set the display rotation to 0, 1, 2 or 3 ( 1 & 3 = landscape)
epd_width = frame.width(); // Get the values for the current rotation
epd_height = frame.height(); // epd_height is not used in this sketch
frame.frameBuffer(1);
frame.drawString("Rotation 0", epd_width / 2, 10);
frame.setRotation(1); // Set the display rotation to 1
epd_width = frame.width(); // Get the values for the current rotation
epd_height = frame.height(); // epd_height is not used in this sketch
frame.frameBuffer(2);
frame.drawString("Rotation 1", epd_width / 2, 10);
frame.setRotation(2); // Set the display rotation to 2
epd_width = frame.width(); // Get the values for the current rotation
epd_height = frame.height(); // epd_height is not used in this sketch
frame.frameBuffer(1);
frame.drawString("Rotation 2", epd_width / 2, 10);
frame.setRotation(3); // Set the display rotation to 3
epd_width = frame.width(); // Get the values for the current rotation
epd_height = frame.height(); // epd_height is not used in this sketch
frame.frameBuffer(2);
frame.drawString("Rotation 3", epd_width / 2, 10);
Serial.println("Updating display");
updateDisplay(); // Update display
}
I see you have cracked it!
Here is my updated example that draws a filled red circle during the test. Floyd_Steinberg_1in54b.zip
Yep, thanks to your help. Now I just have to figure out how to do partial updates so I'm not sucking up so much RAM and I can change the data on the screen a little faster.
Partial update is not possible with the 1in54b but is with the single colour version.
It is tricky and there are quite a few gotchas. This is code for a 2in9 display that includes a partial update area and will give you clues.
The ability to use the eInk displays is really nice, especially for low power monitoring operations. (see #105)
But we are again, out of pins. #74
Is there a way to get the eInk to work in overlap mode?
I've been trying but so far it's not working for me.