diff --git a/examples/scrolling/CMakeLists.txt b/examples/scrolling/CMakeLists.txt new file mode 100644 index 0000000..9dbbeb3 --- /dev/null +++ b/examples/scrolling/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.13) + +include(pico_sdk_import.cmake) + +project(scrolling_example) + +pico_sdk_init() + +add_subdirectory(pico-ssd1306) + +add_executable(scrolling_example + main.cpp) + +target_link_libraries(scrolling_example + hardware_i2c + pico_ssd1306) + + +pico_add_extra_outputs(scrolling_example) diff --git a/examples/scrolling/main.cpp b/examples/scrolling/main.cpp new file mode 100644 index 0000000..e476c9f --- /dev/null +++ b/examples/scrolling/main.cpp @@ -0,0 +1,43 @@ +#include "pico/stdlib.h" +#include "pico-ssd1306/ssd1306.h" +#include "pico-ssd1306/textRenderer/TextRenderer.h" +#include "hardware/i2c.h" + +// Use the namespace for convenience +using namespace pico_ssd1306; + +int main(){ + // Init i2c0 controller + i2c_init(i2c0, 1000000); + // Set up pins 12 and 13 + gpio_set_function(12, GPIO_FUNC_I2C); + gpio_set_function(13, GPIO_FUNC_I2C); + gpio_pull_up(12); + gpio_pull_up(13); + + // If you don't do anything before initializing a display pi pico is too fast and starts sending + // commands before the screen controller had time to set itself up, so we add an artificial delay for + // ssd1306 to set itself up + sleep_ms(250); + + // Create a new display object at address 0x3D and size of 128x64 + SSD1306 display = SSD1306(i2c0, 0x3D, Size::W128xH64); + + // Here we rotate the display by 180 degrees, so that it's not upside down from my perspective + // If your screen is upside down try setting it to 1 or 0 + display.setOrientation(0); + + drawText(&display, font_12x16, "Hello", 12, 0); + drawText(&display, font_12x16, "World!", 48, 16); + // Send buffer to the display + display.sendBuffer(); + + while (true) { + display.setHorizontalScroll(ScrollDirection::Left, true, 0, 7, 0x00); // scroll left + sleep_ms(6500); + display.setHorizontalScroll(ScrollDirection::Right, true, 0, 7, 0x00); // scroll right + sleep_ms(6500); + display.setHorizontalScroll(ScrollDirection::Left, false); // turn scrolling off + sleep_ms(5000); + } +} diff --git a/examples/scrolling/output.gif b/examples/scrolling/output.gif new file mode 100644 index 0000000..c771aa1 Binary files /dev/null and b/examples/scrolling/output.gif differ diff --git a/examples/scrolling/readme.md b/examples/scrolling/readme.md new file mode 100644 index 0000000..0803f5a --- /dev/null +++ b/examples/scrolling/readme.md @@ -0,0 +1,7 @@ +# This examples produces such a result + +![output](output.gif) + +## Notes + +Utilizes the hardware scrolling commands for SSD1306. See data sheet for more info. diff --git a/ssd1306.cpp b/ssd1306.cpp index 673b617..61ba002 100644 --- a/ssd1306.cpp +++ b/ssd1306.cpp @@ -20,42 +20,42 @@ namespace pico_ssd1306 { // this is a list of setup commands for the display uint8_t setup[] = { - SSD1306_DISPLAY_OFF, - SSD1306_LOWCOLUMN, - SSD1306_HIGHCOLUMN, - SSD1306_STARTLINE, + SSD1306_DISPLAY_OFF, + SSD1306_LOWCOLUMN, + SSD1306_HIGHCOLUMN, + SSD1306_STARTLINE, - SSD1306_MEMORYMODE, - SSD1306_MEMORYMODE_HORZONTAL, + SSD1306_MEMORYMODE, + SSD1306_MEMORYMODE_HORZONTAL, - SSD1306_CONTRAST, - 0xFF, + SSD1306_CONTRAST, + 0xFF, - SSD1306_INVERTED_OFF, + SSD1306_INVERTED_OFF, - SSD1306_MULTIPLEX, - 63, + SSD1306_MULTIPLEX, + 63, - SSD1306_DISPLAYOFFSET, - 0x00, + SSD1306_DISPLAYOFFSET, + 0x00, - SSD1306_DISPLAYCLOCKDIV, - 0x80, + SSD1306_DISPLAYCLOCKDIV, + 0x80, - SSD1306_PRECHARGE, - 0x22, + SSD1306_PRECHARGE, + 0x22, - SSD1306_COMPINS, - 0x12, + SSD1306_COMPINS, + 0x12, - SSD1306_VCOMDETECT, - 0x40, + SSD1306_VCOMDETECT, + 0x40, - SSD1306_CHARGEPUMP, - 0x14, + SSD1306_CHARGEPUMP, + 0x14, - SSD1306_DISPLAYALL_ON_RESUME, - SSD1306_DISPLAY_ON + SSD1306_DISPLAYALL_ON_RESUME, + SSD1306_DISPLAY_ON }; // send each one of the setup commands @@ -166,7 +166,6 @@ namespace pico_ssd1306 { i2c_write_blocking(this->i2CInst, this->address, data, 2, false); } - void SSD1306::setContrast(unsigned char contrast) { this->cmd(SSD1306_CONTRAST); this->cmd(contrast); @@ -184,4 +183,26 @@ namespace pico_ssd1306 { this->cmd(SSD1306_DISPLAY_ON); } + bool SSD1306::setHorizontalScroll(ScrollDirection scrollDirection, bool shouldScroll, uint8_t startPage, uint8_t endPage, uint8_t timeInterval) { + uint8_t scrollCommand = (scrollDirection == ScrollDirection::Left) ? SSD1306_HORIZ_SCROLL_LEFT : SSD1306_HORIZ_SCROLL_RIGHT; + + if (startPage > 7 || endPage > 7 || endPage < startPage || timeInterval > 0x07) return false; + + uint8_t commands[] = { + scrollCommand, + 0x00, // dummy byte + startPage, // start page 0 + timeInterval, // time interval + endPage, // end page + 0x00, // dummy byte + 0xFF, // dummy byte + static_cast(SSD1306_SET_SCROLL | (shouldScroll ? 1 : 0)) // Start/stop scrolling + }; + + for (uint8_t &command: commands) { + this->cmd(command); + } + + return true; + } } diff --git a/ssd1306.h b/ssd1306.h index b97b910..4c42aa5 100644 --- a/ssd1306.h +++ b/ssd1306.h @@ -37,6 +37,9 @@ namespace pico_ssd1306 { SSD1306_CHARGEPUMP = 0x8D, SSD1306_EXTERNALVCC = 0x1, SSD1306_SWITCHCAPVCC = 0x2, + SSD1306_HORIZ_SCROLL_RIGHT = 0x26, + SSD1306_HORIZ_SCROLL_LEFT = 0x27, + SSD1306_SET_SCROLL = 0x2E }; /// \enum pico_ssd1306::Size @@ -48,7 +51,7 @@ namespace pico_ssd1306 { }; /// \enum pico_ssd1306::WriteMode - enum class WriteMode : const unsigned char{ + enum class WriteMode : const unsigned char { /// sets pixel on regardless of its state ADD = 0, /// sets pixel off regardless of its state @@ -57,6 +60,12 @@ namespace pico_ssd1306 { INVERT = 2, }; + /// \enum pico_ssd1306::ScrollDirection + enum class ScrollDirection : const unsigned char { + Left, + Right + }; + /// \class SSD1306 ssd1306.h "pico-ssd1306/ssd1306.h" /// \brief SSD1306 class represents i2c connection to display class SSD1306 { @@ -127,8 +136,17 @@ namespace pico_ssd1306 { /// \brief Turns display on void turnOn(); - }; + /// \brief Enables or disables scrolling + /// \param scrollDirection - direction of scrolling. Left or right + /// \param shouldScroll - true to enable scrolling, false to disable scrolling + /// \param startPage - page to start scrolling from. Valid values are 0 to 7 + /// \param endPage - page to end scrolling at. Valid values are 0 to 7 and must be greater than or equal to startPage + /// \param timeInterval - time interval between each scroll step. Accepted values 0x00 to 0x07 + /// \return true if parameters are valid and scrolling was set, false if parameters were invalid + bool setHorizontalScroll(ScrollDirection scrollDirection, bool shouldScroll = true, uint8_t startPage = 0, + uint8_t endPage = 7,uint8_t timeInterval = 0x00); + }; } -#endif //SSD1306_SSD1306_H \ No newline at end of file +#endif //SSD1306_SSD1306_H