From 7a01f64f6d58fedafc142bfa136725772cc00a4b Mon Sep 17 00:00:00 2001 From: NoobTracker <63962365+NoobTracker@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:48:42 +0200 Subject: [PATCH 1/5] Update OLEDDisplay.cpp --- src/OLEDDisplay.cpp | 271 ++++++++++++++++++++++++++++++-------------- 1 file changed, 188 insertions(+), 83 deletions(-) diff --git a/src/OLEDDisplay.cpp b/src/OLEDDisplay.cpp index df1832f..b088257 100644 --- a/src/OLEDDisplay.cpp +++ b/src/OLEDDisplay.cpp @@ -216,123 +216,228 @@ void OLEDDisplay::fillRect(int16_t xMove, int16_t yMove, int16_t width, int16_t } } -void OLEDDisplay::drawCircle(int16_t x0, int16_t y0, int16_t radius) { - int16_t x = 0, y = radius; - int16_t dp = 1 - radius; - do { - if (dp < 0) - dp = dp + (x++) * 2 + 3; - else - dp = dp + (x++) * 2 - (y--) * 2 + 5; - - setPixel(x0 + x, y0 + y); //For the 8 octants - setPixel(x0 - x, y0 + y); - setPixel(x0 + x, y0 - y); - setPixel(x0 - x, y0 - y); - setPixel(x0 + y, y0 + x); - setPixel(x0 - y, y0 + x); - setPixel(x0 + y, y0 - x); - setPixel(x0 - y, y0 - x); - - } while (x < y); - - setPixel(x0 + radius, y0); - setPixel(x0, y0 + radius); - setPixel(x0 - radius, y0); - setPixel(x0, y0 - radius); -} - -void OLEDDisplay::drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads) { +uint8_t OLEDDisplay::drawCircle(int16_t x0, int16_t y0, uint16_t radius, uint8_t quads, bool improve) { + quads &= B1111; + if (improve) { + if ((((x0 + radius) < 0) || ((y0 + radius) < 0)) || ((x0 > 127) || (y0 > 63))) { + quads &= B0111; + } + if ((((x0 - radius) > 127) || ((y0 + radius) < 0)) || ((x0 < 0) || (y0 > 63))) { + quads &= B1011; + } + if ((((x0 + radius) < 0) || ((y0 - radius) > 63)) || ((x0 > 127) || (y0 < 0))) { + quads &= B1110; + } + if ((((x0 - radius) > 127) || ((y0 - radius) > 63)) || ((x0 < 0) || (y0 < 0))) { + quads &= B1101; + } + if (!quads) { + return false; + } + } int16_t x = 0, y = radius; int16_t dp = 1 - radius; - while (x < y) { - if (dp < 0) - dp = dp + (x++) * 2 + 3; - else - dp = dp + (x++) * 2 - (y--) * 2 + 5; - if (quads & 0x1) { + if (quads == B1111) { + while (x < y) { + if (dp < 0) + dp = dp + (x++) * 2 + 3; + else + dp = dp + (x++) * 2 - (y--) * 2 + 5; setPixel(x0 + x, y0 - y); setPixel(x0 + y, y0 - x); - } - if (quads & 0x2) { setPixel(x0 - y, y0 - x); setPixel(x0 - x, y0 - y); - } - if (quads & 0x4) { setPixel(x0 - y, y0 + x); setPixel(x0 - x, y0 + y); - } - if (quads & 0x8) { setPixel(x0 + x, y0 + y); setPixel(x0 + y, y0 + x); } - } - if (quads & 0x1 && quads & 0x8) { setPixel(x0 + radius, y0); - } - if (quads & 0x4 && quads & 0x8) { setPixel(x0, y0 + radius); - } - if (quads & 0x2 && quads & 0x4) { setPixel(x0 - radius, y0); - } - if (quads & 0x1 && quads & 0x2) { setPixel(x0, y0 - radius); } + else { + while (x < y) { + if (dp < 0) + dp = dp + (x++) * 2 + 3; + else + dp = dp + (x++) * 2 - (y--) * 2 + 5; + if (quads & 0x1) { + setPixel(x0 + x, y0 - y); + setPixel(x0 + y, y0 - x); + } + if (quads & 0x2) { + setPixel(x0 - y, y0 - x); + setPixel(x0 - x, y0 - y); + } + if (quads & 0x4) { + setPixel(x0 - y, y0 + x); + setPixel(x0 - x, y0 + y); + } + if (quads & 0x8) { + setPixel(x0 + x, y0 + y); + setPixel(x0 + y, y0 + x); + } + } + + if (quads & B1001) { + setPixel(x0 + radius, y0); + } + if (quads & B1100) { + setPixel(x0, y0 + radius); + } + if (quads & B0110) { + setPixel(x0 - radius, y0); + } + if (quads & B0011) { + setPixel(x0, y0 - radius); + } + } + return quads; } +void OLEDDisplay::drawCircleQuads(int16_t x0, int16_t y0, uint16_t radius, uint8_t quads) { //Only for backward compatibility + drawCircle(x0, y0, radius, quads); +} -void OLEDDisplay::fillCircle(int16_t x0, int16_t y0, int16_t radius) { +uint8_t OLEDDisplay::fillCircle(int16_t x0, int16_t y0, uint16_t radius, bool improve) { + if (improve) { + return fillRing(x0, y0, radius, 0, B1111, true); + } int16_t x = 0, y = radius; - int16_t dp = 1 - radius; - do { - if (dp < 0) + int16_t dp = 1 - radius; + do { + if (dp < 0) dp = dp + (x++) * 2 + 3; else dp = dp + (x++) * 2 - (y--) * 2 + 5; - drawHorizontalLine(x0 - x, y0 - y, 2*x); - drawHorizontalLine(x0 - x, y0 + y, 2*x); - drawHorizontalLine(x0 - y, y0 - x, 2*y); - drawHorizontalLine(x0 - y, y0 + x, 2*y); + drawHorizontalLine(x0 - x, y0 - y, 2 * x + 1); + drawHorizontalLine(x0 - x, y0 + y, 2 * x + 1); + drawHorizontalLine(x0 - y, y0 - x, 2 * y + 1); + drawHorizontalLine(x0 - y, y0 + x, 2 * y + 1); - } while (x < y); - drawHorizontalLine(x0 - radius, y0, 2 * radius); - + } while (x < y); + drawHorizontalLine(x0 - radius, y0, (2 * radius) + 1); + drawVerticalLine(x0, y0 - radius, 2 * radius); + return B1111; } -void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) { - if (y < 0 || y >= this->height()) { return; } - - if (x < 0) { - length += x; - x = 0; +uint8_t OLEDDisplay::fillRing(int16_t x0, int16_t y0, uint16_t radius, uint16_t radius2, byte quads, bool improve) { + quads &= B1111; + if (radius < radius2) { + _swap_int16_t(radius, radius2); } - - if ( (x + length) > this->width()) { - length = (this->width() - x); + if (improve) { + if ((((x0 + radius) < 0) || ((y0 + radius) < 0)) || ((x0 > 127) || (y0 > 63))) { + quads &= B0111; + } + if ((((x0 - radius) > 127) || ((y0 + radius) < 0)) || ((x0 < 0) || (y0 > 63))) { + quads &= B1011; + } + if ((((x0 + radius) < 0) || ((y0 - radius) > 63)) || ((x0 > 127) || (y0 < 0))) { + quads &= B1110; + } + if ((((x0 - radius) > 127) || ((y0 - radius) > 63)) || ((x0 < 0) || (y0 < 0))) { + quads &= B1101; + } } + if (quads == 0) { + return false; + } + if(radius2 == 0){ + setPixel(x0, y0); + radius2 = 1; + } + int16_t x = 0, y = radius; + int16_t dp = 1 - radius; - if (length <= 0) { return; } - - uint8_t * bufferPtr = buffer; - bufferPtr += (y >> 3) * this->width(); - bufferPtr += x; + int16_t x2 = 0, y2 = radius2; + int16_t dp2 = 1 - radius2; + if (quads == B1111) { + do { + if (dp < 0) + dp = dp + (x++) * 2 + 3; + else + dp = dp + (x++) * 2 - (y--) * 2 + 5; + + if (x2 < y2 + 1) { + if (dp2 < 0) + dp2 = dp2 + (x2++) * 2 + 3; + else + dp2 = dp2 + (x2++) * 2 - (y2--) * 2 + 5; + } + else { + x2++; + y2++; + } - uint8_t drawBit = 1 << (y & 7); + drawVerticalLine(x0 - x, y0 - y, y - y2 + 1); + drawHorizontalLine(x0 - y, y0 - x, y - y2 + 1); + drawVerticalLine(x0 + x, y0 - y, y - y2 + 1); + drawHorizontalLine(x0 + y2, y0 - x, y - y2 + 1); + drawVerticalLine(x0 - x, y0 + y2, y - y2 + 1); + drawHorizontalLine(x0 - y, y0 + x, y - y2 + 1); + drawVerticalLine(x0 + x, y0 + y2, y - y2 + 1); + drawHorizontalLine(x0 + y2, y0 + x, y - y2 + 1); + } while (x < y); + drawVerticalLine(x0, y0 - radius, radius - radius2 + 1); + drawVerticalLine(x0, y0 + radius2, radius - radius2 + 1); + drawHorizontalLine(x0 - radius, y0, radius - radius2 + 1); + drawHorizontalLine(x0 + radius2, y0, radius - radius2 + 1); + } + else { + do { + if (dp < 0) + dp = dp + (x++) * 2 + 3; + else + dp = dp + (x++) * 2 - (y--) * 2 + 5; + + if (x2 < y2 + 1) { + if (dp2 < 0) + dp2 = dp2 + (x2++) * 2 + 3; + else + dp2 = dp2 + (x2++) * 2 - (y2--) * 2 + 5; + } + else { + x2++; + y2++; + } - switch (color) { - case WHITE: while (length--) { - *bufferPtr++ |= drawBit; - }; break; - case BLACK: drawBit = ~drawBit; while (length--) { - *bufferPtr++ &= drawBit; - }; break; - case INVERSE: while (length--) { - *bufferPtr++ ^= drawBit; - }; break; + if (quads & B0010) { + drawVerticalLine(x0 - x, y0 - y, y - y2 + 1); + drawHorizontalLine(x0 - y, y0 - x, y - y2 + 1); + } + if (quads & B0001) { + drawVerticalLine(x0 + x, y0 - y, y - y2 + 1); + drawHorizontalLine(x0 + y2, y0 - x, y - y2 + 1); + } + if (quads & B0100) { + drawVerticalLine(x0 - x, y0 + y2, y - y2 + 1); + drawHorizontalLine(x0 - y, y0 + x, y - y2 + 1); + } + if (quads & B1000) { + drawVerticalLine(x0 + x, y0 + y2, y - y2 + 1); + drawHorizontalLine(x0 + y2, y0 + x, y - y2 + 1); + } + } while (x < y); + if (quads & B0011) { + drawVerticalLine(x0, y0 - radius, radius - radius2 + 1); + } + if (quads & B1100) { + drawVerticalLine(x0, y0 + radius2, radius - radius2 + 1); + } + if (quads & B0110) { + drawHorizontalLine(x0 - radius, y0, radius - radius2 + 1); + } + if (quads & B1001) { + drawHorizontalLine(x0 + radius2, y0, radius - radius2 + 1); + } } + + return quads; } void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { From 57ea43eed99c048c9956bea69d1910ebe2e2f2af Mon Sep 17 00:00:00 2001 From: NoobTracker <63962365+NoobTracker@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:50:30 +0200 Subject: [PATCH 2/5] Update OLEDDisplay.h --- src/OLEDDisplay.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/OLEDDisplay.h b/src/OLEDDisplay.h index 205dffc..0e89d67 100644 --- a/src/OLEDDisplay.h +++ b/src/OLEDDisplay.h @@ -200,13 +200,16 @@ class OLEDDisplay : public Stream { void fillRect(int16_t x, int16_t y, int16_t width, int16_t height); // Draw the border of a circle - void drawCircle(int16_t x, int16_t y, int16_t radius); + uint8_t drawCircle(int16_t x, int16_t y, uint16_t radius, uint8_t quads = B1111, bool improve = false); - // Draw all Quadrants specified in the quads bit mask - void drawCircleQuads(int16_t x0, int16_t y0, int16_t radius, uint8_t quads); + // Draw all Quadrants specified in the quads bit mask (backward compatibility) + void drawCircleQuads(int16_t x0, int16_t y0, uint16_t radius, uint8_t quads); // Fill circle - void fillCircle(int16_t x, int16_t y, int16_t radius); + uint8_t fillCircle(int16_t x, int16_t y, uint16_t radius, bool improve = false); + + // Fill ring + uint8_t fillRing(int16_t x0, int16_t y0, uint16_t radius, uint16_t radius2, uint8_t quads = B1111, bool improve = false); // Draw a line horizontally void drawHorizontalLine(int16_t x, int16_t y, int16_t length); From 7881d4f19628f2a0fb66201bcdfe528250f34d34 Mon Sep 17 00:00:00 2001 From: NoobTracker <63962365+NoobTracker@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:51:12 +0200 Subject: [PATCH 3/5] Add files via upload --- keywords.txt | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 keywords.txt diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..395a37c --- /dev/null +++ b/keywords.txt @@ -0,0 +1,95 @@ +INVERSE LITERAL1 + +TEXT_ALIGN_LEFT LITERAL1 +TEXT_ALIGN_RIGHT LITERAL1 +TEXT_ALIGN_CENTER LITERAL1 +TEXT_ALIGN_CENTER_BOTH LITERAL1 + +GEOMETRY_128_64 LITERAL1 +GEOMETRY_128_32 LITERAL1 +GEOMETRY_RAWMODE LITERAL1 + +ArialMT_Plain_10 LITERAL1 +ArialMT_Plain_16 LITERAL1 +ArialMT_Plain_24 LITERAL1 + +SLIDE_UP LITERAL1 +SLIDE_DOWN LITERAL1 +SLIDE_LEFT LITERAL1 +SLIDE_RIGHT LITERAL1 + +TOP LITERAL1 +RIGHT LITERAL1 +BOTTOM LITERAL1 +LEFT LITERAL1 + +LEFT_RIGHT LITERAL1 +RIGHT_LEFT LITERAL1 + +IN_TRANSITION LITERAL1 +FIXED LITERAL1 + + + + + +OLEDDisplay KEYWORD1 +OLEDDisplayUi KEYWORD1 + +SH1106Wire KEYWORD1 +SH1106Brzo KEYWORD1 +SH1106Spi KEYWORD1 + +SSD1306Wire KEYWORD1 +SSD1306Brzo KEYWORD1 +SSD1306I2C KEYWORD1 +SSD1306Spi KEYWORD1 + + + + + +allocateBuffer KEYWORD2 +init KEYWORD2 +resetDisplay KEYWORD2 +setColor KEYWORD2 +getColor KEYWORD2 +setPixel KEYWORD2 +setPixelColor KEYWORD2 +clearPixel KEYWORD2 +drawLine KEYWORD2 +drawRect KEYWORD2 +fillRect KEYWORD2 +drawCircle KEYWORD2 +drawCircleQuads KEYWORD2 +fillCircle KEYWORD2 +fillRing KEYWORD2 +drawHorizontalLine KEYWORD2 +drawVerticalLine KEYWORD2 +drawProgressBar KEYWORD2 +drawFastImage KEYWORD2 +drawXbm KEYWORD2 +drawIco16x16 KEYWORD2 +drawString KEYWORD2 +drawStringMaxWidth KEYWORD2 +getStringWidth KEYWORD2 +setTextAlignment KEYWORD2 +setFont KEYWORD2 +setFontTableLookupFunction KEYWORD2 +displayOn KEYWORD2 +displayOff KEYWORD2 +invertDisplay KEYWORD2 +normalDisplay KEYWORD2 +setContrast KEYWORD2 +setBrightness KEYWORD2 +resetOrientation KEYWORD2 +flipScreenVertically KEYWORD2 +mirrorScreen KEYWORD2 +display KEYWORD2 +setLogBuffer KEYWORD2 +drawLogBuffer KEYWORD2 +getWidth KEYWORD2 +getHeight KEYWORD2 + + + From 50cc47b13aeb35518db15fae248775f797f536f2 Mon Sep 17 00:00:00 2001 From: NoobTracker <63962365+NoobTracker@users.noreply.github.com> Date: Tue, 2 Jun 2020 19:52:02 +0200 Subject: [PATCH 4/5] Add files via upload --- examples/SSD1306RingDemo/SSD1306RingDemo.ino | 85 ++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 examples/SSD1306RingDemo/SSD1306RingDemo.ino diff --git a/examples/SSD1306RingDemo/SSD1306RingDemo.ino b/examples/SSD1306RingDemo/SSD1306RingDemo.ino new file mode 100644 index 0000000..e57fa29 --- /dev/null +++ b/examples/SSD1306RingDemo/SSD1306RingDemo.ino @@ -0,0 +1,85 @@ + /** + * The MIT License (MIT) + * + * Copyright (c) 2020 by NoobTracker + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * ThingPulse invests considerable time and money to develop these open source libraries. + * Please support us by buying our products (and not the clones) from + * https://thingpulse.com + * + */ + + // Include the correct display library + // For a connection via I2C using Wire include + #include // Only needed for Arduino 1.6.5 and earlier + #include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"` + // or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"` + // For a connection via I2C using brzo_i2c (must be installed) include + // #include // Only needed for Arduino 1.6.5 and earlier + // #include "SSD1306Brzo.h" + // #include "SH1106Brzo.h" + // For a connection via SPI include + // #include // Only needed for Arduino 1.6.5 and earlier + // #include "SSD1306Spi.h" + // #include "SH1106SPi.h" + + // Use the corresponding display class: + + // Initialize the OLED display using SPI + // D5 -> CLK + // D7 -> MOSI (DOUT) + // D0 -> RES + // D2 -> DC + // D8 -> CS + // SSD1306Spi display(D0, D2, D8); + // or + // SH1106Spi display(D0, D2); + + // Initialize the OLED display using brzo_i2c + // D3 -> SDA + // D5 -> SCL + // SSD1306Brzo display(0x3c, SDA, SCL); + // or + // SH1106Brzo display(0x3c, SDA, SCL); + + // Initialize the OLED display using Wire library + SSD1306Wire display(0x3c, SDA, SCL); + // SH1106 display(0x3c, SDA, SCL); + +void ring(byte quads, byte pos){ + float angle = (pos * PI * 2) / 256; + float angle2 = ((pos + 0x20) * PI * 2) / 256; + display.fillRing(display.getWidth() / 2, display.getHeight() / 2, abs(sin(angle) * 30), abs(sin(angle2) * 25), quads); +} + +void setup() { + display.init(); + display.flipScreenVertically(); + display.setColor(WHITE); +} +uint16_t pos = 0x100; +void loop() { + display.clear(); + ring(pos >> 8, pos & 0xFF); + pos++; + display.display(); + delay(30); +} From 39eaa8a5e7b4fdf3a6f9162a447475000456646d Mon Sep 17 00:00:00 2001 From: NoobTracker <63962365+NoobTracker@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:53:08 +0200 Subject: [PATCH 5/5] drawHorizontalLine was deleted! Really. I actually deleted this function when I just wanted to replace drawCircle, drawCircleQuads and fillCircle. Unfortunately, drawHorizontalLine was directly underneath, so I accidentally replaced this function. --- src/OLEDDisplay.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/OLEDDisplay.cpp b/src/OLEDDisplay.cpp index b088257..7d99b7b 100644 --- a/src/OLEDDisplay.cpp +++ b/src/OLEDDisplay.cpp @@ -440,6 +440,42 @@ uint8_t OLEDDisplay::fillRing(int16_t x0, int16_t y0, uint16_t radius, uint16_t return quads; } +void OLEDDisplay::drawHorizontalLine(int16_t x, int16_t y, int16_t length) { + if (y < 0 || y >= this->height()) { + return; + } + + if (x < 0) { + length += x; + x = 0; + } + + if ( (x + length) > this->width()) { + length = (this->width() - x); + } + + if (length <= 0) { + return; + } + + uint8_t * bufferPtr = buffer; + bufferPtr += (y >> 3) * this->width(); + bufferPtr += x; + + uint8_t drawBit = 1 << (y & 7); + + switch (color) { + case WHITE: while (length--) { + *bufferPtr++ |= drawBit; + }; break; + case BLACK: drawBit = ~drawBit; while (length--) { + *bufferPtr++ &= drawBit; + }; break; + case INVERSE: while (length--) { + *bufferPtr++ ^= drawBit; + }; break; + } +} void OLEDDisplay::drawVerticalLine(int16_t x, int16_t y, int16_t length) { if (x < 0 || x >= this->width()) return;