diff --git a/Inkplate.cpp b/Inkplate.cpp index bcfaff0..e717bff 100644 --- a/Inkplate.cpp +++ b/Inkplate.cpp @@ -12,1353 +12,1353 @@ SdFat sd(&spi2); //For precise 1uS timing, we cannot use delayMicroseconds(), instead we use ASM with nop command. Initial Z value will be difeerent on different CPU speeds! (for 240 MHz CPU Clock z = 25) void usleep1() { - int z = 25; - while (z--) - { - asm("NOP"); - }; + int z = 25; + while (z--) + { + asm("NOP"); + }; } void ckvClock() { - CKV_CLEAR; - usleep1(); - CKV_SET; - usleep1(); + CKV_CLEAR; + usleep1(); + CKV_SET; + usleep1(); } //--------------------------USER FUNCTIONS-------------------------------------------- Inkplate::Inkplate(uint8_t _mode) : Adafruit_GFX(E_INK_WIDTH, E_INK_HEIGHT) { - _displayMode = _mode; + _displayMode = _mode; } void Inkplate::begin(void) { - if (_beginDone == 1) - return; - Wire.begin(); - mcp.begin(0); - mcp.pinMode(VCOM, OUTPUT); - mcp.pinMode(PWRUP, OUTPUT); - mcp.pinMode(WAKEUP, OUTPUT); - mcp.pinMode(GPIO0_ENABLE, OUTPUT); - mcp.digitalWrite(GPIO0_ENABLE, HIGH); + if (_beginDone == 1) + return; + Wire.begin(); + mcp.begin(0); + mcp.pinMode(VCOM, OUTPUT); + mcp.pinMode(PWRUP, OUTPUT); + mcp.pinMode(WAKEUP, OUTPUT); + mcp.pinMode(GPIO0_ENABLE, OUTPUT); + mcp.digitalWrite(GPIO0_ENABLE, HIGH); - //CONTROL PINS - pinMode(0, OUTPUT); - pinMode(2, OUTPUT); - pinMode(32, OUTPUT); - pinMode(33, OUTPUT); - mcp.pinMode(OE, OUTPUT); - mcp.pinMode(GMOD, OUTPUT); - mcp.pinMode(SPV, OUTPUT); - //pinMode(SPV, OUTPUT); + //CONTROL PINS + pinMode(0, OUTPUT); + pinMode(2, OUTPUT); + pinMode(32, OUTPUT); + pinMode(33, OUTPUT); + mcp.pinMode(OE, OUTPUT); + mcp.pinMode(GMOD, OUTPUT); + mcp.pinMode(SPV, OUTPUT); + //pinMode(SPV, OUTPUT); - //DATA PINS - pinMode(4, OUTPUT); //D0 - pinMode(5, OUTPUT); - pinMode(18, OUTPUT); - pinMode(19, OUTPUT); - pinMode(23, OUTPUT); - pinMode(25, OUTPUT); - pinMode(26, OUTPUT); - pinMode(27, OUTPUT); //D7 + //DATA PINS + pinMode(4, OUTPUT); //D0 + pinMode(5, OUTPUT); + pinMode(18, OUTPUT); + pinMode(19, OUTPUT); + pinMode(23, OUTPUT); + pinMode(25, OUTPUT); + pinMode(26, OUTPUT); + pinMode(27, OUTPUT); //D7 - //TOUCHPAD PINS - mcp.pinMode(10, INPUT); - mcp.pinMode(11, INPUT); - mcp.pinMode(12, INPUT); + //TOUCHPAD PINS + mcp.pinMode(10, INPUT); + mcp.pinMode(11, INPUT); + mcp.pinMode(12, INPUT); - //Battery voltage Switch MOSFET - mcp.pinMode(9, OUTPUT); + //Battery voltage Switch MOSFET + mcp.pinMode(9, OUTPUT); - D_memory_new = (uint8_t *)ps_malloc(600 * 100); - _partial = (uint8_t *)ps_malloc(600 * 100); - _pBuffer = (uint8_t *)ps_malloc(120000); - D_memory4Bit = (uint8_t *)ps_malloc(240000); - if (D_memory_new == NULL || _partial == NULL || _pBuffer == NULL || D_memory4Bit == NULL) - { - do + D_memory_new = (uint8_t *)ps_malloc(600 * 100); + _partial = (uint8_t *)ps_malloc(600 * 100); + _pBuffer = (uint8_t *)ps_malloc(120000); + D_memory4Bit = (uint8_t *)ps_malloc(240000); + if (D_memory_new == NULL || _partial == NULL || _pBuffer == NULL || D_memory4Bit == NULL) { - delay(100); - } while (true); - } - memset(D_memory_new, 0, 60000); - memset(_partial, 0, 60000); - memset(_pBuffer, 0, 120000); - memset(D_memory4Bit, 255, 240000); + do + { + delay(100); + } while (true); + } + memset(D_memory_new, 0, 60000); + memset(_partial, 0, 60000); + memset(_pBuffer, 0, 120000); + memset(D_memory4Bit, 255, 240000); - //precalculateGamma(gammaLUT, INKPLATE_GAMMA); - precalculateGamma(gammaLUT, 1); - _beginDone = 1; + //precalculateGamma(gammaLUT, INKPLATE_GAMMA); + precalculateGamma(gammaLUT, 1); + _beginDone = 1; } //Draw function, used by Adafruit GFX. void Inkplate::drawPixel(int16_t x0, int16_t y0, uint16_t color) { - if (x0 > _width - 1 || y0 > _height - 1 || x0 < 0 || y0 < 0) - return; + if (x0 > _width - 1 || y0 > _height - 1 || x0 < 0 || y0 < 0) + return; - switch (_rotation) - { - case 1: - _swap_int16_t(x0, y0); - x0 = _height - x0 - 1; - break; - case 2: - x0 = _width - x0 - 1; - y0 = _height - y0 - 1; - break; - case 3: - _swap_int16_t(x0, y0); - y0 = _width - y0 - 1; - break; - } + switch (_rotation) + { + case 1: + _swap_int16_t(x0, y0); + x0 = _height - x0 - 1; + break; + case 2: + x0 = _width - x0 - 1; + y0 = _height - y0 - 1; + break; + case 3: + _swap_int16_t(x0, y0); + y0 = _width - y0 - 1; + break; + } - if (_displayMode == 0) - { - int x = x0 / 8; - int x_sub = x0 % 8; - uint8_t temp = *(_partial + 100 * y0 + x); //D_memory_new[99 * y0 + x]; - *(_partial + 100 * y0 + x) = ~pixelMaskLUT[x_sub] & temp | (color ? pixelMaskLUT[x_sub] : 0); - } - else - { - color &= 7; - int x = x0 / 2; - int x_sub = x0 % 2; - uint8_t temp; - temp = *(D_memory4Bit + 400 * y0 + x); - *(D_memory4Bit + 400 * y0 + x) = pixelMaskGLUT[x_sub] & temp | (x_sub ? color : color << 4); - } + if (_displayMode == 0) + { + int x = x0 / 8; + int x_sub = x0 % 8; + uint8_t temp = *(_partial + 100 * y0 + x); //D_memory_new[99 * y0 + x]; + *(_partial + 100 * y0 + x) = ~pixelMaskLUT[x_sub] & temp | (color ? pixelMaskLUT[x_sub] : 0); + } + else + { + color &= 7; + int x = x0 / 2; + int x_sub = x0 % 2; + uint8_t temp; + temp = *(D_memory4Bit + 400 * y0 + x); + *(D_memory4Bit + 400 * y0 + x) = pixelMaskGLUT[x_sub] & temp | (x_sub ? color : color << 4); + } } void Inkplate::clearDisplay() { - //Clear 1 bit per pixel display buffer - if (_displayMode == 0) - memset(_partial, 0, 60000); + //Clear 1 bit per pixel display buffer + if (_displayMode == 0) + memset(_partial, 0, 60000); - //Clear 3 bit per pixel display buffer - if (_displayMode == 1) - memset(D_memory4Bit, 255, 240000); + //Clear 3 bit per pixel display buffer + if (_displayMode == 1) + memset(D_memory4Bit, 255, 240000); } //Function that displays content from RAM to screen void Inkplate::display() { - if (_displayMode == 0) - display1b(); - if (_displayMode == 1) - display3b(); + if (_displayMode == 0) + display1b(); + if (_displayMode == 1) + display3b(); } void Inkplate::partialUpdate() { - if (_displayMode == 1) - return; - if (_blockPartial == 1) - display1b(); - uint16_t _pos = 59999; - uint32_t _send; - uint8_t data; - uint8_t diffw, diffb; - uint32_t n = 119999; - uint8_t dram; + if (_displayMode == 1) + return; + if (_blockPartial == 1) + display1b(); + uint16_t _pos = 59999; + uint32_t _send; + uint8_t data; + uint8_t diffw, diffb; + uint32_t n = 119999; + uint8_t dram; - for (int i = 0; i < 600; i++) - { - for (int j = 0; j < 100; j++) - { - diffw = ((*(D_memory_new + _pos)) ^ (*(_partial + _pos))) & (~(*(_partial + _pos))); - diffb = ((*(D_memory_new + _pos)) ^ (*(_partial + _pos))) & ((*(_partial + _pos))); - _pos--; - *(_pBuffer + n) = LUTW[diffw >> 4] & (LUTB[diffb >> 4]); - n--; - *(_pBuffer + n) = LUTW[diffw & 0x0F] & (LUTB[diffb & 0x0F]); - n--; - } - } - - einkOn(); - for (int k = 0; k < 5; k++) - { - vscan_start(); - n = 119999; for (int i = 0; i < 600; i++) { - data = *(_pBuffer + n); - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + for (int j = 0; j < 100; j++) + { + diffw = ((*(D_memory_new + _pos)) ^ (*(_partial + _pos))) & (~(*(_partial + _pos))); + diffb = ((*(D_memory_new + _pos)) ^ (*(_partial + _pos))) & ((*(_partial + _pos))); + _pos--; + *(_pBuffer + n) = LUTW[diffw >> 4] & (LUTB[diffb >> 4]); + n--; + *(_pBuffer + n) = LUTW[diffw & 0x0F] & (LUTB[diffb & 0x0F]); + n--; + } + } + + einkOn(); + for (int k = 0; k < 5; k++) + { + vscan_start(); + n = 119999; + for (int i = 0; i < 600; i++) + { + data = *(_pBuffer + n); + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + hscan_start(_send); + n--; + for (int j = 0; j < 199; j++) + { + data = *(_pBuffer + n); + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + n--; + } + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + vscan_end(); + } + delayMicroseconds(230); + } + /* + for (int k = 0; k < 1; k++) { + vscan_start(); + _pos = 59999; + for (int i = 0; i < 600; i++) { + data = discharge[(*(D_memory_new + _pos) >> 4)]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); hscan_start(_send); - n--; - for (int j = 0; j < 199; j++) - { - data = *(_pBuffer + n); + data = discharge[*(D_memory_new + _pos) & 0x0F]; _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); GPIO.out_w1ts = (_send) | CL; GPIO.out_w1tc = DATA | CL; - n--; - } + _pos--; + for (int j = 0; j < 99; j++) { + data = discharge[(*(D_memory_new + _pos) >> 4)]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + data = discharge[*(D_memory_new + _pos) & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + _pos--; + } GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; + GPIO.out_w1tc = DATA | CL; vscan_end(); - } - delayMicroseconds(230); - } - /* - for (int k = 0; k < 1; k++) { - vscan_start(); - _pos = 59999; - for (int i = 0; i < 600; i++) { - data = discharge[(*(D_memory_new + _pos) >> 4)]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - hscan_start(_send); - data = discharge[*(D_memory_new + _pos) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - _pos--; - for (int j = 0; j < 99; j++) { - data = discharge[(*(D_memory_new + _pos) >> 4)]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - data = discharge[*(D_memory_new + _pos) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - _pos--; } - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - vscan_end(); + delayMicroseconds(230); + } + */ + cleanFast(2, 2); + cleanFast(3, 1); + vscan_start(); + einkOff(); + einkOff(); + for (int i = 0; i < 60000; i++) + { + *(D_memory_new + i) &= *(_partial + i); + *(D_memory_new + i) |= (*(_partial + i)); } - delayMicroseconds(230); - } - */ - cleanFast(2, 2); - cleanFast(3, 1); - vscan_start(); - einkOff(); - einkOff(); - for (int i = 0; i < 60000; i++) - { - *(D_memory_new + i) &= *(_partial + i); - *(D_memory_new + i) |= (*(_partial + i)); - } } void Inkplate::drawBitmap3Bit(int16_t _x, int16_t _y, const unsigned char *_p, int16_t _w, int16_t _h) { - if (_displayMode != INKPLATE_3BIT) - return; - uint8_t _rem = _w % 2; - int i, j; - int xSize = _w / 2 + _rem; + if (_displayMode != INKPLATE_3BIT) + return; + uint8_t _rem = _w % 2; + int i, j; + int xSize = _w / 2 + _rem; - for (i = 0; i < _h; i++) - { - for (j = 0; j < xSize - 1; j++) + for (i = 0; i < _h; i++) { - drawPixel((j * 2) + _x, i + _y, (*(_p + xSize * (i) + j) >> 4) >> 1); - drawPixel((j * 2) + 1 + _x, i + _y, (*(_p + xSize * (i) + j) & 0xff) >> 1); + for (j = 0; j < xSize - 1; j++) + { + drawPixel((j * 2) + _x, i + _y, (*(_p + xSize * (i)+j) >> 4) >> 1); + drawPixel((j * 2) + 1 + _x, i + _y, (*(_p + xSize * (i)+j) & 0xff) >> 1); + } + drawPixel((j * 2) + _x, i + _y, (*(_p + xSize * (i)+j) >> 4) >> 1); + if (_rem == 0) + drawPixel((j * 2) + 1 + _x, i + _y, (*(_p + xSize * (i)+j) & 0xff) >> 1); } - drawPixel((j * 2) + _x, i + _y, (*(_p + xSize * (i) + j) >> 4) >> 1); - if (_rem == 0) - drawPixel((j * 2) + 1 + _x, i + _y, (*(_p + xSize * (i) + j) & 0xff) >> 1); - } } void Inkplate::setRotation(uint8_t r) { - _rotation = r % 4; - switch (_rotation) - { - case 0: - _width = E_INK_WIDTH; - _height = E_INK_HEIGHT; - break; - case 1: - _width = E_INK_HEIGHT; - _height = E_INK_WIDTH; - break; - case 2: - _width = E_INK_WIDTH; - _height = E_INK_HEIGHT; - break; - case 3: - _width = E_INK_HEIGHT; - _height = E_INK_WIDTH; - break; - } + _rotation = r % 4; + switch (_rotation) + { + case 0: + _width = E_INK_WIDTH; + _height = E_INK_HEIGHT; + break; + case 1: + _width = E_INK_HEIGHT; + _height = E_INK_WIDTH; + break; + case 2: + _width = E_INK_WIDTH; + _height = E_INK_HEIGHT; + break; + case 3: + _width = E_INK_HEIGHT; + _height = E_INK_WIDTH; + break; + } } //Turn off epapewr supply and put all digital IO pins in high Z state void Inkplate::einkOff() { - if (_panelOn == 0) - return; - _panelOn = 0; - GMOD_CLEAR; - OE_CLEAR; - GPIO.out &= ~(DATA | CL | LE); - SPH_CLEAR; - SPV_CLEAR; + if (_panelOn == 0) + return; + _panelOn = 0; + GMOD_CLEAR; + OE_CLEAR; + GPIO.out &= ~(DATA | CL | LE); + SPH_CLEAR; + SPV_CLEAR; - PWRUP_CLEAR; - WAKEUP_CLEAR; - VCOM_CLEAR; + PWRUP_CLEAR; + WAKEUP_CLEAR; + VCOM_CLEAR; - pinsZstate(); + pinsZstate(); } //Turn on supply for epaper display (TPS65186) [+15 VDC, -15VDC, +22VDC, -20VDC, +3.3VDC, VCOM] void Inkplate::einkOn() { - if (_panelOn == 1) - return; - _panelOn = 1; - pinsAsOutputs(); - WAKEUP_SET; - PWRUP_SET; - VCOM_SET; - //Enable all rails - Wire.beginTransmission(0x48); - Wire.write(0x01); - Wire.write(B00111111); - Wire.endTransmission(); + if (_panelOn == 1) + return; + _panelOn = 1; + pinsAsOutputs(); + WAKEUP_SET; + PWRUP_SET; + VCOM_SET; + //Enable all rails + Wire.beginTransmission(0x48); + Wire.write(0x01); + Wire.write(B00111111); + Wire.endTransmission(); - delay(40); + delay(40); - Wire.beginTransmission(0x48); - Wire.write(0x0D); - Wire.write(B10000000); - Wire.endTransmission(); + Wire.beginTransmission(0x48); + Wire.write(0x0D); + Wire.write(B10000000); + Wire.endTransmission(); - delay(2); + delay(2); - Wire.beginTransmission(0x48); - Wire.write(0x00); - Wire.endTransmission(); + Wire.beginTransmission(0x48); + Wire.write(0x00); + Wire.endTransmission(); - Wire.requestFrom(0x48, 1); - _temperature = Wire.read(); + Wire.requestFrom(0x48, 1); + _temperature = Wire.read(); - LE_CLEAR; //setpin_le(FALSE); - OE_CLEAR; //setpin_oe(FALSE); - CL_CLEAR; //setpin_cl(FALSE); - SPH_SET; //setpin_sph(FALSE); - GMOD_SET; //setpin_gmode(FALSE); - SPV_SET; //setpin_spv(FALSE); - CKV_CLEAR; //setpin_ckv(FALSE); - OE_SET; + LE_CLEAR; //setpin_le(FALSE); + OE_CLEAR; //setpin_oe(FALSE); + CL_CLEAR; //setpin_cl(FALSE); + SPH_SET; //setpin_sph(FALSE); + GMOD_SET; //setpin_gmode(FALSE); + SPV_SET; //setpin_spv(FALSE); + CKV_CLEAR; //setpin_ckv(FALSE); + OE_SET; } void Inkplate::selectDisplayMode(uint8_t _mode) { - if (_mode != _displayMode) - { - _displayMode = _mode & 1; - memset(D_memory_new, 0, 60000); - memset(_partial, 0, 60000); - memset(_pBuffer, 0, 120000); - memset(D_memory4Bit, 255, 240000); - _blockPartial = 1; - } + if (_mode != _displayMode) + { + _displayMode = _mode & 1; + memset(D_memory_new, 0, 60000); + memset(_partial, 0, 60000); + memset(_pBuffer, 0, 120000); + memset(D_memory4Bit, 255, 240000); + _blockPartial = 1; + } } uint8_t Inkplate::getDisplayMode() { - return _displayMode; + return _displayMode; } int Inkplate::drawBitmapFromSD(SdFile *p, int x, int y, bool invert) { - if (sdCardOk == 0) - return 0; - struct bitmapHeader bmpHeader; - readBmpHeaderSd(p, &bmpHeader); - if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) - return 0; + if (sdCardOk == 0) + return 0; + struct bitmapHeader bmpHeader; + readBmpHeaderSd(p, &bmpHeader); + if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) + return 0; - if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) - { - selectDisplayMode(INKPLATE_3BIT); - } + if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) + { + selectDisplayMode(INKPLATE_3BIT); + } - if (bmpHeader.color == 1 && getDisplayMode() != INKPLATE_1BIT) - { - selectDisplayMode(INKPLATE_1BIT); - } + if (bmpHeader.color == 1 && getDisplayMode() != INKPLATE_1BIT) + { + selectDisplayMode(INKPLATE_1BIT); + } - if (bmpHeader.color == 1) - drawMonochromeBitmapSd(p, bmpHeader, x, y, invert); - if (bmpHeader.color == 4) - drawGrayscaleBitmap4Sd(p, bmpHeader, x, y, invert); - if (bmpHeader.color == 8) - drawGrayscaleBitmap8Sd(p, bmpHeader, x, y, invert); - if (bmpHeader.color == 24) - drawGrayscaleBitmap24Sd(p, bmpHeader, x, y, invert); + if (bmpHeader.color == 1) + drawMonochromeBitmapSd(p, bmpHeader, x, y, invert); + if (bmpHeader.color == 4) + drawGrayscaleBitmap4Sd(p, bmpHeader, x, y, invert); + if (bmpHeader.color == 8) + drawGrayscaleBitmap8Sd(p, bmpHeader, x, y, invert); + if (bmpHeader.color == 24) + drawGrayscaleBitmap24Sd(p, bmpHeader, x, y, invert); - return 1; + return 1; } int Inkplate::drawBitmapFromSD(char *fileName, int x, int y, bool invert) { - if (sdCardOk == 0) - return 0; - SdFile dat; - if (dat.open(fileName, O_RDONLY)) - { - return drawBitmapFromSD(&dat, x, y, invert); - } - else - { - return 0; - } + if (sdCardOk == 0) + return 0; + SdFile dat; + if (dat.open(fileName, O_RDONLY)) + { + return drawBitmapFromSD(&dat, x, y, invert); + } + else + { + return 0; + } } int Inkplate::drawBitmapFromWeb(WiFiClient *s, int x, int y, int len, bool invert) { - struct bitmapHeader bmpHeader; - readBmpHeaderWeb(s, &bmpHeader); - if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) - return 0; + struct bitmapHeader bmpHeader; + readBmpHeaderWeb(s, &bmpHeader); + if (bmpHeader.signature != 0x4D42 || bmpHeader.compression != 0 || !(bmpHeader.color == 1 || bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24)) + return 0; - if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) - { - selectDisplayMode(INKPLATE_3BIT); - } + if ((bmpHeader.color == 4 || bmpHeader.color == 8 || bmpHeader.color == 24 || bmpHeader.color == 32) && getDisplayMode() != INKPLATE_3BIT) + { + selectDisplayMode(INKPLATE_3BIT); + } - if (bmpHeader.color == 1 && getDisplayMode() != INKPLATE_1BIT) - { - selectDisplayMode(INKPLATE_1BIT); - } + if (bmpHeader.color == 1 && getDisplayMode() != INKPLATE_1BIT) + { + selectDisplayMode(INKPLATE_1BIT); + } - if (bmpHeader.color == 1) - drawMonochromeBitmapWeb(s, bmpHeader, x, y, len, invert); - if (bmpHeader.color == 4) - drawGrayscaleBitmap4Web(s, bmpHeader, x, y, len, invert); - if (bmpHeader.color == 8) - drawGrayscaleBitmap8Web(s, bmpHeader, x, y, len, invert); - if (bmpHeader.color == 24) - drawGrayscaleBitmap24Web(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 1) + drawMonochromeBitmapWeb(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 4) + drawGrayscaleBitmap4Web(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 8) + drawGrayscaleBitmap8Web(s, bmpHeader, x, y, len, invert); + if (bmpHeader.color == 24) + drawGrayscaleBitmap24Web(s, bmpHeader, x, y, len, invert); - return 1; + return 1; } int Inkplate::drawBitmapFromWeb(char *url, int x, int y, bool invert) { - if (WiFi.status() != WL_CONNECTED) - return 0; - int ret = 0; + if (WiFi.status() != WL_CONNECTED) + return 0; + int ret = 0; - bool sleep = WiFi.getSleep(); - WiFi.setSleep(false); + bool sleep = WiFi.getSleep(); + WiFi.setSleep(false); - HTTPClient http; - http.getStream().setNoDelay(true); - http.getStream().setTimeout(1); - http.begin(url); + HTTPClient http; + http.getStream().setNoDelay(true); + http.getStream().setTimeout(1); + http.begin(url); - int httpCode = http.GET(); - if (httpCode == 200) - { - int32_t len = http.getSize(); - if (len > 0) + int httpCode = http.GET(); + if (httpCode == 200) { - WiFiClient *dat = http.getStreamPtr(); - ret = drawBitmapFromWeb(dat, x, y, len, invert); + int32_t len = http.getSize(); + if (len > 0) + { + WiFiClient *dat = http.getStreamPtr(); + ret = drawBitmapFromWeb(dat, x, y, len, invert); + } } - } - http.end(); - WiFi.setSleep(sleep); - return ret; + http.end(); + WiFi.setSleep(sleep); + return ret; } void Inkplate::drawThickLine(int x1, int y1, int x2, int y2, int color, float thickness) { - float deg = atan2f((float)(y2 - y1), (float)(x2 - x1)); + float deg = atan2f((float)(y2 - y1), (float)(x2 - x1)); - float l1 = tan(deg); - float k1 = (float)y1 - l1 * (float)x1; + float l1 = tan(deg); + float k1 = (float)y1 - l1 * (float)x1; - float degShift = (l1 < 0 ? M_PI_2 : -M_PI_2); + float degShift = (l1 < 0 ? M_PI_2 : -M_PI_2); - int x3 = (int)round((float)x1 + thickness / 2.0 * cos(deg + degShift)); - int y3 = (int)round((float)y1 + thickness / 2.0 * sin(deg + degShift)); + int x3 = (int)round((float)x1 + thickness / 2.0 * cos(deg + degShift)); + int y3 = (int)round((float)y1 + thickness / 2.0 * sin(deg + degShift)); - int x4 = (int)round((float)x2 + thickness / 2.0 * cos(deg + degShift)); - int y4 = (int)round((float)y2 + thickness / 2.0 * sin(deg + degShift)); + int x4 = (int)round((float)x2 + thickness / 2.0 * cos(deg + degShift)); + int y4 = (int)round((float)y2 + thickness / 2.0 * sin(deg + degShift)); - x1 = (int)round((float)x1 + thickness / 2.0 * cos(deg - degShift)); - y1 = (int)round((float)y1 + thickness / 2.0 * sin(deg - degShift)); + x1 = (int)round((float)x1 + thickness / 2.0 * cos(deg - degShift)); + y1 = (int)round((float)y1 + thickness / 2.0 * sin(deg - degShift)); - x2 = (int)round((float)x2 + thickness / 2.0 * cos(deg - degShift)); - y2 = (int)round((float)y2 + thickness / 2.0 * sin(deg - degShift)); + x2 = (int)round((float)x2 + thickness / 2.0 * cos(deg - degShift)); + y2 = (int)round((float)y2 + thickness / 2.0 * sin(deg - degShift)); - fillTriangle(x1, y1, x2, y2, x3, y3, color); - fillTriangle(x2, y2, x4, y4, x3, y3, color); + fillTriangle(x1, y1, x2, y2, x3, y3, color); + fillTriangle(x2, y2, x4, y4, x3, y3, color); } void Inkplate::drawGradientLine(int x1, int y1, int x2, int y2, int color1, int color2, float thickness) { - int n = color2 - color1; + int n = color2 - color1; - float px = (float)(x2 - x1) / (float)n; - float py = (float)(y2 - y1) / (float)n; + float px = (float)(x2 - x1) / (float)n; + float py = (float)(y2 - y1) / (float)n; - for (int i = 0; i < n; ++i) - { - if (abs(thickness + 1) < 0.1) - drawLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py), - (int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py), - color1 + i); - else - drawThickLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py), - (int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py), - color1 + i, - thickness); - } + for (int i = 0; i < n; ++i) + { + if (abs(thickness + 1) < 0.1) + drawLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py), + (int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py), + color1 + i); + else + drawThickLine((int)((float)x1 + (float)i * px), (int)((float)y1 + (float)i * py), + (int)((float)x1 + (float)(i + 1) * px), (int)((float)y1 + (float)(i + 1) * py), + color1 + i, + thickness); + } } int Inkplate::sdCardInit() { - spi2.begin(14, 12, 13, 15); - sdCardOk = sd.begin(15, SD_SCK_MHZ(25)); - return sdCardOk; + spi2.begin(14, 12, 13, 15); + sdCardOk = sd.begin(15, SD_SCK_MHZ(25)); + return sdCardOk; } SdFat Inkplate::getSdFat() { - return sd; + return sd; } SPIClass Inkplate::getSPI() { - return spi2; + return spi2; } uint8_t Inkplate::getPanelState() { - return _panelOn; + return _panelOn; } uint8_t Inkplate::readTouchpad(uint8_t _pad) { - return mcp.digitalRead((_pad & 3) + 10); + return mcp.digitalRead((_pad & 3) + 10); } int8_t Inkplate::readTemperature() { - return _temperature; + return _temperature; } double Inkplate::readBattery() { - mcp.digitalWrite(9, HIGH); - delay(1); - int adc = analogRead(35); - mcp.digitalWrite(9, LOW); - return (double(adc) / 4095 * 3.3 * 2); + mcp.digitalWrite(9, HIGH); + delay(1); + int adc = analogRead(35); + mcp.digitalWrite(9, LOW); + return (double(adc) / 4095 * 3.3 * 2); } //--------------------------LOW LEVEL STUFF-------------------------------------------- void Inkplate::vscan_start() { - CKV_SET; - delayMicroseconds(7); - SPV_CLEAR; - delayMicroseconds(10); - CKV_CLEAR; - delayMicroseconds(0); //usleep1(); - CKV_SET; - delayMicroseconds(8); - SPV_SET; - delayMicroseconds(10); - CKV_CLEAR; - delayMicroseconds(0); //usleep1(); - CKV_SET; - delayMicroseconds(18); - CKV_CLEAR; - delayMicroseconds(0); //usleep1(); - CKV_SET; - delayMicroseconds(18); - CKV_CLEAR; - delayMicroseconds(0); //usleep1(); - CKV_SET; - //delayMicroseconds(18); + CKV_SET; + delayMicroseconds(7); + SPV_CLEAR; + delayMicroseconds(10); + CKV_CLEAR; + delayMicroseconds(0); //usleep1(); + CKV_SET; + delayMicroseconds(8); + SPV_SET; + delayMicroseconds(10); + CKV_CLEAR; + delayMicroseconds(0); //usleep1(); + CKV_SET; + delayMicroseconds(18); + CKV_CLEAR; + delayMicroseconds(0); //usleep1(); + CKV_SET; + delayMicroseconds(18); + CKV_CLEAR; + delayMicroseconds(0); //usleep1(); + CKV_SET; + //delayMicroseconds(18); } void Inkplate::vscan_write() { - CKV_CLEAR; - LE_SET; - LE_CLEAR; - delayMicroseconds(0); - SPH_CLEAR; - CL_SET; - CL_CLEAR; - SPH_SET; - CKV_SET; + CKV_CLEAR; + LE_SET; + LE_CLEAR; + delayMicroseconds(0); + SPH_CLEAR; + CL_SET; + CL_CLEAR; + SPH_SET; + CKV_SET; } void Inkplate::hscan_start(uint32_t _d) { - SPH_CLEAR; - GPIO.out_w1ts = (_d) | CL; - GPIO.out_w1tc = DATA | CL; - //CL_SET; - //CL_CLEAR; - SPH_SET; + SPH_CLEAR; + GPIO.out_w1ts = (_d) | CL; + GPIO.out_w1tc = DATA | CL; + //CL_SET; + //CL_CLEAR; + SPH_SET; } void Inkplate::vscan_end() { - CKV_CLEAR; - LE_SET; - LE_CLEAR; - delayMicroseconds(1); - CKV_SET; + CKV_CLEAR; + LE_SET; + LE_CLEAR; + delayMicroseconds(1); + CKV_SET; } //Clear screan before new screen update using waveform void Inkplate::clean() { - einkOn(); - int m = 0; - cleanFast(0, 1); //white - m++; - cleanFast((waveform[m] >> 30) & 3, 8); //White to white - m++; - cleanFast((waveform[m] >> 24) & 3, 1); //white to black - m++; - cleanFast((waveform[m]) & 3, 8); //Black to black - m++; - cleanFast((waveform[m] >> 6) & 3, 1); //Black to white - m++; - cleanFast((waveform[m] >> 30) & 3, 10); //White to white + einkOn(); + int m = 0; + cleanFast(0, 1); //white + m++; + cleanFast((waveform[m] >> 30) & 3, 8); //White to white + m++; + cleanFast((waveform[m] >> 24) & 3, 1); //white to black + m++; + cleanFast((waveform[m]) & 3, 8); //Black to black + m++; + cleanFast((waveform[m] >> 6) & 3, 1); //Black to white + m++; + cleanFast((waveform[m] >> 30) & 3, 10); //White to white } //Clears content from epaper diplay as fast as ESP32 can. void Inkplate::cleanFast(uint8_t c, uint8_t rep) { - einkOn(); - uint8_t data; - if (c == 0) - { - data = B10101010; //White - } - else if (c == 1) - { - data = B01010101; //Black - } - else if (c == 2) - { - data = B00000000; //Discharge - } - else if (c == 3) - { - data = B11111111; //Skip - } - - uint32_t _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - for (int i = 0; i < rep; i++) - { - unsigned int x, y; - vscan_start(); - for (y = 0; y < 600; y++) + einkOn(); + uint8_t data; + if (c == 0) { - hscan_start(_send); - for (x = 0; x < 100; x++) - { - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - } - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - vscan_end(); + data = B10101010; //White + } + else if (c == 1) + { + data = B01010101; //Black + } + else if (c == 2) + { + data = B00000000; //Discharge + } + else if (c == 3) + { + data = B11111111; //Skip + } + + uint32_t _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + for (int i = 0; i < rep; i++) + { + unsigned int x, y; + vscan_start(); + for (y = 0; y < 600; y++) + { + hscan_start(_send); + for (x = 0; x < 100; x++) + { + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + } + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + vscan_end(); + } + delayMicroseconds(230); } - delayMicroseconds(230); - } } void Inkplate::cleanFast2(uint8_t c, uint8_t n, uint16_t d) { - /* - uint8_t data; - if (c == 0) { - data = B10101010; //White - } else if (c == 1) { - data = B01010101; //Black - } else if (c == 2) { - data = B00000000; //Discharge - } else if (c == 3) { - data = B11111111; //Skip - } - uint32_t _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - begin_frame(); - for (int k = 0; k < n; k++) { - - for (int i = 0; i < 600; i++) { - begin_line(); - if (k == 0) { - - for (int j = 0; j < 100; j++) { - GPIO.out_w1tc = DATA | CL; - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - GPIO.out_w1ts = (_send) | CL; - } - } - end_line(); + /* + uint8_t data; + if (c == 0) { + data = B10101010; //White + } else if (c == 1) { + data = B01010101; //Black + } else if (c == 2) { + data = B00000000; //Discharge + } else if (c == 3) { + data = B11111111; //Skip } - end_frame(); - delayMicroseconds(d); - } - */ + uint32_t _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + begin_frame(); + for (int k = 0; k < n; k++) { + + for (int i = 0; i < 600; i++) { + begin_line(); + if (k == 0) { + + for (int j = 0; j < 100; j++) { + GPIO.out_w1tc = DATA | CL; + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + GPIO.out_w1ts = (_send) | CL; + } + } + end_line(); + } + end_frame(); + delayMicroseconds(d); + } + */ } void Inkplate::pinsZstate() { - //CONTROL PINS - pinMode(0, INPUT); - pinMode(2, INPUT); - pinMode(32, INPUT); - pinMode(33, INPUT); - mcp.pinMode(OE, INPUT); - mcp.pinMode(GMOD, INPUT); - mcp.pinMode(SPV, INPUT); + //CONTROL PINS + pinMode(0, INPUT); + pinMode(2, INPUT); + pinMode(32, INPUT); + pinMode(33, INPUT); + mcp.pinMode(OE, INPUT); + mcp.pinMode(GMOD, INPUT); + mcp.pinMode(SPV, INPUT); - //DATA PINS - pinMode(4, INPUT); //D0 - pinMode(5, INPUT); - pinMode(18, INPUT); - pinMode(19, INPUT); - pinMode(23, INPUT); - pinMode(25, INPUT); - pinMode(26, INPUT); - pinMode(27, INPUT); //D7 + //DATA PINS + pinMode(4, INPUT); //D0 + pinMode(5, INPUT); + pinMode(18, INPUT); + pinMode(19, INPUT); + pinMode(23, INPUT); + pinMode(25, INPUT); + pinMode(26, INPUT); + pinMode(27, INPUT); //D7 } void Inkplate::pinsAsOutputs() { - //CONTROL PINS - pinMode(0, OUTPUT); - pinMode(2, OUTPUT); - pinMode(32, OUTPUT); - pinMode(33, OUTPUT); - mcp.pinMode(OE, OUTPUT); - mcp.pinMode(GMOD, OUTPUT); - mcp.pinMode(SPV, OUTPUT); + //CONTROL PINS + pinMode(0, OUTPUT); + pinMode(2, OUTPUT); + pinMode(32, OUTPUT); + pinMode(33, OUTPUT); + mcp.pinMode(OE, OUTPUT); + mcp.pinMode(GMOD, OUTPUT); + mcp.pinMode(SPV, OUTPUT); - //DATA PINS - pinMode(4, OUTPUT); //D0 - pinMode(5, OUTPUT); - pinMode(18, OUTPUT); - pinMode(19, OUTPUT); - pinMode(23, OUTPUT); - pinMode(25, OUTPUT); - pinMode(26, OUTPUT); - pinMode(27, OUTPUT); //D7 + //DATA PINS + pinMode(4, OUTPUT); //D0 + pinMode(5, OUTPUT); + pinMode(18, OUTPUT); + pinMode(19, OUTPUT); + pinMode(23, OUTPUT); + pinMode(25, OUTPUT); + pinMode(26, OUTPUT); + pinMode(27, OUTPUT); //D7 } //--------------------------PRIVATE FUNCTIONS-------------------------------------------- //Display content from RAM to display (1 bit per pixel,. monochrome picture). void Inkplate::display1b() { - for (int i = 0; i < 60000; i++) - { - *(D_memory_new + i) &= *(_partial + i); - *(D_memory_new + i) |= (*(_partial + i)); - } - uint16_t _pos; - uint32_t _send; - uint8_t data; - uint8_t dram; - einkOn(); - //clean(); - cleanFast(0, 1); - cleanFast(1, 12); - cleanFast(2, 1); - cleanFast(0, 11); - cleanFast(2, 1); - cleanFast(1, 12); - cleanFast(2, 1); - cleanFast(0, 11); - for (int k = 0; k < 5; k++) - { + for (int i = 0; i < 60000; i++) + { + *(D_memory_new + i) &= *(_partial + i); + *(D_memory_new + i) |= (*(_partial + i)); + } + uint16_t _pos; + uint32_t _send; + uint8_t data; + uint8_t dram; + einkOn(); + //clean(); + cleanFast(0, 1); + cleanFast(1, 12); + cleanFast(2, 1); + cleanFast(0, 11); + cleanFast(2, 1); + cleanFast(1, 12); + cleanFast(2, 1); + cleanFast(0, 11); + for (int k = 0; k < 5; k++) + { + _pos = 59999; + vscan_start(); + for (int i = 0; i < 600; i++) + { + dram = *(D_memory_new + _pos); + data = LUTB[(dram >> 4) & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + hscan_start(_send); + data = LUTB[dram & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + _pos--; + for (int j = 0; j < 99; j++) + { + dram = *(D_memory_new + _pos); + data = LUTB[(dram >> 4) & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + data = LUTB[dram & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + _pos--; + } + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + vscan_end(); + } + delayMicroseconds(230); + } + _pos = 59999; vscan_start(); for (int i = 0; i < 600; i++) { - dram = *(D_memory_new + _pos); - data = LUTB[(dram >> 4) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - hscan_start(_send); - data = LUTB[dram & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - _pos--; - for (int j = 0; j < 99; j++) - { dram = *(D_memory_new + _pos); - data = LUTB[(dram >> 4) & 0x0F]; + data = LUT2[(dram >> 4) & 0x0F]; _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - data = LUTB[dram & 0x0F]; + hscan_start(_send); + data = LUT2[dram & 0x0F]; _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); GPIO.out_w1ts = (_send) | CL; GPIO.out_w1tc = DATA | CL; _pos--; - } - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - vscan_end(); + for (int j = 0; j < 99; j++) + { + dram = *(D_memory_new + _pos); + data = LUT2[(dram >> 4) & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + data = LUT2[dram & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + _pos--; + } + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + vscan_end(); } delayMicroseconds(230); - } - - _pos = 59999; - vscan_start(); - for (int i = 0; i < 600; i++) - { - dram = *(D_memory_new + _pos); - data = LUT2[(dram >> 4) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - hscan_start(_send); - data = LUT2[dram & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - _pos--; - for (int j = 0; j < 99; j++) - { - dram = *(D_memory_new + _pos); - data = LUT2[(dram >> 4) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - data = LUT2[dram & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; + /* + for (int k = 0; k < 1; k++) { + vscan_start(); + hscan_start(); + _pos = 59999; + for (int i = 0; i < 600; i++) { + for (int j = 0; j < 100; j++) { + data = discharge[(*(D_memory_new + _pos) >> 4)]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1tc = DATA | CL; + GPIO.out_w1ts = (_send) | CL; + data = discharge[*(D_memory_new + _pos) & 0x0F]; + _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); + GPIO.out_w1tc = DATA | CL; + GPIO.out_w1ts = (_send) | CL; _pos--; - } - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - vscan_end(); - } - delayMicroseconds(230); - /* - for (int k = 0; k < 1; k++) { - vscan_start(); - hscan_start(); - _pos = 59999; - for (int i = 0; i < 600; i++) { - for (int j = 0; j < 100; j++) { - data = discharge[(*(D_memory_new + _pos) >> 4)]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1tc = DATA | CL; - GPIO.out_w1ts = (_send) | CL; - data = discharge[*(D_memory_new + _pos) & 0x0F]; - _send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) | (((data & B11100000) >> 5) << 25); - GPIO.out_w1tc = DATA | CL; - GPIO.out_w1ts = (_send) | CL; - _pos--; + } + vscan_write(); } - vscan_write(); + CKV_CLEAR; + delayMicroseconds(230); } - CKV_CLEAR; - delayMicroseconds(230); - } - */ - cleanFast(2, 2); - cleanFast(3, 1); - vscan_start(); - einkOff(); - _blockPartial = 0; + */ + cleanFast(2, 2); + cleanFast(3, 1); + vscan_start(); + einkOff(); + _blockPartial = 0; } //Display content from RAM to display (3 bit per pixel,. 8 level of grayscale, STILL IN PROGRESSS, we need correct wavefrom to get good picture, use it only for pictures not for GFX). void Inkplate::display3b() { - einkOn(); - cleanFast(0, 1); - cleanFast(1, 12); - cleanFast(2, 1); - cleanFast(0, 11); - cleanFast(2, 1); - cleanFast(1, 12); - cleanFast(2, 1); - cleanFast(0, 11); + einkOn(); + cleanFast(0, 1); + cleanFast(1, 12); + cleanFast(2, 1); + cleanFast(0, 11); + cleanFast(2, 1); + cleanFast(1, 12); + cleanFast(2, 1); + cleanFast(0, 11); - for (int k = 0; k < 7; k++) - { - uint8_t *dp = D_memory4Bit + 239999; - uint32_t _send; - uint8_t pix1; - uint8_t pix2; - uint8_t pix3; - uint8_t pix4; - uint8_t pixel; - uint8_t pixel2; - - vscan_start(); - for (int i = 0; i < 600; i++) + for (int k = 0; k < 7; k++) { - pixel = 0B00000000; - pixel2 = 0B00000000; - pix1 = *(dp--); - pix2 = *(dp--); - pix3 = *(dp--); - pix4 = *(dp--); - pixel |= (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); - pixel2 |= (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); + uint8_t *dp = D_memory4Bit + 239999; + uint32_t _send; + uint8_t pix1; + uint8_t pix2; + uint8_t pix3; + uint8_t pix4; + uint8_t pixel; + uint8_t pixel2; - _send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | (((pixel & B11100000) >> 5) << 25); - hscan_start(_send); - _send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | (((pixel2 & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; + vscan_start(); + for (int i = 0; i < 600; i++) + { + pixel = 0B00000000; + pixel2 = 0B00000000; + pix1 = *(dp--); + pix2 = *(dp--); + pix3 = *(dp--); + pix4 = *(dp--); + pixel |= (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); + pixel2 |= (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); - for (int j = 0; j < 99; j++) - { + _send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | (((pixel & B11100000) >> 5) << 25); + hscan_start(_send); + _send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | (((pixel2 & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; - pixel = 0B00000000; - pixel2 = 0B00000000; - pix1 = *(dp--); - pix2 = *(dp--); - pix3 = *(dp--); - pix4 = *(dp--); - pixel |= (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); - pixel2 |= (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); + for (int j = 0; j < 99; j++) + { - _send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | (((pixel & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; + pixel = 0B00000000; + pixel2 = 0B00000000; + pix1 = *(dp--); + pix2 = *(dp--); + pix3 = *(dp--); + pix4 = *(dp--); + pixel |= (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0); + pixel2 |= (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) | (waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0); - _send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | (((pixel2 & B11100000) >> 5) << 25); - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - } - GPIO.out_w1ts = (_send) | CL; - GPIO.out_w1tc = DATA | CL; - vscan_end(); + _send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) | (((pixel & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + + _send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) | (((pixel2 & B11100000) >> 5) << 25); + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + } + GPIO.out_w1ts = (_send) | CL; + GPIO.out_w1tc = DATA | CL; + vscan_end(); + } + delayMicroseconds(230); } - delayMicroseconds(230); - } - cleanFast(2, 1); - cleanFast(3, 1); - vscan_start(); - einkOff(); + cleanFast(2, 1); + cleanFast(3, 1); + vscan_start(); + einkOff(); } uint32_t Inkplate::read32(uint8_t *c) { - return (*(c) | (*(c + 1) << 8) | (*(c + 2) << 16) | (*(c + 3) << 24)); + return (*(c) | (*(c + 1) << 8) | (*(c + 2) << 16) | (*(c + 3) << 24)); } uint16_t Inkplate::read16(uint8_t *c) { - return (*(c) | (*(c + 1) << 8)); + return (*(c) | (*(c + 1) << 8)); } void Inkplate::readBmpHeaderSd(SdFile *_f, struct bitmapHeader *_h) { - uint8_t header[100]; - _f->rewind(); - _f->read(header, 100); - _h->signature = read16(header + 0); - _h->fileSize = read32(header + 2); - _h->startRAW = read32(header + 10); - _h->dibHeaderSize = read32(header + 14); - _h->width = read32(header + 18); - _h->height = read32(header + 22); - _h->color = read16(header + 28); - _h->compression = read32(header + 30); - return; + uint8_t header[100]; + _f->rewind(); + _f->read(header, 100); + _h->signature = read16(header + 0); + _h->fileSize = read32(header + 2); + _h->startRAW = read32(header + 10); + _h->dibHeaderSize = read32(header + 14); + _h->width = read32(header + 18); + _h->height = read32(header + 22); + _h->color = read16(header + 28); + _h->compression = read32(header + 30); + return; } void Inkplate::readBmpHeaderWeb(WiFiClient *_s, struct bitmapHeader *_h) { - uint8_t header[34]; - _s->read(header, 34); - _h->signature = read16(header + 0); - _h->fileSize = read32(header + 2); - _h->startRAW = read32(header + 10); - _h->dibHeaderSize = read32(header + 14); - _h->width = read32(header + 18); - _h->height = read32(header + 22); - _h->color = read16(header + 28); - _h->compression = read32(header + 30); - return; + uint8_t header[34]; + _s->read(header, 34); + _h->signature = read16(header + 0); + _h->fileSize = read32(header + 2); + _h->startRAW = read32(header + 10); + _h->dibHeaderSize = read32(header + 14); + _h->width = read32(header + 18); + _h->height = read32(header + 22); + _h->color = read16(header + 28); + _h->compression = read32(header + 30); + return; } int Inkplate::drawMonochromeBitmapSd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - uint8_t paddingBits = w % 32; - w /= 32; + int w = bmpHeader.width; + int h = bmpHeader.height; + uint8_t paddingBits = w % 32; + w /= 32; - f->seekSet(bmpHeader.startRAW); - int i, j; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + f->seekSet(bmpHeader.startRAW); + int i, j; + for (j = 0; j < h; j++) { - uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < 32; n++) - { - drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); - } + for (i = 0; i < w; i++) + { + uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < 32; n++) + { + drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); + } + } + if (paddingBits) + { + uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < paddingBits; n++) + { + drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); + } + } } - if (paddingBits) - { - uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < paddingBits; n++) - { - drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); - } - } - } - f->close(); - return 1; + f->close(); + return 1; } int Inkplate::drawGrayscaleBitmap4Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - uint8_t paddingBits = w % 8; - w /= 8; + int w = bmpHeader.width; + int h = bmpHeader.height; + uint8_t paddingBits = w % 8; + w /= 8; - f->seekSet(bmpHeader.startRAW); - int i, j; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + f->seekSet(bmpHeader.startRAW); + int i, j; + for (j = 0; j < h; j++) { - uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < 8; n++) - { - drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n * 4))) >> (28 - n * 4 + 1)); - } + for (i = 0; i < w; i++) + { + uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < 8; n++) + { + drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n * 4))) >> (28 - n * 4 + 1)); + } + } + if (paddingBits) + { + uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < paddingBits; n++) + { + drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n * 4)))) >> (28 - n * 4 + 1)); + } + } } - if (paddingBits) - { - uint32_t pixelRow = f->read() << 24 | f->read() << 16 | f->read() << 8 | f->read(); - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < paddingBits; n++) - { - drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n * 4)))) >> (28 - n * 4 + 1)); - } - } - } - f->close(); - return 1; + f->close(); + return 1; } int Inkplate::drawGrayscaleBitmap8Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - char padding = w % 4; - f->seekSet(bmpHeader.startRAW); - int i, j; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int w = bmpHeader.width; + int h = bmpHeader.height; + char padding = w % 4; + f->seekSet(bmpHeader.startRAW); + int i, j; + for (j = 0; j < h; j++) { - uint8_t px = 0; - if (invert) - px = 255 - f->read(); - else - px = f->read(); - drawPixel(i + x, h - 1 - j + y, px >> 5); + for (i = 0; i < w; i++) + { + uint8_t px = 0; + if (invert) + px = 255 - f->read(); + else + px = f->read(); + drawPixel(i + x, h - 1 - j + y, px >> 5); + } + if (padding) + { + for (int p = 0; p < 4 - padding; p++) + { + f->read(); + } + } } - if (padding) - { - for (int p = 0; p < 4 - padding; p++) - { - f->read(); - } - } - } - f->close(); - return 1; + f->close(); + return 1; } int Inkplate::drawGrayscaleBitmap24Sd(SdFile *f, struct bitmapHeader bmpHeader, int x, int y, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - char padding = w % 4; - f->seekSet(bmpHeader.startRAW); - int i, j; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int w = bmpHeader.width; + int h = bmpHeader.height; + char padding = w % 4; + f->seekSet(bmpHeader.startRAW); + int i, j; + for (j = 0; j < h; j++) { - //This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!) - //float px = (0.2126 * (readByteFromSD(&file) / 255.0)) + (0.7152 * (readByteFromSD(&file) / 255.0)) + (0.0722 * (readByteFromSD(&file) / 255.0)); - //px = pow(px, 1.5); - //display.drawPixel(i + x, h - j + y, (uint8_t)(px*7)); + for (i = 0; i < w; i++) + { + //This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!) + //float px = (0.2126 * (readByteFromSD(&file) / 255.0)) + (0.7152 * (readByteFromSD(&file) / 255.0)) + (0.0722 * (readByteFromSD(&file) / 255.0)); + //px = pow(px, 1.5); + //display.drawPixel(i + x, h - j + y, (uint8_t)(px*7)); - //So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method. - uint8_t px = 0; - if (invert) - px = ((255 - f->read()) * 2126 / 10000) + ((255 - f->read()) * 7152 / 10000) + ((255 - f->read()) * 722 / 10000); - else - px = (f->read() * 2126 / 10000) + (f->read() * 7152 / 10000) + (f->read() * 722 / 10000); - //drawPixel(i + x, h - j + y, gammaLUT[px]); - drawPixel(i + x, h - 1 - j + y, px >> 5); - //drawPixel(i + x, h - j + y, px/32); + //So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method. + uint8_t px = 0; + if (invert) + px = ((255 - f->read()) * 2126 / 10000) + ((255 - f->read()) * 7152 / 10000) + ((255 - f->read()) * 722 / 10000); + else + px = (f->read() * 2126 / 10000) + (f->read() * 7152 / 10000) + (f->read() * 722 / 10000); + //drawPixel(i + x, h - j + y, gammaLUT[px]); + drawPixel(i + x, h - 1 - j + y, px >> 5); + //drawPixel(i + x, h - j + y, px/32); + } + if (padding) + { + for (int p = 0; p < padding; p++) + { + f->read(); + } + } } - if (padding) - { - for (int p = 0; p < padding; p++) - { - f->read(); - } - } - } - f->close(); - return 1; + f->close(); + return 1; } int Inkplate::drawMonochromeBitmapWeb(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - uint8_t paddingBits = w % 32; - int total = len - 34; - w /= 32; + int w = bmpHeader.width; + int h = bmpHeader.height; + uint8_t paddingBits = w % 32; + int total = len - 34; + w /= 32; - uint8_t *buf = (uint8_t *)ps_malloc(total); - if (buf == NULL) - return 0; + uint8_t *buf = (uint8_t *)ps_malloc(total); + if (buf == NULL) + return 0; - int pnt = 0; - while (pnt < total) - { - int toread = s->available(); - if (toread > 0) + int pnt = 0; + while (pnt < total) { - int read = s->read(buf + pnt, toread); - if (read > 0) - pnt += read; + int toread = s->available(); + if (toread > 0) + { + int read = s->read(buf + pnt, toread); + if (read > 0) + pnt += read; + } } - } - int i, j, k = bmpHeader.startRAW - 34; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { - uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < 32; n++) - { - drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); - } + for (i = 0; i < w; i++) + { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < 32; n++) + { + drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); + } + } + if (paddingBits) + { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < paddingBits; n++) + { + drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); + } + } } - if (paddingBits) - { - uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < paddingBits; n++) - { - drawPixel((i * 32) + n + x, h - 1 - j + y, !(pixelRow & (1ULL << (31 - n)))); - } - } - } - free(buf); + free(buf); - return 1; + return 1; } int Inkplate::drawGrayscaleBitmap4Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - char paddingBits = w % 8; - int total = len - 34; - w /= 8; + int w = bmpHeader.width; + int h = bmpHeader.height; + char paddingBits = w % 8; + int total = len - 34; + w /= 8; - uint8_t *buf = (uint8_t *)ps_malloc(total); - if (buf == NULL) - return 0; + uint8_t *buf = (uint8_t *)ps_malloc(total); + if (buf == NULL) + return 0; - int pnt = 0; - while (pnt < total) - { - int toread = s->available(); - if (toread > 0) + int pnt = 0; + while (pnt < total) { - int read = s->read(buf + pnt, toread); - if (read > 0) - pnt += read; + int toread = s->available(); + if (toread > 0) + { + int read = s->read(buf + pnt, toread); + if (read > 0) + pnt += read; + } } - } - int i, j, k = bmpHeader.startRAW - 34; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { - uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < 8; n++) - { - drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n * 4))) >> (28 - n * 4 + 1)); - } + for (i = 0; i < w; i++) + { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < 8; n++) + { + drawPixel((i * 8) + n + x, h - 1 - j + y, (pixelRow & (0xFULL << (28 - n * 4))) >> (28 - n * 4 + 1)); + } + } + if (paddingBits) + { + uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; + if (invert) + pixelRow = ~pixelRow; + for (int n = 0; n < paddingBits; n++) + { + drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n * 4)))) >> (28 - n * 4 + 1)); + } + } } - if (paddingBits) - { - uint32_t pixelRow = buf[k++] << 24 | buf[k++] << 16 | buf[k++] << 8 | buf[k++]; - if (invert) - pixelRow = ~pixelRow; - for (int n = 0; n < paddingBits; n++) - { - drawPixel((i * 8) + n + x, h - 1 - j + y, ((pixelRow & (0xFULL << (28 - n * 4)))) >> (28 - n * 4 + 1)); - } - } - } - free(buf); + free(buf); - return 1; + return 1; } int Inkplate::drawGrayscaleBitmap8Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - char padding = w % 4; - int total = len - 34; + int w = bmpHeader.width; + int h = bmpHeader.height; + char padding = w % 4; + int total = len - 34; - uint8_t *buf = (uint8_t *)ps_malloc(total); - if (buf == NULL) - return 0; + uint8_t *buf = (uint8_t *)ps_malloc(total); + if (buf == NULL) + return 0; - int pnt = 0; - while (pnt < total) - { - int toread = s->available(); - if (toread > 0) + int pnt = 0; + while (pnt < total) { - int read = s->read(buf + pnt, toread); - if (read > 0) - pnt += read; + int toread = s->available(); + if (toread > 0) + { + int read = s->read(buf + pnt, toread); + if (read > 0) + pnt += read; + } } - } - int i, j, k = bmpHeader.startRAW - 34; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { - uint8_t px = 0; - if (invert) - px = 255 - buf[k++]; - else - px = buf[k++]; - drawPixel(i + x, h - 1 - j + y, px >> 5); + for (i = 0; i < w; i++) + { + uint8_t px = 0; + if (invert) + px = 255 - buf[k++]; + else + px = buf[k++]; + drawPixel(i + x, h - 1 - j + y, px >> 5); + } + if (padding) + { + for (int p = 0; p < 4 - padding; p++) + { + k++; + } + } } - if (padding) - { - for (int p = 0; p < 4 - padding; p++) - { - k++; - } - } - } - free(buf); + free(buf); - return 1; + return 1; } int Inkplate::drawGrayscaleBitmap24Web(WiFiClient *s, struct bitmapHeader bmpHeader, int x, int y, int len, bool invert) { - int w = bmpHeader.width; - int h = bmpHeader.height; - char padding = w % 4; - int total = len - 34; + int w = bmpHeader.width; + int h = bmpHeader.height; + char padding = w % 4; + int total = len - 34; - uint8_t *buf = (uint8_t *)ps_malloc(total); - if (buf == NULL) - return 0; + uint8_t *buf = (uint8_t *)ps_malloc(total); + if (buf == NULL) + return 0; - int pnt = 0; - while (pnt < total) - { - int toread = s->available(); - if (toread > 0) + int pnt = 0; + while (pnt < total) { - int read = s->read(buf + pnt, toread); - if (read > 0) - pnt += read; + int toread = s->available(); + if (toread > 0) + { + int read = s->read(buf + pnt, toread); + if (read > 0) + pnt += read; + } } - } - int i, j, k = bmpHeader.startRAW - 34; - for (j = 0; j < h; j++) - { - for (i = 0; i < w; i++) + int i, j, k = bmpHeader.startRAW - 34; + for (j = 0; j < h; j++) { - //This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!) - //float px = (0.2126 * (readByteFromSD(&file) / 255.0)) + (0.7152 * (readByteFromSD(&file) / 255.0)) + (0.0722 * (readByteFromSD(&file) / 255.0)); - //px = pow(px, 1.5); - //display.drawPixel(i + x, h - j + y, (uint8_t)(px*7)); + for (i = 0; i < w; i++) + { + //This is the proper way of converting True Color (24 Bit RGB) bitmap file into grayscale, but it takes waaay too much time (full size picture takes about 17s to decode!) + //float px = (0.2126 * (readByteFromSD(&file) / 255.0)) + (0.7152 * (readByteFromSD(&file) / 255.0)) + (0.0722 * (readByteFromSD(&file) / 255.0)); + //px = pow(px, 1.5); + //display.drawPixel(i + x, h - j + y, (uint8_t)(px*7)); - //So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method. - uint8_t px = 0; - if (invert) - px = ((255 - buf[k++]) * 2126 / 10000) + ((255 - buf[k++]) * 7152 / 10000) + ((255 - buf[k++]) * 722 / 10000); - else - px = (buf[k++] * 2126 / 10000) + (buf[k++] * 7152 / 10000) + (buf[k++] * 722 / 10000); - //drawPixel(i + x, h - j + y, gammaLUT[px]); - drawPixel(i + x, h - 1 - j + y, px >> 5); - //drawPixel(i + x, h - j + y, px/32); + //So then, we are convertng it to grayscale using good old average and gamma correction (from LUT). With this metod, it is still slow (full size image takes 4 seconds), but much beter than prev mentioned method. + uint8_t px = 0; + if (invert) + px = ((255 - buf[k++]) * 2126 / 10000) + ((255 - buf[k++]) * 7152 / 10000) + ((255 - buf[k++]) * 722 / 10000); + else + px = (buf[k++] * 2126 / 10000) + (buf[k++] * 7152 / 10000) + (buf[k++] * 722 / 10000); + //drawPixel(i + x, h - j + y, gammaLUT[px]); + drawPixel(i + x, h - 1 - j + y, px >> 5); + //drawPixel(i + x, h - j + y, px/32); + } + if (padding) + { + for (int p = 0; p < padding; p++) + { + k++; + } + } } - if (padding) - { - for (int p = 0; p < padding; p++) - { - k++; - } - } - } - free(buf); + free(buf); - return 1; + return 1; } void Inkplate::precalculateGamma(uint8_t *c, float gamma) { - for (int i = 0; i < 256; i++) - { - c[i] = int(round((pow(i / 255.0, gamma)) * 15)); - } + for (int i = 0; i < 256; i++) + { + c[i] = int(round((pow(i / 255.0, gamma)) * 15)); + } } diff --git a/Inkplate.h b/Inkplate.h index 25b5ebb..8077224 100644 --- a/Inkplate.h +++ b/Inkplate.h @@ -160,19 +160,19 @@ public: uint8_t *_partial; uint8_t *D_memory4Bit; uint8_t *_pBuffer; - const uint8_t LUT2[16] = {B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101, B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101}; - const uint8_t LUTW[16] = {B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010, B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010}; - const uint8_t LUTB[16] = {B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101, B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101}; - const uint8_t pixelMaskLUT[8] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}; - const uint8_t pixelMaskGLUT[2] = {B00001111, B11110000}; - const uint8_t discharge[16] = {B11111111, B11111100, B11110011, B11110000, B11001111, B11001100, B11000011, B11000000, B00111111, B00111100, B00110011, B00110000, B00001111, B00001100, B00000011, B00000000}; + const uint8_t LUT2[16] ={ B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101, B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101 }; + const uint8_t LUTW[16] ={ B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010, B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010 }; + const uint8_t LUTB[16] ={ B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101, B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101 }; + const uint8_t pixelMaskLUT[8] ={ B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000 }; + const uint8_t pixelMaskGLUT[2] ={ B00001111, B11110000 }; + const uint8_t discharge[16] ={ B11111111, B11111100, B11110011, B11110000, B11001111, B11001100, B11000011, B11000000, B00111111, B00111100, B00110011, B00110000, B00001111, B00001100, B00000011, B00000000 }; //BLACK->WHITE //THIS IS OKAYISH WAVEFORM FOR GRAYSCALE. IT CAN BE MUCH BETTER. - const uint8_t waveform3Bit[8][7] = {{0, 0, 0, 0, 1, 1, 1}, {0, 0, 1, 1, 1, 2, 1}, {0, 1, 1, 2, 1, 2, 1}, {0, 0, 1, 1, 2, 1, 2}, {1, 1, 1, 2, 2, 1, 2}, {0, 0, 1, 1, 1, 2, 2}, {0, 1, 1, 2, 1, 2, 2}, {0, 0, 0, 0, 0, 0, 2}}; + const uint8_t waveform3Bit[8][7] ={ { 0, 0, 0, 0, 1, 1, 1 }, { 0, 0, 1, 1, 1, 2, 1 }, { 0, 1, 1, 2, 1, 2, 1 }, { 0, 0, 1, 1, 2, 1, 2 }, { 1, 1, 1, 2, 2, 1, 2 }, { 0, 0, 1, 1, 1, 2, 2 }, { 0, 1, 1, 2, 1, 2, 2 }, { 0, 0, 0, 0, 0, 0, 2 } }; //const uint8_t waveform3Bit[8][12] = {{3,3,3,1,1,1,1,1,1,1,2,0}, {3,3,3,3,1,1,1,1,1,1,2,0}, {3,3,3,3,3,1,1,1,1,1,2,0}, {3,3,3,3,3,3,1,1,1,1,2,0}, {3,3,3,3,3,3,3,1,1,1,2,0}, {3,3,3,3,3,3,3,2,1,1,2,0}, {3,3,3,3,3,3,3,3,3,1,2,0}, {3,3,3,3,3,3,3,3,3,3,2,0}}; //const uint8_t waveform3Bit[16][12] = {{0,0,0,0,0,0,1,2,1,1,0,3},{0,0,1,1,1,2,2,2,1,1,0,3},{0,0,0,1,1,2,2,2,1,1,0,3}, {0,0,0,1,2,1,2,1,2,1,3}, {0,0,2,1,2,1,2,1,2,1,3}, {0,0,1,2,2,1,1,1,1,2,0,3}, {0,0,0,2,1,1,1,1,0,2,0,3}, {0,0,2,1,2,2,1,1,1,2,0,3}, {0,0,0,2,2,2,1,1,1,2,0,3}, {0,0,0,0,0,0,2,1,1,2,0,3}, {0,0,0,0,0,2,2,1,1,2,0,3}, {0,0,0,0,0,1,1,1,2,2,0,3}, {0,0,0,0,1,2,1,2,1,2,0,3}, {0,0,0,0,1,1,2,2,1,2,0,3},{0,0,0,0,1,1,1,2,2,2,0,3}, {0,0,0,0,0,0,0,0,0,2,0,3}}; //PVI waveform for cleaning screen, not sure if it is correct, but it cleans screen properly. - const uint32_t waveform[50] = {0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868, 0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68, 0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595, 0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484, 0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111}; + const uint32_t waveform[50] ={ 0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868, 0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68, 0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595, 0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484, 0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111 }; struct bitmapHeader { diff --git a/examples/1. Basic Inkplate Functionality/2-Inkplate_basic_grayscale/2-Inkplate_basic_grayscale.ino b/examples/1. Basic Inkplate Functionality/2-Inkplate_basic_grayscale/2-Inkplate_basic_grayscale.ino index 951b995..4cda363 100644 --- a/examples/1. Basic Inkplate Functionality/2-Inkplate_basic_grayscale/2-Inkplate_basic_grayscale.ino +++ b/examples/1. Basic Inkplate Functionality/2-Inkplate_basic_grayscale/2-Inkplate_basic_grayscale.ino @@ -2,14 +2,14 @@ 2_Basic_grayscale example for e-radionica.com Inkplate 6 For this example you will need only USB cable and Inkplate 6 Select "Inkplate 6(ESP32)" from Tools -> Board menu. - Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it: + Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it: https://e-radionica.com/en/blog/add-inkplate-6-to-arduino-ide/ - - This example will show you how you can draw some simple graphics using + + This example will show you how you can draw some simple graphics using Adafruit GFX functions. Yes, Inkplate library is 100% compatible with GFX lib! Learn more about Adafruit GFX: https://learn.adafruit.com/adafruit-gfx-graphics-library Inkplate will be used in grayscale mode which is 3 bit, so you can have up to 8 different colors (black, 6 gray colors and white) - Color is represented by number, where number 0 means black and number 7 means white, while everything in between are shades of gray. + Color is represented by number, where number 0 means black and number 7 means white, while everything in between are shades of gray. Want to learn more about Inkplate? Visit www.inkplate.io Looking to get support? Write on our forums: http://forum.e-radionica.com/en/ @@ -26,278 +26,278 @@ Inkplate display(INKPLATE_3BIT); //Create object on Inkplate library and set lib void setup() { - display.begin(); //Init library (you should call this function ONLY ONCE) - display.clearDisplay(); //Clear any data that may have been in (software) frame buffer. - //(NOTE! This does not clean image on screen, it only clears it in the frame buffer inside ESP32). - display.clean(); //Clear everything that has previously been on a screen - display.setTextColor(0, 7); - display.setCursor(150, 320); - display.setTextSize(4); - display.print("Welcome to Inkplate 6!"); - display.display(); //Write hello message - delay(5000); //Wait a little bit + display.begin(); //Init library (you should call this function ONLY ONCE) + display.clearDisplay(); //Clear any data that may have been in (software) frame buffer. + //(NOTE! This does not clean image on screen, it only clears it in the frame buffer inside ESP32). + display.clean(); //Clear everything that has previously been on a screen + display.setTextColor(0, 7); + display.setCursor(150, 320); + display.setTextSize(4); + display.print("Welcome to Inkplate 6!"); + display.display(); //Write hello message + delay(5000); //Wait a little bit } void loop() { - //Example will demostrate funcionality one by one. You always first set everything in the frame buffer and afterwards you show - //it on the screen using display.display(). + //Example will demostrate funcionality one by one. You always first set everything in the frame buffer and afterwards you show + //it on the screen using display.display(). - //Let'sstart by drawing pixel at x = 100 and y = 50 location - display.clearDisplay(); //Clear everytning that is inside frame buffer in ESP32 - display.drawPixel(100, 50, 0); //Draw one black pixel at X = 100, Y = 50 position in 0 (BLACK) color - displayCurrentAction("Drawing a pixel"); //Function which writes small text at bottom left indicating what's currently done - //NOTE: you do not need displayCurrentAction function to use Inkplate! - display.display(); //Send image to display. You need to call this one each time you want to transfer frame buffer to the screen. - delay(DELAY_MS); //Wait a little bit + //Let'sstart by drawing pixel at x = 100 and y = 50 location + display.clearDisplay(); //Clear everytning that is inside frame buffer in ESP32 + display.drawPixel(100, 50, 0); //Draw one black pixel at X = 100, Y = 50 position in 0 (BLACK) color + displayCurrentAction("Drawing a pixel"); //Function which writes small text at bottom left indicating what's currently done + //NOTE: you do not need displayCurrentAction function to use Inkplate! + display.display(); //Send image to display. You need to call this one each time you want to transfer frame buffer to the screen. + delay(DELAY_MS); //Wait a little bit - //Now, let's draw some random pixels! - display.clearDisplay(); //Clear everything that is inside frame buffer in ESP32 - for (int i = 0; i < 1000; i++) - { //Write 1000 random colored pixels at random locations - display.drawPixel(random(0, 799), random(0, 599), random(0, 7)); //We are setting color of the pixels using numbers from 0 to 7, - } //where 0 mens black, 7 white and gray is in between - displayCurrentAction("Drawing 600 random pixels in random colors"); - display.display(); //Write everything from frame buffer to screen - delay(DELAY_MS); //Wait + //Now, let's draw some random pixels! + display.clearDisplay(); //Clear everything that is inside frame buffer in ESP32 + for (int i = 0; i < 1000; i++) + { //Write 1000 random colored pixels at random locations + display.drawPixel(random(0, 799), random(0, 599), random(0, 7)); //We are setting color of the pixels using numbers from 0 to 7, + } //where 0 mens black, 7 white and gray is in between + displayCurrentAction("Drawing 600 random pixels in random colors"); + display.display(); //Write everything from frame buffer to screen + delay(DELAY_MS); //Wait - //Draw two diagonal lines accros screen - display.clearDisplay(); - display.drawLine(0, 0, 799, 599, 0); //All of those drawing fuctions originate from Adafruit GFX library, so maybe you are already familiar - display.drawLine(799, 0, 0, 599, 0); //with those. Arguments are: start X, start Y, ending X, ending Y, color. - displayCurrentAction("Drawing two diagonal lines"); - display.display(); - delay(DELAY_MS); - - //And again, let's draw some random lines on screen! - display.clearDisplay(); - for (int i = 0; i < 100; i++) - { - display.drawLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7)); - } - displayCurrentAction("Drawing 50 random lines in random colors"); - display.display(); - delay(DELAY_MS); - - //Let's draw some random thick lines on screen! - display.clearDisplay(); - for (int i = 0; i < 100; i++) - { - display.drawThickLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7), (float)random(1, 20)); - } - displayCurrentAction("Drawing 50 random lines in random colors and thickness"); - display.display(); - delay(DELAY_MS); - - //Let's draw some random gradient thick lines on screen! - display.clearDisplay(); - for (int i = 0; i < 100; i++) - { - int startColor = random(0, 7); - int endColor = random(startColor, 7); - display.drawGradientLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), startColor, endColor, (float)random(1, 20)); - } - displayCurrentAction("Drawing 50 random gradient lines in random colors and thickness"); - display.display(); - delay(DELAY_MS); - - //Now draw one horizontal... - display.clearDisplay(); - display.drawFastHLine(100, 100, 600, 0); //Arguments are: starting X, starting Y, length, color - displayCurrentAction("Drawing one horizontal line"); - display.display(); - delay(DELAY_MS); - - //... and one vertical line - display.clearDisplay(); - display.drawFastVLine(100, 100, 400, 0); //Arguments are: starting X, starting Y, length, color - displayCurrentAction("Drawing one vertical line"); - display.display(); - delay(DELAY_MS); - - //Now, let' make a grid using only horizontal and vertical lines in random colors! - display.clearDisplay(); - for (int i = 0; i < 800; i += 8) - { - display.drawFastVLine(i, 0, 600, (i / 8) & 0x0F); - } - for (int i = 0; i < 600; i += 4) - { - display.drawFastHLine(0, i, 800, (i / 8) & 0x0F); - } - displayCurrentAction("Drawing a grid using horizontal and vertical lines in different colors"); - display.display(); - delay(DELAY_MS); - - //Draw rectangle at X = 200, Y = 200 and size of 400x300 pixels - display.clearDisplay(); - display.drawRect(200, 200, 400, 300, 0); //Arguments are: start X, start Y, size X, size Y, color - displayCurrentAction("Drawing rectangle"); - display.display(); - delay(DELAY_MS); - - //Draw rectangles on random location, size 100x150 pixels in random color - display.clearDisplay(); - for (int i = 0; i < 50; i++) - { - display.drawRect(random(0, 799), random(0, 599), 100, 150, random(0, 7)); - } - displayCurrentAction("Drawing many rectangles in random colors"); - display.display(); - delay(DELAY_MS); - - //Draw filled black rectangle at X = 200, Y = 200, size of 400x300 pixels in gray color - display.clearDisplay(); - display.fillRect(200, 200, 400, 300, 4); //Arguments are: start X, start Y, size X, size Y, color - displayCurrentAction("Drawing gray rectangle"); - display.display(); - delay(DELAY_MS); - - //Draw filled random colored rectangles on random location, size of 30x30 pixels in radnom color - display.clearDisplay(); - for (int i = 0; i < 50; i++) - { - display.fillRect(random(0, 799), random(0, 599), 30, 30, random(0, 7)); - } - displayCurrentAction("Drawing many filled rectangles randomly in random colors"); - display.display(); - delay(DELAY_MS); - - //Draw circle at center of a screen with radius of 75 pixels - display.clearDisplay(); - display.drawCircle(400, 300, 75, 0); //Arguments are: start X, start Y, radius, color - displayCurrentAction("Drawing a circle"); - display.display(); - delay(DELAY_MS); - - //Draw some random colored circles at random location with radius of 25 pixels in random color - display.clearDisplay(); - for (int i = 0; i < 40; i++) - { - display.drawCircle(random(0, 799), random(0, 599), 25, random(0, 7)); - } - displayCurrentAction("Drawing many circles randomly in random colors"); - display.display(); - delay(DELAY_MS); - - //Draw black filled circle at center of a screen with radius of 75 pixels - display.clearDisplay(); - display.fillCircle(400, 300, 75, 0); //Arguments are: start X, start Y, radius, color - displayCurrentAction("Drawing black-filled circle"); - display.display(); - delay(DELAY_MS); - - //Draw some random colored filled circles at random location with radius of 15 pixels - display.clearDisplay(); - for (int i = 0; i < 40; i++) - { - display.fillCircle(random(0, 799), random(0, 599), 15, random(0, 7)); - } - displayCurrentAction("Drawing many filled circles randomly in random colors"); - display.display(); //To show stuff on screen, you always need to call display.display(); - delay(DELAY_MS); - - //Draw rounded rectangle at X = 200, Y = 200 and size of 400x300 pixels and radius of 10 pixels - display.clearDisplay(); - display.drawRoundRect(200, 200, 400, 300, 10, 0); //Arguments are: start X, start Y, size X, size Y, radius, color - displayCurrentAction("Drawing rectangle with rounded edges"); - display.display(); - delay(DELAY_MS); - - //Draw rounded rectangles on random location, size 100x150 pixels, radius of 5 pixels in radnom color - display.clearDisplay(); - for (int i = 0; i < 50; i++) - { - display.drawRoundRect(random(0, 799), random(0, 599), 100, 150, 5, random(0, 7)); - } - displayCurrentAction("Drawing many rounded edges rectangles"); - display.display(); - delay(DELAY_MS); - - //Draw filled random colored rectangle at X = 200, Y = 200, size of 400x300 pixels and radius of 10 pixels - display.clearDisplay(); - display.fillRoundRect(200, 200, 400, 300, 10, 0); //Arguments are: start X, start Y, size X, size Y, radius, color - displayCurrentAction("Drawing filled rectangle with rounded edges"); - display.display(); - delay(DELAY_MS); - - //Draw filled random colored rectangle on random location, size of 30x30 pixels, radius of 3 pixels in radnom color - display.clearDisplay(); - for (int i = 0; i < 50; i++) - { - display.fillRoundRect(random(0, 799), random(0, 599), 30, 30, 3, random(0, 7)); - } - displayCurrentAction("Drawing many filled rectangle with rounded edges in random colors"); - display.display(); - delay(DELAY_MS); - - //Draw simple triangle - display.clearDisplay(); - display.drawTriangle(250, 400, 550, 400, 400, 100, 0); //Arguments are: X1, Y1, X2, Y2, X3, Y3, color - display.display(); - delay(DELAY_MS); - - //Draw filled triangle inside simple triangle (so no display.clearDisplay() this time) - display.fillTriangle(300, 350, 500, 350, 400, 150, 0); //Arguments are: X1, Y1, X2, Y2, X3, Y3, color - displayCurrentAction("Drawing filled triangle inside exsisting one"); - display.display(); - delay(DELAY_MS); - - //Display some grayscale image on screen. We are going to display e-radionica logo on display at location X = 100, Y = 100 - //Image size is 500x332 pixels. - display.clearDisplay(); - display.drawBitmap3Bit(100, 100, picture1, 500, 332); //Arguments are: start X, start Y, array variable name, size X, size Y - displayCurrentAction("Drawing a bitmap image"); - display.display(); - delay(DELAY_MS); - - //Write some text on screen with different sizes and color - display.clearDisplay(); - for (int i = 0; i < 6; i++) - { - display.setTextColor(i); - display.setTextSize(i + 1); //textSize parameter starts at 0 and goes up to 10 (larger won't fit Inkplate 6 screen) - display.setCursor(200, (i * i * 8)); //setCursor works as same as on LCD displays - sets "the cursor" at the place you want to write someting next - display.print("INKPLATE6!"); //The actual text you want to show on e-paper as String - } - displayCurrentAction("Text in different sizes and shadings"); - display.display(); //To show stuff on screen, you always need to call display.display(); - delay(DELAY_MS); - - //Write same text on different location, but now invert colors (text is white, text background is black) - display.setTextColor(7, 0); //First argument is text color, while second argument is background color. In greyscale, - for (int i = 0; i < 6; i++) - { //you are able to choose from 8 different colors (0-7) - display.setTextSize(i + 1); - display.setCursor(200, 300 + (i * i * 8)); - display.print("INKPLATE6!"); - } - display.display(); - delay(DELAY_MS); - - //Write text and rotate it by 90 deg. forever - int r = 0; - display.setTextSize(8); - display.setTextColor(7, 0); - while (true) - { - display.setCursor(100, 100); + //Draw two diagonal lines accros screen display.clearDisplay(); - display.setRotation(r); //Set rotation will sent rotation for the entire display, so you can use it sideways or upside-down - display.print("INKPLATE6"); + display.drawLine(0, 0, 799, 599, 0); //All of those drawing fuctions originate from Adafruit GFX library, so maybe you are already familiar + display.drawLine(799, 0, 0, 599, 0); //with those. Arguments are: start X, start Y, ending X, ending Y, color. + displayCurrentAction("Drawing two diagonal lines"); display.display(); - r++; delay(DELAY_MS); - } - //Did you know that you can change between monochrome and greyscale mode anytime? - //Just call Inkplate display(INKPLATE_1BIT) or Inkplate display(INKPLATE_3BIT) + //And again, let's draw some random lines on screen! + display.clearDisplay(); + for (int i = 0; i < 100; i++) + { + display.drawLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7)); + } + displayCurrentAction("Drawing 50 random lines in random colors"); + display.display(); + delay(DELAY_MS); + + //Let's draw some random thick lines on screen! + display.clearDisplay(); + for (int i = 0; i < 100; i++) + { + display.drawThickLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), random(0, 7), (float)random(1, 20)); + } + displayCurrentAction("Drawing 50 random lines in random colors and thickness"); + display.display(); + delay(DELAY_MS); + + //Let's draw some random gradient thick lines on screen! + display.clearDisplay(); + for (int i = 0; i < 100; i++) + { + int startColor = random(0, 7); + int endColor = random(startColor, 7); + display.drawGradientLine(random(0, 799), random(0, 599), random(0, 799), random(0, 599), startColor, endColor, (float)random(1, 20)); + } + displayCurrentAction("Drawing 50 random gradient lines in random colors and thickness"); + display.display(); + delay(DELAY_MS); + + //Now draw one horizontal... + display.clearDisplay(); + display.drawFastHLine(100, 100, 600, 0); //Arguments are: starting X, starting Y, length, color + displayCurrentAction("Drawing one horizontal line"); + display.display(); + delay(DELAY_MS); + + //... and one vertical line + display.clearDisplay(); + display.drawFastVLine(100, 100, 400, 0); //Arguments are: starting X, starting Y, length, color + displayCurrentAction("Drawing one vertical line"); + display.display(); + delay(DELAY_MS); + + //Now, let' make a grid using only horizontal and vertical lines in random colors! + display.clearDisplay(); + for (int i = 0; i < 800; i += 8) + { + display.drawFastVLine(i, 0, 600, (i / 8) & 0x0F); + } + for (int i = 0; i < 600; i += 4) + { + display.drawFastHLine(0, i, 800, (i / 8) & 0x0F); + } + displayCurrentAction("Drawing a grid using horizontal and vertical lines in different colors"); + display.display(); + delay(DELAY_MS); + + //Draw rectangle at X = 200, Y = 200 and size of 400x300 pixels + display.clearDisplay(); + display.drawRect(200, 200, 400, 300, 0); //Arguments are: start X, start Y, size X, size Y, color + displayCurrentAction("Drawing rectangle"); + display.display(); + delay(DELAY_MS); + + //Draw rectangles on random location, size 100x150 pixels in random color + display.clearDisplay(); + for (int i = 0; i < 50; i++) + { + display.drawRect(random(0, 799), random(0, 599), 100, 150, random(0, 7)); + } + displayCurrentAction("Drawing many rectangles in random colors"); + display.display(); + delay(DELAY_MS); + + //Draw filled black rectangle at X = 200, Y = 200, size of 400x300 pixels in gray color + display.clearDisplay(); + display.fillRect(200, 200, 400, 300, 4); //Arguments are: start X, start Y, size X, size Y, color + displayCurrentAction("Drawing gray rectangle"); + display.display(); + delay(DELAY_MS); + + //Draw filled random colored rectangles on random location, size of 30x30 pixels in radnom color + display.clearDisplay(); + for (int i = 0; i < 50; i++) + { + display.fillRect(random(0, 799), random(0, 599), 30, 30, random(0, 7)); + } + displayCurrentAction("Drawing many filled rectangles randomly in random colors"); + display.display(); + delay(DELAY_MS); + + //Draw circle at center of a screen with radius of 75 pixels + display.clearDisplay(); + display.drawCircle(400, 300, 75, 0); //Arguments are: start X, start Y, radius, color + displayCurrentAction("Drawing a circle"); + display.display(); + delay(DELAY_MS); + + //Draw some random colored circles at random location with radius of 25 pixels in random color + display.clearDisplay(); + for (int i = 0; i < 40; i++) + { + display.drawCircle(random(0, 799), random(0, 599), 25, random(0, 7)); + } + displayCurrentAction("Drawing many circles randomly in random colors"); + display.display(); + delay(DELAY_MS); + + //Draw black filled circle at center of a screen with radius of 75 pixels + display.clearDisplay(); + display.fillCircle(400, 300, 75, 0); //Arguments are: start X, start Y, radius, color + displayCurrentAction("Drawing black-filled circle"); + display.display(); + delay(DELAY_MS); + + //Draw some random colored filled circles at random location with radius of 15 pixels + display.clearDisplay(); + for (int i = 0; i < 40; i++) + { + display.fillCircle(random(0, 799), random(0, 599), 15, random(0, 7)); + } + displayCurrentAction("Drawing many filled circles randomly in random colors"); + display.display(); //To show stuff on screen, you always need to call display.display(); + delay(DELAY_MS); + + //Draw rounded rectangle at X = 200, Y = 200 and size of 400x300 pixels and radius of 10 pixels + display.clearDisplay(); + display.drawRoundRect(200, 200, 400, 300, 10, 0); //Arguments are: start X, start Y, size X, size Y, radius, color + displayCurrentAction("Drawing rectangle with rounded edges"); + display.display(); + delay(DELAY_MS); + + //Draw rounded rectangles on random location, size 100x150 pixels, radius of 5 pixels in radnom color + display.clearDisplay(); + for (int i = 0; i < 50; i++) + { + display.drawRoundRect(random(0, 799), random(0, 599), 100, 150, 5, random(0, 7)); + } + displayCurrentAction("Drawing many rounded edges rectangles"); + display.display(); + delay(DELAY_MS); + + //Draw filled random colored rectangle at X = 200, Y = 200, size of 400x300 pixels and radius of 10 pixels + display.clearDisplay(); + display.fillRoundRect(200, 200, 400, 300, 10, 0); //Arguments are: start X, start Y, size X, size Y, radius, color + displayCurrentAction("Drawing filled rectangle with rounded edges"); + display.display(); + delay(DELAY_MS); + + //Draw filled random colored rectangle on random location, size of 30x30 pixels, radius of 3 pixels in radnom color + display.clearDisplay(); + for (int i = 0; i < 50; i++) + { + display.fillRoundRect(random(0, 799), random(0, 599), 30, 30, 3, random(0, 7)); + } + displayCurrentAction("Drawing many filled rectangle with rounded edges in random colors"); + display.display(); + delay(DELAY_MS); + + //Draw simple triangle + display.clearDisplay(); + display.drawTriangle(250, 400, 550, 400, 400, 100, 0); //Arguments are: X1, Y1, X2, Y2, X3, Y3, color + display.display(); + delay(DELAY_MS); + + //Draw filled triangle inside simple triangle (so no display.clearDisplay() this time) + display.fillTriangle(300, 350, 500, 350, 400, 150, 0); //Arguments are: X1, Y1, X2, Y2, X3, Y3, color + displayCurrentAction("Drawing filled triangle inside exsisting one"); + display.display(); + delay(DELAY_MS); + + //Display some grayscale image on screen. We are going to display e-radionica logo on display at location X = 100, Y = 100 + //Image size is 500x332 pixels. + display.clearDisplay(); + display.drawBitmap3Bit(100, 100, picture1, 500, 332); //Arguments are: start X, start Y, array variable name, size X, size Y + displayCurrentAction("Drawing a bitmap image"); + display.display(); + delay(DELAY_MS); + + //Write some text on screen with different sizes and color + display.clearDisplay(); + for (int i = 0; i < 6; i++) + { + display.setTextColor(i); + display.setTextSize(i + 1); //textSize parameter starts at 0 and goes up to 10 (larger won't fit Inkplate 6 screen) + display.setCursor(200, (i * i * 8)); //setCursor works as same as on LCD displays - sets "the cursor" at the place you want to write someting next + display.print("INKPLATE6!"); //The actual text you want to show on e-paper as String + } + displayCurrentAction("Text in different sizes and shadings"); + display.display(); //To show stuff on screen, you always need to call display.display(); + delay(DELAY_MS); + + //Write same text on different location, but now invert colors (text is white, text background is black) + display.setTextColor(7, 0); //First argument is text color, while second argument is background color. In greyscale, + for (int i = 0; i < 6; i++) + { //you are able to choose from 8 different colors (0-7) + display.setTextSize(i + 1); + display.setCursor(200, 300 + (i * i * 8)); + display.print("INKPLATE6!"); + } + display.display(); + delay(DELAY_MS); + + //Write text and rotate it by 90 deg. forever + int r = 0; + display.setTextSize(8); + display.setTextColor(7, 0); + while (true) + { + display.setCursor(100, 100); + display.clearDisplay(); + display.setRotation(r); //Set rotation will sent rotation for the entire display, so you can use it sideways or upside-down + display.print("INKPLATE6"); + display.display(); + r++; + delay(DELAY_MS); + } + + //Did you know that you can change between monochrome and greyscale mode anytime? + //Just call Inkplate display(INKPLATE_1BIT) or Inkplate display(INKPLATE_3BIT) } //Small function that will write on the screen what function is currently in demonstration. void displayCurrentAction(String text) { - display.setTextSize(2); - display.setCursor(2, 580); - display.print(text); + display.setTextSize(2); + display.setCursor(2, 580); + display.print(text); } \ No newline at end of file diff --git a/examples/3. Projects/1-Daily_weather_station_example/1-Daily_weather_station_example.ino b/examples/3. Projects/1-Daily_weather_station_example/1-Daily_weather_station_example.ino index bd4c678..c925acc 100644 --- a/examples/3. Projects/1-Daily_weather_station_example/1-Daily_weather_station_example.ino +++ b/examples/3. Projects/1-Daily_weather_station_example/1-Daily_weather_station_example.ino @@ -55,11 +55,11 @@ Inkplate display(INKPLATE_1BIT); Network network; // Contants used for drawing icons -char abbrs[32][16] = {"sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "c"}; -const uint8_t *logos[16] = {icon_sn, icon_sl, icon_h, icon_t, icon_hr, icon_lr, icon_s, icon_hc, icon_lc, icon_c}; +char abbrs[32][16] ={ "sn", "sl", "h", "t", "hr", "lr", "s", "hc", "lc", "c" }; +const uint8_t *logos[16] ={ icon_sn, icon_sl, icon_h, icon_t, icon_hr, icon_lr, icon_s, icon_hc, icon_lc, icon_c }; // Variables for storing temperature -char temps[8][4] = { +char temps[8][4] ={ "0F", "0F", "0F", @@ -67,7 +67,7 @@ char temps[8][4] = { }; // Variables for storing days of the week -char days[8][4] = { +char days[8][4] ={ "", "", "", @@ -153,6 +153,8 @@ void loop() else display.partialUpdate(); + + // Go to sleep before checking again esp_sleep_enable_timer_wakeup(1000L * DELAY_MS); (void)esp_light_sleep_start(); diff --git a/examples/3. Projects/1-Daily_weather_station_example/Network.cpp b/examples/3. Projects/1-Daily_weather_station_example/Network.cpp index bd5f46d..7449ccc 100644 --- a/examples/3. Projects/1-Daily_weather_station_example/Network.cpp +++ b/examples/3. Projects/1-Daily_weather_station_example/Network.cpp @@ -3,20 +3,15 @@ #include "Network.h" #include -#include #include -#include #include -// WiFiMulti object declaration -WiFiMulti WiFiMulti; - // Static Json from ArduinoJson library StaticJsonDocument<6000> doc; // Declared week days -char weekDays[8][8] = { +char weekDays[8][8] ={ "Mon", "Tue", "Wed", @@ -30,25 +25,27 @@ void Network::begin(char *city) { // Initiating wifi, like in BasicHttpClient example WiFi.mode(WIFI_STA); - WiFiMulti.addAP(ssid, pass); + WiFi.begin(ssid, pass); - Serial.print(F("Waiting for WiFi to connect...")); - while ((WiFiMulti.run() != WL_CONNECTED)) - { - // Printing a dot to Serial monitor every second while waiting to connect - Serial.print(F(".")); - delay(1000); + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); + + delay(5000); + + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } } - Serial.println(F(" connected")); // Find internet time setTime(); // Search for given cities woeid findCity(city); - - // reduce power by making WiFi module sleep - WiFi.setSleep(1); } // Gets time from ntp server @@ -89,9 +86,20 @@ void formatWind(char *str, float wind) void Network::getData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr) { - // Return if wifi isn't connected - if (WiFi.status() != WL_CONNECTED) - return; + // Reconnect if wifi isn't connected + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); + + delay(5000); + + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } + } // Wake up if sleeping and save inital state bool sleep = WiFi.getSleep(); @@ -201,9 +209,20 @@ void Network::getDays(char *day, char *day1, char *day2, char *day3) void Network::findCity(char *city) { - // If not connected to wifi, return - if (WiFi.status() != WL_CONNECTED) - return; + // If not connected to wifi reconnect wifi + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); + + delay(5000); + + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } + } // Wake wifi module and save initial state bool sleep = WiFi.getSleep(); diff --git a/examples/3. Projects/2-Hourly_weather_station_example/2-Hourly_weather_station_example.ino b/examples/3. Projects/2-Hourly_weather_station_example/2-Hourly_weather_station_example.ino index 0ccdcfd..6453dc2 100644 --- a/examples/3. Projects/2-Hourly_weather_station_example/2-Hourly_weather_station_example.ino +++ b/examples/3. Projects/2-Hourly_weather_station_example/2-Hourly_weather_station_example.ino @@ -63,8 +63,8 @@ Inkplate display(INKPLATE_1BIT); Network network; //Contants used for drawing icons -char abbrs[32][32] = {"01d", "02d", "03d", "04d", "09d", "10d", "11d", "13d", "50d", "01n", "02n", "03n", "04n", "09n", "10n", "11n", "13n", "50n"}; -const uint8_t *logos[18] = { +char abbrs[32][32] ={ "01d", "02d", "03d", "04d", "09d", "10d", "11d", "13d", "50d", "01n", "02n", "03n", "04n", "09n", "10n", "11n", "13n", "50n" }; +const uint8_t *logos[18] ={ icon_01d, icon_02d, icon_03d, @@ -85,7 +85,7 @@ const uint8_t *logos[18] = { icon_50n, }; -const uint8_t *s_logos[18] = { +const uint8_t *s_logos[18] ={ icon_s_01d, icon_s_02d, icon_s_03d, @@ -107,7 +107,7 @@ const uint8_t *s_logos[18] = { }; //Variables for storing temperature -char temps[8][4] = { +char temps[8][4] ={ "0F", "0F", "0F", @@ -115,7 +115,7 @@ char temps[8][4] = { }; //Variables for storing hour strings -char hours[8][4] = { +char hours[8][4] ={ "", "", "", diff --git a/examples/3. Projects/2-Hourly_weather_station_example/Network.cpp b/examples/3. Projects/2-Hourly_weather_station_example/Network.cpp index 3636e1a..9b51ee2 100644 --- a/examples/3. Projects/2-Hourly_weather_station_example/Network.cpp +++ b/examples/3. Projects/2-Hourly_weather_station_example/Network.cpp @@ -3,15 +3,11 @@ #include "Network.h" #include -#include #include #include #include -//WiFiMulti object declaration -WiFiMulti WiFiMulti; - //Static Json from ArduinoJson library StaticJsonDocument<32000> doc; @@ -19,10 +15,10 @@ void Network::begin(char *city) { //Initiating wifi, like in BasicHttpClient example WiFi.mode(WIFI_STA); - WiFiMulti.addAP(ssid, pass); + WiFi.begin(ssid, pass); Serial.print(F("Waiting for WiFi to connect...")); - while ((WiFiMulti.run() != WL_CONNECTED)) + while ((WiFi.status() != WL_CONNECTED)) { //Printing a dot to Serial monitor every second while waiting to connect Serial.print(F(".")); @@ -76,10 +72,20 @@ void formatWind(char *str, float wind) bool Network::getData(char *city, char *temp1, char *temp2, char *temp3, char *temp4, char *currentTemp, char *currentWind, char *currentTime, char *currentWeather, char *currentWeatherAbbr, char *abbr1, char *abbr2, char *abbr3, char *abbr4) { bool f = 0; + // If not connected to wifi reconnect wifi + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); - //Return if wifi isn't connected - if (WiFi.status() != WL_CONNECTED) - return 0; + delay(5000); + + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } + } //Wake up if sleeping and save inital state bool sleep = WiFi.getSleep(); diff --git a/examples/3. Projects/3-Crypto_tracker_example/3-Crypto_tracker_example.ino b/examples/3. Projects/3-Crypto_tracker_example/3-Crypto_tracker_example.ino index f9c781f..f244d9f 100644 --- a/examples/3. Projects/3-Crypto_tracker_example/3-Crypto_tracker_example.ino +++ b/examples/3. Projects/3-Crypto_tracker_example/3-Crypto_tracker_example.ino @@ -8,7 +8,7 @@ This example will show you how you can use Inkplate 6 to display API data. Here we use Coingecko API to get latest cryptocurrency prices and display them on the Inkplate screen. If you wish to change the currecny, you can - edit it below. + edit it below. IMPORTANT: Make sure to change your timezone and wifi credentials below @@ -92,7 +92,7 @@ char minimum[16]; char maximum[16]; //All months in a year, for finding current date -char *months[] = { +char *months[] ={ "Jan" "Feb", "Mar", @@ -108,27 +108,27 @@ char *months[] = { }; //Out UI elements data -textElement elements[] = { - {50, 130, &Roboto_Light_160, currencyAbbr, 0}, - {390, 80, &Roboto_Light_40, date, 0}, - {190, 185, &Roboto_Light_40, fromToDate, 0}, - {570, 140, &Roboto_Light_40, "Current price:", 0}, - {790, 190, &Roboto_Light_40, current, 1}, - {630, 275, &Roboto_Light_40, "Minimum:", 0}, - {790, 320, &Roboto_Light_40, minimum, 1}, - {625, 420, &Roboto_Light_40, "Maximum:", 0}, - {790, 466, &Roboto_Light_40, maximum, 1}, +textElement elements[] ={ + { 50, 130, &Roboto_Light_160, currencyAbbr, 0 }, + { 390, 80, &Roboto_Light_40, date, 0 }, + { 190, 185, &Roboto_Light_40, fromToDate, 0 }, + { 570, 140, &Roboto_Light_40, "Current price:", 0 }, + { 790, 190, &Roboto_Light_40, current, 1 }, + { 630, 275, &Roboto_Light_40, "Minimum:", 0 }, + { 790, 320, &Roboto_Light_40, minimum, 1 }, + { 625, 420, &Roboto_Light_40, "Maximum:", 0 }, + { 790, 466, &Roboto_Light_40, maximum, 1 }, - {18, 570, &Roboto_Light_36, dates, 0}, - {122, 570, &Roboto_Light_36, dates + 8, 0}, - {227, 570, &Roboto_Light_36, dates + 16, 0}, - {342, 570, &Roboto_Light_36, dates + 24, 0}, - {466, 570, &Roboto_Light_36, dates + 32, 0}, + { 18, 570, &Roboto_Light_36, dates, 0 }, + { 122, 570, &Roboto_Light_36, dates + 8, 0 }, + { 227, 570, &Roboto_Light_36, dates + 16, 0 }, + { 342, 570, &Roboto_Light_36, dates + 24, 0 }, + { 466, 570, &Roboto_Light_36, dates + 32, 0 }, - {450, 240, &Roboto_Light_36, prices, 0}, - {450, 322, &Roboto_Light_36, prices + 16, 0}, - {450, 401, &Roboto_Light_36, prices + 32, 0}, - {450, 483, &Roboto_Light_36, prices + 48, 0}, + { 450, 240, &Roboto_Light_36, prices, 0 }, + { 450, 322, &Roboto_Light_36, prices + 16, 0 }, + { 450, 401, &Roboto_Light_36, prices + 32, 0 }, + { 450, 483, &Roboto_Light_36, prices + 48, 0 }, }; // Our functions declared below setup and loop @@ -270,9 +270,9 @@ void drawGraph() //Draw a gradient line from every pixel to bottom line in graph line for (int j = 0; j < (x2 - x1 - textMargin) / 31 + 1; ++j) display.drawGradientLine(prev_x + j, - (int)round((double)prev_y + dy * (double)j), - prev_x + j, - y1, 3, 7); + (int)round((double)prev_y + dy * (double)j), + prev_x + j, + y1, 3, 7); } //Set previous x and y diff --git a/examples/3. Projects/3-Crypto_tracker_example/Network.cpp b/examples/3. Projects/3-Crypto_tracker_example/Network.cpp index 9f28329..51b3508 100644 --- a/examples/3. Projects/3-Crypto_tracker_example/Network.cpp +++ b/examples/3. Projects/3-Crypto_tracker_example/Network.cpp @@ -1,7 +1,6 @@ #include "Network.h" #include -#include #include #include @@ -18,9 +17,6 @@ extern char *currency; //Get our Inkplate object from main file to draw debug info on extern Inkplate display; -//WiFiMulti object declaration -WiFiMulti WiFiMulti; - //Static Json from ArduinoJson library StaticJsonDocument<30000> doc; @@ -28,10 +24,10 @@ void Network::begin() { //Initiating wifi, like in BasicHttpClient example WiFi.mode(WIFI_STA); - WiFiMulti.addAP(ssid, pass); + WiFi.begin(ssid, pass); Serial.print(F("Waiting for WiFi to connect...")); - while ((WiFiMulti.run() != WL_CONNECTED)) + while ((WiFi.status() != WL_CONNECTED)) { Serial.print(F(".")); delay(1000); @@ -70,9 +66,20 @@ bool Network::getData(double *data) { bool f = 0; - //Return if wifi isn't connected - if (WiFi.status() != WL_CONNECTED) - return 0; + // If not connected to wifi reconnect wifi + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); + + delay(5000); + + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } + } //Wake up if sleeping and save inital state bool sleep = WiFi.getSleep(); diff --git a/examples/3. Projects/4-Google_calendar_example/4-Google_calendar_example.ino b/examples/3. Projects/4-Google_calendar_example/4-Google_calendar_example.ino index 0f15ac5..9227f13 100644 --- a/examples/3. Projects/4-Google_calendar_example/4-Google_calendar_example.ino +++ b/examples/3. Projects/4-Google_calendar_example/4-Google_calendar_example.ino @@ -5,7 +5,7 @@ Don't have "Inkplate 6(ESP32)" option? Follow our tutorial and add it: https://e-radionica.com/en/blog/add-inkplate-6-to-arduino-ide/ - This project shows you how Inkplate 6 can be used to display + This project shows you how Inkplate 6 can be used to display events in your Google Calendar using their provided API For this to work you need to change your timezone, wifi credentials and your private calendar url @@ -16,7 +16,7 @@ 3. Click 'Settings and sharing' 4. Navigate to 'Integrate Calendar' 5. Take the 'Secret address in iCal format' - + (https://support.google.com/calendar/thread/2408874?hl=en) Want to learn more about Inkplate? Visit www.inkplate.io @@ -111,8 +111,6 @@ void setup() delay(5000); network.begin(); - //Our begin function - network.begin(); } void loop() @@ -238,7 +236,7 @@ void drawGrid() void getToFrom(char *dst, char *from, char *to, int *day, int *timeStamp) { //ANSI C time struct - struct tm ltm = {0}, ltm2 = {0}; + struct tm ltm ={ 0 }, ltm2 ={ 0 }; char temp[128], temp2[128]; strncpy(temp, from, 16); temp[16] = 0; @@ -369,7 +367,7 @@ bool drawEvent(entry *event, int day, int beginY, int maxHeigth, int *heigthNeed display.setCursor(x1 + 5, display.getCursorY()); - char line[128] = {0}; + char line[128] ={ 0 }; for (int i = 0; i < strlen(event->location); ++i) { @@ -465,14 +463,14 @@ void drawData() //Sort entries by time qsort(entries, - entriesNum, - sizeof(entry), - cmp); + entriesNum, + sizeof(entry), + cmp); //Events displayed and overflown counters - int columns[3] = {0}; - bool clogged[3] = {0}; - int cloggedCount[3] = {0}; + int columns[3] ={ 0 }; + bool clogged[3] ={ 0 }; + int cloggedCount[3] ={ 0 }; //Displaying events one by one for (int i = 0; i < entriesNum; ++i) diff --git a/examples/3. Projects/4-Google_calendar_example/Network.cpp b/examples/3. Projects/4-Google_calendar_example/Network.cpp index ba20e9c..3edef49 100644 --- a/examples/3. Projects/4-Google_calendar_example/Network.cpp +++ b/examples/3. Projects/4-Google_calendar_example/Network.cpp @@ -1,21 +1,18 @@ #include "Network.h" #include -#include #include #include -// WiFiMulti object declaration -WiFiMulti WiFiMulti; void Network::begin() { // Initiating wifi, like in BasicHttpClient example WiFi.mode(WIFI_STA); - WiFiMulti.addAP(ssid, pass); + WiFi.begin(ssid, pass); Serial.print(F("Waiting for WiFi to connect...")); - while ((WiFiMulti.run() != WL_CONNECTED)) + while ((WiFi.status() != WL_CONNECTED)) { // Prints a dot every second that wifi isn't connected Serial.print(F(".")); @@ -46,14 +43,20 @@ bool Network::getData(char *data) { // Variable to store fail bool f = 0; + // If not connected to wifi reconnect wifi + if (WiFi.status() != WL_CONNECTED) { + WiFi.reconnect(); - // Return if wifi isn't connected - if (WiFi.status() != WL_CONNECTED) - return 0; + delay(5000); - // Wake up if sleeping and save inital state - bool sleep = WiFi.getSleep(); - WiFi.setSleep(false); + Serial.println(F("Waiting for WiFi to reconnect...")); + while ((WiFi.status() != WL_CONNECTED)) + { + // Prints a dot every second that wifi isn't connected + Serial.print(F(".")); + delay(1000); + } + } // Http object used to make get request HTTPClient http; @@ -68,23 +71,23 @@ bool Network::getData(char *data) // Actually do request int httpCode = http.GET(); + if (httpCode == 200) { long n = 0; while (http.getStream().available()) data[n++] = http.getStream().read(); + data[n++]= 0; } else { + Serial.println(httpCode); f = 1; } // end http http.end(); - // Return to initial state - WiFi.setSleep(sleep); - return !f; }