├── .gitignore ├── historical ├── digistump │ ├── TODO.txt │ ├── RESEARCH.txt │ ├── README.txt │ └── CHANGES.txt └── tinusaur │ ├── LICENSE.txt │ ├── README.txt │ └── RESEARCH.txt ├── src ├── Tiny4kOLEDprintless.h ├── Tiny4kOLED.h ├── font6x8digits.h ├── Tiny4kOLED_Wire.h ├── Tiny4kOLED_tiny-i2c.h ├── font8x16digits.h ├── Tiny4kOLED_TinyWireM.h ├── Tiny4kOLED_bitbang.h ├── font6x8caps.h ├── font6x8.h ├── font6x8p.h ├── font8x16caps.h ├── font8x16capsp.h ├── font8x16.h ├── font8x16p.h └── Tiny4kOLED_common.h ├── library.properties ├── examples ├── ResetToDefaults │ └── ResetToDefaults.ino ├── I2CSpeedTest │ └── I2CSpeedTest.ino ├── BatteryMonitor │ ├── eeprom_contents.h │ └── BatteryMonitor.ino ├── TemperatureMonitor │ ├── eeprom_contents.h │ └── TemperatureMonitor.ino ├── Devices │ ├── 64x32 │ │ └── 64x32.ino │ ├── 64x48 │ │ └── 64x48.ino │ ├── 72x40 │ │ └── 72x40.ino │ ├── 128x32 │ │ └── 128x32.ino │ ├── 128x64 │ │ └── 128x64.ino │ └── Identify │ │ └── Identify.ino ├── CustomChineseFont │ ├── CustomChineseFont.ino │ └── font16x16cn.h ├── DoubleSizeText │ └── DoubleSizeText.ino ├── DoubleSizeSmoothText │ └── DoubleSizeSmoothText.ino ├── InverseText │ └── InverseText.ino ├── Bitmap │ ├── Bitmap.ino │ └── SolomonSystech.h ├── PacMan │ ├── PacManMap.h │ └── Graphics.h ├── DatacuteBoxyFont │ ├── boxyfont.h │ └── DatacuteBoxyFont.ino ├── ScrollingExample │ └── ScrollingExample.ino ├── DoubleBufferedMillis │ └── DoubleBufferedMillis.ino ├── DoubleBufferedDisplay │ └── DoubleBufferedDisplay.ino ├── DoubleBufferedMillis128x64 │ └── DoubleBufferedMillis128x64.ino └── ScrollingText │ └── ScrollingText.ino ├── LICENSE ├── keywords.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.development 2 | /.vscode 3 | -------------------------------------------------------------------------------- /historical/digistump/TODO.txt: -------------------------------------------------------------------------------- 1 | TODO 2 | 3 | 4 | - Implement power saving mode 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Tiny4kOLEDprintless.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | #define TINY4KOLED_NO_PRINT 9 | #include "Tiny4kOLED.h" 10 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=Tiny4kOLED 2 | version=2.3.0 3 | author=Stephen Denne 4 | maintainer=Stephen Denne 5 | sentence=This is a library for an ATTiny85 to use an I2C SSD1306 OLED. It supports double buffering on 128x32 pixel OLED. 6 | paragraph=I2C only (no SPI support). Supports all SSD1306 features, all resolutions. Very memory efficient. UTF-8/Unicode. Proportional fonts. Double buffering. 7 | category=Display 8 | url=https://github.com/datacute/Tiny4kOLED 9 | architectures=* 10 | includes=Tiny4kOLED.h -------------------------------------------------------------------------------- /src/Tiny4kOLED.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | #ifndef TINY4KOLED_H 9 | #define TINY4KOLED_H 10 | 11 | #if defined(TwoWire_h) || defined (USIWire_h) 12 | #include "Tiny4kOLED_Wire.h" 13 | #elif defined(TinyWireM_h) 14 | #include "Tiny4kOLED_TinyWireM.h" 15 | #elif defined(TinyI2CMaster_h) 16 | #include "Tiny4kOLED_tiny-i2c.h" 17 | #else 18 | #include 19 | #include "Tiny4kOLED_Wire.h" 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /historical/digistump/RESEARCH.txt: -------------------------------------------------------------------------------- 1 | RESEARCH 2 | 3 | 4 | SSD1306 5 | http://www.solomon-systech.com/en/product/display-ic/oled-driver-controller/ssd1306/ 6 | SSD1306 is a single-chip CMOS OLED/PLED driver with controller for organic / polymer light emitting diode dot-matrix graphic display system. It consists of 128 segments and 64 commons. This IC is designed for Common Cathode type OLED panel. 7 | 8 | 9 | ---- SSD1306 Datasheets ---- 10 | 11 | https://www.adafruit.com/datasheets/SSD1306.pdf 12 | 13 | http://www.crystalfontz.com/controllers/Solomon_Systech_SSD1306_v1.1_April_2008.pdf 14 | 15 | 16 | ---- Other SSD1306 Libraries ---- 17 | 18 | 19 | 20 | ---- Projects ---- 21 | 22 | 23 | 24 | ---- Other References ---- 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /historical/digistump/README.txt: -------------------------------------------------------------------------------- 1 | Overhauled to support Wire library, print library, and generally be more "Arduino friendly" - renamed DigiOLED to avoid confussion - 1/14/2015 by Erik Kettenburg/Digistump 2 | 3 | Ported to Arduino CPP and working on DigiStump Pro 1/11/15 by defragster 4 | 5 | SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 6 | 7 | SSD1306xLED is a C library for working with the SSD1306 display driver to control dot matrix OLED/PLED 128x64 displays. It is intended to be used with the Tinusaur board but should also work with any other board based on ATtiny85 or similar microcontroller. 8 | 9 | SSD1306xLED is written in plain C and does not require any additional libraries to function except those that come with the WinAVR SDK. 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/ResetToDefaults/ResetToDefaults.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * The SSD1306 remembers many of its settings even when powered off. 8 | * After experimenting with various features, 9 | * it can be useful to reset all the settings to the default values, 10 | * which can be done by uploading and running this example. 11 | * 12 | */ 13 | 14 | #include 15 | 16 | void setup() { 17 | oled.begin(128, 64, sizeof(tiny4koled_init_defaults), tiny4koled_init_defaults); 18 | oled.enableChargePump(); // The default is off, but most boards need this. 19 | oled.setRotation(1); // The default orientation is not the most commonly used. 20 | oled.clear(); 21 | oled.setFont(FONT8X16CAPSP); 22 | oled.setCursor(0, 0); 23 | oled.print("DEFAULT SETTINGS"); 24 | oled.on(); 25 | } 26 | 27 | void loop() { 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Stephen Denne 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /historical/tinusaur/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /examples/I2CSpeedTest/I2CSpeedTest.ino: -------------------------------------------------------------------------------- 1 | // Timing and space used measured with SpenceKonde's ATTinyCore 2 | // and an ATTiny85 at 8MHz 3 | 4 | // Without any other includes, this library uses the standard Wire library. 5 | // See timing below for the Wire-specific include 6 | #include 7 | 8 | // 4264 bytes program, 101 bytes dynamic memory 9 | // 348ms to fill the screen 10 | //#include 11 | 12 | // 3920 bytes program, 80 bytes dynamic memory 13 | // 142ms to fill the screen 14 | //#include 15 | 16 | // 3672 bytes program, 60 bytes dynamic memory 17 | // 56ms to fill the screen 18 | //#include 19 | 20 | // 3622 bytes program, 60 bytes dynamic memory 21 | // 45ms to fill the screen 22 | //#include 23 | 24 | unsigned long lastTime = 0L; 25 | 26 | void setup() { 27 | // Test by writing to the entire memory space of the SSD1306 28 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 29 | oled.clear(); 30 | oled.setFont(FONT8X16); 31 | oled.on(); 32 | lastTime = millis(); 33 | } 34 | 35 | uint8_t b = 0; 36 | void loop() { 37 | oled.fill(b); 38 | if (b==255) { 39 | unsigned long thisTime = millis(); 40 | oled.setCursor(0,0); 41 | oled.println((thisTime-lastTime)>>8, DEC); 42 | delay(4000); 43 | lastTime = millis(); 44 | } 45 | b++; 46 | } 47 | -------------------------------------------------------------------------------- /src/font6x8digits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 6x8 font */ 25 | const uint8_t ssd1306xled_font6x8_digits [] PROGMEM = { 26 | 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 27 | 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 28 | 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 29 | 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 30 | 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 31 | 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 32 | 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 33 | 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 34 | 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 35 | 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 36 | }; 37 | 38 | // ---------------------------------------------------------------------------- 39 | 40 | const DCfont TinyOLED4kfont6x8Digits = { 41 | (uint8_t *)ssd1306xled_font6x8_digits, 42 | 6, // character width in pixels 43 | 1, // character height in pages (8 pixels) 44 | 48,57, // ASCII extents 45 | 0,0,0 // Unused for fixed width fonts 46 | }; 47 | 48 | // for backwards compatibility 49 | #define FONT6X8DIGITS (&TinyOLED4kfont6x8Digits) 50 | -------------------------------------------------------------------------------- /examples/BatteryMonitor/eeprom_contents.h: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM CONTENTS 3 | 4 | Location (HEX) 5 | 000: 4 bytes - magic EEPROM content identifier #1D424154 (ID BAT) 6 | 004: 1 byte - next location to write data to. 7 | 005: 1 byte - current contrast - hold button down to cycle (todo) 8 | 006: 1 byte - used to adjust freq/turn off, 0 means 1 reading per hour (todo) 9 | 007: 1 byte - graph scale and type, 0 means graph 0V to 6V (todo) 10 | 008: 120 bytes of readings in a circular buffer. 11 | 12 | Since the readings are being displayed in a screen 13 | with maximum resolution of 128x64 14 | and maximum voltage is 6V 15 | Each reading is converted to a value from 0 to 60 16 | where 60 means 6 volts. 17 | */ 18 | 19 | /* 20 | * The Magic Number 21 | * 22 | * If this does not match the first four bytes of the EEPROM, 23 | * then the EEPROM does not contain battery monitor information. 24 | * The EEPROM will be cleared so that the graph of historical data 25 | * is not showing garbage. 26 | */ 27 | #define BATTERY_MAGIC 0x1D424154 28 | #define BATTERY_MAGIC0 0x1D 29 | #define BATTERY_MAGIC1 0x42 30 | #define BATTERY_MAGIC2 0x41 31 | #define BATTERY_MAGIC3 0x54 32 | 33 | #define BATTERY_MAGIC_ADDRESS 0 34 | #define BATTERY_CURRENT_ADDRESS 4 35 | #define BATTERY_CONTRAST_ADDRESS 5 36 | #define BATTERY_FREQUENCY_ADDRESS 6 37 | #define BATTERY_GRAPH_TYPE_ADDRESS 7 38 | #define BATTERY_READINGS_ADDRESS 8 39 | 40 | #define BATTERY_DEFAULT_CONTRAST 0x10 41 | #define BATTERY_DEFAULT_FREQUENCY 0x00 42 | #define BATTERY_DEFAULT_GRAPH 0x00 43 | 44 | const byte header [] PROGMEM = { 45 | BATTERY_MAGIC0, BATTERY_MAGIC1, BATTERY_MAGIC2, BATTERY_MAGIC3, 46 | BATTERY_READINGS_ADDRESS, // current reading 47 | BATTERY_DEFAULT_CONTRAST, // contrast 48 | BATTERY_DEFAULT_FREQUENCY, // reading frequency 49 | BATTERY_DEFAULT_GRAPH // graph scale and type 50 | }; 51 | -------------------------------------------------------------------------------- /src/Tiny4kOLED_Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | #ifndef TINY4KOLED_WIRE_H 9 | #define TINY4KOLED_WIRE_H 10 | 11 | #include 12 | #include "Tiny4kOLED_common.h" 13 | 14 | #ifndef DATACUTE_I2C_WIRE 15 | #define DATACUTE_I2C_WIRE 16 | 17 | static bool datacute_write_wire(uint8_t byte) { 18 | return Wire.write(byte); 19 | } 20 | 21 | static uint8_t datacute_read_wire(void) __attribute__((unused)); 22 | static uint8_t datacute_read_wire(void) { 23 | return Wire.read(); 24 | } 25 | 26 | static void datacute_end_read_wire(void) __attribute__((unused)); 27 | static void datacute_end_read_wire(void) {} 28 | 29 | static uint8_t datacute_endTransmission_wire(void) { 30 | return Wire.endTransmission(); 31 | } 32 | 33 | #endif 34 | 35 | static bool tiny4koled_beginTransmission_wire(void) { 36 | Wire.beginTransmission(SSD1306); 37 | return true; 38 | } 39 | 40 | #ifndef TINY4KOLED_QUICK_BEGIN 41 | inline static bool tiny4koled_check_wire(void) { 42 | const uint8_t noError = 0x00; 43 | tiny4koled_beginTransmission_wire(); 44 | return (datacute_endTransmission_wire()==noError); 45 | } 46 | #endif 47 | 48 | static void tiny4koled_begin_wire(void) { 49 | Wire.begin(); 50 | #ifndef TINY4KOLED_QUICK_BEGIN 51 | while (!tiny4koled_check_wire()) { 52 | delay(10); 53 | } 54 | #endif 55 | } 56 | 57 | #ifndef TINY4KOLED_NO_PRINT 58 | SSD1306PrintDevice oled(&tiny4koled_begin_wire, &tiny4koled_beginTransmission_wire, &datacute_write_wire, &datacute_endTransmission_wire); 59 | #else 60 | SSD1306Device oled(&tiny4koled_begin_wire, &tiny4koled_beginTransmission_wire, &datacute_write_wire, &datacute_endTransmission_wire); 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/Tiny4kOLED_tiny-i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This file adds support for the I2C implementation from https://github.com/technoblogy/tiny-i2c 8 | * 9 | */ 10 | #ifndef TINY4KOLED_TINYI2C_H 11 | #define TINY4KOLED_TINYI2C_H 12 | 13 | #include 14 | #include "Tiny4kOLED_common.h" 15 | 16 | #ifndef DATACUTE_I2C_TINYI2C 17 | #define DATACUTE_I2C_TINYI2C 18 | 19 | static bool datacute_write_tinyi2c(uint8_t byte) { 20 | return TinyI2C.write(byte); 21 | } 22 | 23 | static uint8_t datacute_read_tinyi2c(void) __attribute__((unused)); 24 | static uint8_t datacute_read_tinyi2c(void) { 25 | return TinyI2C.read(); 26 | } 27 | 28 | static void datacute_end_read_tinyi2c(void) __attribute__((unused)); 29 | static void datacute_end_read_tinyi2c(void) { 30 | TinyI2C.stop(); 31 | } 32 | 33 | static uint8_t datacute_endTransmission_tinyi2c(void) { 34 | TinyI2C.stop(); 35 | return 0; 36 | } 37 | 38 | #endif 39 | 40 | static bool tiny4koled_beginTransmission_tinyi2c(void) { 41 | return TinyI2C.start(SSD1306, 0); 42 | } 43 | 44 | static void tiny4koled_begin_tinyi2c(void) { 45 | TinyI2C.init(); 46 | #ifndef TINY4KOLED_QUICK_BEGIN 47 | while (!tiny4koled_beginTransmission_tinyi2c()) { 48 | delay(10); 49 | } 50 | datacute_endTransmission_tinyi2c(); 51 | #endif 52 | } 53 | 54 | #ifndef TINY4KOLED_NO_PRINT 55 | SSD1306PrintDevice oled(&tiny4koled_begin_tinyi2c, &tiny4koled_beginTransmission_tinyi2c, &datacute_write_tinyi2c, &datacute_endTransmission_tinyi2c); 56 | #else 57 | SSD1306Device oled(&tiny4koled_begin_tinyi2c, &tiny4koled_beginTransmission_tinyi2c, &datacute_write_tinyi2c, &datacute_endTransmission_tinyi2c); 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /examples/TemperatureMonitor/eeprom_contents.h: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM CONTENTS 3 | 4 | Location (HEX) 5 | 000: 4 bytes - magic EEPROM content identifier #1D544D50 (ID TMP) 6 | 004: 1 byte - next location to write data to. 7 | 005: 1 byte - current contrast - hold button down to cycle (todo) 8 | 006: 1 byte - used to adjust freq/turn off, 0 means 1 reading per hour (todo) 9 | 007: 1 byte - graph scale and type, 0 means graph -10 to 50 deg C (todo) 10 | 008: 120 bytes of readings in a circular buffer. 11 | 12 | Since the readings are being displayed in a screen 13 | with maximum resolution of 128x64 14 | Each reading is converted to a value from -10 to 50 15 | where 0 means -10 degrees C. 16 | */ 17 | 18 | /* 19 | * The Magic Number 20 | * 21 | * If this does not match the first four bytes of the EEPROM, 22 | * then the EEPROM does not contain battery monitor information. 23 | * The EEPROM will be cleared so that the graph of historical data 24 | * is not showing garbage. 25 | */ 26 | #define TEMPERATURE_MAGIC 0x1D544D50 27 | #define TEMPERATURE_MAGIC0 0x1D 28 | #define TEMPERATURE_MAGIC1 0x54 29 | #define TEMPERATURE_MAGIC2 0x4D 30 | #define TEMPERATURE_MAGIC3 0x50 31 | 32 | #define TEMPERATURE_MAGIC_ADDRESS 0 33 | #define TEMPERATURE_CURRENT_ADDRESS 4 34 | #define TEMPERATURE_CONTRAST_ADDRESS 5 35 | #define TEMPERATURE_FREQUENCY_ADDRESS 6 36 | #define TEMPERATURE_GRAPH_TYPE_ADDRESS 7 37 | #define TEMPERATURE_READINGS_ADDRESS 8 38 | 39 | #define TEMPERATURE_DEFAULT_CONTRAST 0x10 40 | #define TEMPERATURE_DEFAULT_FREQUENCY 0x00 41 | #define TEMPERATURE_DEFAULT_GRAPH 0x00 42 | 43 | const byte header [] PROGMEM = { 44 | TEMPERATURE_MAGIC0, TEMPERATURE_MAGIC1, TEMPERATURE_MAGIC2, TEMPERATURE_MAGIC3, 45 | TEMPERATURE_READINGS_ADDRESS, // current reading 46 | TEMPERATURE_DEFAULT_CONTRAST, // contrast 47 | TEMPERATURE_DEFAULT_FREQUENCY, // reading frequency 48 | TEMPERATURE_DEFAULT_GRAPH // graph scale and type 49 | }; 50 | -------------------------------------------------------------------------------- /historical/digistump/CHANGES.txt: -------------------------------------------------------------------------------- 1 | CHANGES 2 | 3 | 4 | 2015-01-10 (nb) 5 | 6 | Fixed and improved initialization. New and improved printing of text. Updated texts. 7 | 8 | - Fixed initialization commands. 9 | - Implemented ssd1306_init more efficiently. 10 | - New functions ssd1306_send_command_start, ssd1306_send_command_stop. 11 | - Improved ssd1306_setpos, more efficient. 12 | - Reimplemented function ssd1306_char_f6x8 as improved ssd1306_char_font6x8 printing single characters only, added new ssd1306_string_font6x8 for printing strings. 13 | - The font8x16 functions and data moved to another file until properly implemented. 14 | - Added to the Make file ssd1306xled8x16 file. 15 | - Updated testing text displayed on the screen. 16 | 17 | 18 | 2015-01-10 (nb) 19 | 20 | Changed default pins for display, now PB0=SCL and PB1=SDA. Source code reformatting, improvements, edited comments. 21 | 22 | - Changed default pins for connecting to the display for consistency with the built-in TWI interface, they are now PB0=SCL and PB1=SDA. 23 | - Source code, removed redundant initializations of variables. 24 | - Source code reformatting, edited comments. 25 | 26 | 27 | 2015-01-10 (nb) 28 | 29 | Fixed some warnings, variables renamed. The font16x16/Chinese stuff moved to other folders. 30 | 31 | - Font variable ssd1306xled_font8X16 renamed to ssd1306xled_font8x16 for consistency. TODO: rename "ssd1306xled_font8x16" file as well. 32 | - Fixed ssd1306_draw_bmp prototype: added "const" to bitmap so it wont't generate warning. 33 | - Files related to font 16x16 (Chinese) moved to different folders: font16x16cn.h. 34 | - Functions and other code related to font 16x16 (Chinese) moved to different folders. 35 | - Source code reformatting, edited comments. 36 | 37 | 38 | 2014-10-26 (gs) 39 | 40 | Make project compile on gcc-avr - turn static images to consts, and rename include of font16x16cn.h 41 | 42 | 43 | 2014-08-13 (nb) 44 | 45 | More files added to the repository. 46 | 47 | 48 | 2014-08-11 (nb) 49 | 50 | Files added to the repository. 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/font8x16digits.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 8x16 font */ 25 | const uint8_t ssd1306xled_font8x16_digits [] PROGMEM = { 26 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, // 0 27 | 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // 1 28 | 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, // 2 29 | 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, // 3 30 | 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, // 4 31 | 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, // 5 32 | 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, // 6 33 | 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, // 7 34 | 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, // 8 35 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00 // 9 36 | }; 37 | 38 | // ---------------------------------------------------------------------------- 39 | 40 | const DCfont TinyOLED4kfont8x16Digits = { 41 | (uint8_t *)ssd1306xled_font8x16_digits, 42 | 8, // character width in pixels 43 | 2, // character height in pages (8 pixels) 44 | 48,57, // ASCII extents 45 | 0,0,0 // Unused for fixed width fonts 46 | }; 47 | 48 | // for backwards compatibility 49 | #define FONT8X16DIGITS (&TinyOLED4kfont8x16Digits) 50 | -------------------------------------------------------------------------------- /historical/tinusaur/README.txt: -------------------------------------------------------------------------------- 1 | SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 2 | 3 | ----------------------------------------------------------------------------------- 4 | Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved. 5 | Distributed as open source software under MIT License, see LICENSE.txt file. 6 | Please, as a favor, retain the link http://tinusaur.org to The Tinusaur Project. 7 | ----------------------------------------------------------------------------------- 8 | 9 | SSD1306xLED is a C library for working with the SSD1306 display driver to control dot matrix OLED/PLED 128x64 displays. It is intended to be used with the Tinusaur board but should also work with any other board based on ATtiny85 or similar microcontroller. 10 | 11 | The SSD1306xLED library is written in plain C and does not require any additional libraries to function except those that come with the SDK. 12 | 13 | This library has support for and tested work with the 8 MHz CPU clock mode. 14 | 15 | Modules, folders and files Structure: 16 | 17 | - ssd1306xled - the SSD1306xLED library 18 | - font6x8.h - small 6x8 font 19 | - font8x16.h - large 8x16 font 20 | - ssd1306xled.c - library implementation 21 | - ssd1306xled.h - library headers 22 | - ssd1306xled8x16.c - large font 8x16 implementation 23 | - ssd1306xled8x16.h - large font 8x16 headers 24 | - ssd1306xled_cn - additional functions for handling some Chinese characters (currently does not work) 25 | - ssd1306xled_test - simple testing program for the library 26 | - img0_128x64c1.h - sample bitmap image 128x64 27 | - img1_128x64c1.h - sample bitmap image 128x64 28 | - main.c - sample code using the library 29 | - ssd1306xled_test_cn - test for Chinese functions (currently does not work) 30 | 31 | 32 | ==== Links ==== 33 | 34 | Official Tinusaur Project website: http://tinusaur.org 35 | Project SSD1306xLED page: http://tinusaur.org/projects/ssd1306xled/ 36 | Project SSD1306xLED source code: https://bitbucket.org/tinusaur/ssd1306xled 37 | 38 | Twitter: https://twitter.com/tinusaur 39 | Facebook: https://www.facebook.com/tinusaur 40 | 41 | -------------------------------------------------------------------------------- /src/Tiny4kOLED_TinyWireM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This file adds support for the I2C implementation from https://github.com/adafruit/TinyWireM 8 | * Adafruit's version has a buffer overrun bugfix. 9 | * The bug resulted in the appearance of extra dots onscreen. 10 | */ 11 | #ifndef TINY4KOLED_TINYWIREM_H 12 | #define TINY4KOLED_TINYWIREM_H 13 | 14 | #include 15 | #include "Tiny4kOLED_common.h" 16 | 17 | #ifndef DATACUTE_I2C_TINYWIREM 18 | #define DATACUTE_I2C_TINYWIREM 19 | 20 | static bool datacute_write_tinywirem(uint8_t byte) { 21 | return TinyWireM.write(byte); 22 | } 23 | 24 | static uint8_t datacute_read_tinywirem(void) __attribute__((unused)); 25 | static uint8_t datacute_read_tinywirem(void) { 26 | return TinyWireM.read(); 27 | } 28 | 29 | static void datacute_end_read_tinywirem(void) __attribute__((unused)); 30 | static void datacute_end_read_tinywirem(void) {} 31 | 32 | static uint8_t datacute_endTransmission_tinywirem(void) { 33 | return TinyWireM.endTransmission(); 34 | } 35 | 36 | #endif 37 | 38 | static bool tiny4koled_beginTransmission_tinywirem(void) { 39 | TinyWireM.beginTransmission(SSD1306); 40 | return true; 41 | } 42 | 43 | #ifndef TINY4KOLED_QUICK_BEGIN 44 | static bool tiny4koled_check_tinywirem(void) { 45 | const uint8_t noError = 0x00; 46 | tiny4koled_beginTransmission_tinywirem(); 47 | return (datacute_endTransmission_tinywirem()==noError); 48 | } 49 | #endif 50 | 51 | static void tiny4koled_begin_tinywirem(void) { 52 | TinyWireM.begin(); 53 | #ifndef TINY4KOLED_QUICK_BEGIN 54 | while (!tiny4koled_check_tinywirem()) { 55 | delay(10); 56 | } 57 | #endif 58 | } 59 | 60 | #ifndef TINY4KOLED_NO_PRINT 61 | SSD1306PrintDevice oled(&tiny4koled_begin_tinywirem, &tiny4koled_beginTransmission_tinywirem, &datacute_write_tinywirem, &datacute_endTransmission_tinywirem); 62 | #else 63 | SSD1306Device oled(&tiny4koled_begin_tinywirem, &tiny4koled_beginTransmission_tinywirem, &datacute_write_tinywirem, &datacute_endTransmission_tinywirem); 64 | #endif 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /historical/tinusaur/RESEARCH.txt: -------------------------------------------------------------------------------- 1 | RESEARCH 2 | 3 | 4 | SSD1306 5 | http://www.solomon-systech.com/en/product/display-ic/oled-driver-controller/ssd1306/ 6 | 128 x 64, Dot Matrix OLED/PLED Segment/Common Driver with Controller 7 | 8 | SSD1306 is a single-chip CMOS OLED/PLED driver with controller for organic / polymer light emitting diode dot-matrix graphic display system. It consists of 128 segments and 64 commons. This IC is designed for Common Cathode type OLED panel. 9 | 10 | The SSD1306 embeds with contrast control, display RAM and oscillator, which reduces the number of external components and power consumption. It has 256-step brightness control. Data/Commands are sent from general MCU through the hardware selectable 6800/8000 series compatible Parallel Interface, I2C interface or Serial Peripheral Interface. It is suitable for many compact portable applications, such as mobile phone sub-display, MP3 player and calculator, etc. 11 | 12 | ---- SSD1306 Datasheets ---- 13 | 14 | https://www.adafruit.com/datasheets/SSD1306.pdf 15 | 16 | http://www.crystalfontz.com/controllers/Solomon_Systech_SSD1306_v1.1_April_2008.pdf 17 | 18 | 19 | ---- Products ---- 20 | 21 | 128x64 OLED 22 | http://www.adafruit.com/products/326 23 | Monochrome 0.96 128x64 OLED graphic display ID: 326 - $19.50 : Adafruit Industries, Unique & fun DIY electronics and kits 24 | 25 | 26 | ---- Tutorials ---- 27 | 28 | Monochrome OLED Breakouts 29 | https://learn.adafruit.com/monochrome-oled-breakouts 30 | This is a quick tutorial for our 128x64 and 128x32 pixel monochrome OLED displays. These displays are small, only about 1" diagonal, but very readable due to the high contrast of an OLED display. Each OLED display is made of 128x64 or 128x32 individual white OLEDs, each one is turned on or off by the controller chip. Because the display makes its own light, no backlight is required. This reduces the power required to run the OLED and is why the display has such high contrast; we really like this miniature display for its crispness! 31 | 32 | 33 | ---- SSD1306 Libraries ---- 34 | 35 | Adafruit_SSD1306 36 | https://github.com/adafruit/Adafruit_SSD1306 37 | This is a library for our Monochrome OLEDs based on SSD1306 drivers 38 | Requires: Adafruit-GFX-Library 39 | 40 | 41 | ---- Projects ---- 42 | 43 | 44 | 45 | ---- Other References ---- 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/Devices/64x32/64x32.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows a full screen rectangle, 8 | * writes the rectangle size inside the rectangle, 9 | * and scrolls the size off the screen. 10 | * 11 | */ 12 | 13 | #include 14 | 15 | uint8_t width = 64; 16 | uint8_t height = 32; 17 | 18 | void setup() { 19 | oled.begin(width, height, sizeof(tiny4koled_init_64x32br), tiny4koled_init_64x32br); 20 | oled.setFont(FONT8X16); 21 | drawScreen(); 22 | oled.on(); 23 | } 24 | 25 | void loop() { 26 | scrollScreen(); 27 | } 28 | 29 | void drawScreen() { 30 | // Set entire memory to hatched - if you see any of this hatching, then the display is not initialised correctly. 31 | for (uint8_t y = 0; y < 8; y++) { 32 | oled.setCursor(0, y); 33 | oled.startData(); 34 | for (uint8_t x=0; x<128; x += 2) { 35 | oled.sendData(0b10101010); 36 | oled.sendData(0b01010101); 37 | } 38 | oled.endData(); 39 | } 40 | 41 | oled.setCursor(0, 0); 42 | oled.startData(); 43 | oled.sendData(0b11111111); 44 | oled.repeatData(0b00000001, width - 2); 45 | oled.sendData(0b11111111); 46 | oled.endData(); 47 | 48 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 49 | oled.setCursor(0, y); 50 | oled.startData(); 51 | oled.sendData(0b11111111); 52 | oled.repeatData(0b00000000, width - 2); 53 | oled.sendData(0b11111111); 54 | oled.endData(); 55 | } 56 | 57 | oled.setCursor(0, (height - 8) / 8); 58 | oled.startData(); 59 | oled.sendData(0b11111111); 60 | oled.repeatData(0b10000000, width - 2); 61 | oled.sendData(0b11111111); 62 | oled.endData(); 63 | 64 | oled.setCursor(8, 1); 65 | oled.print(width); 66 | oled.print('x'); 67 | oled.print(height); 68 | } 69 | 70 | void scrollScreen() { 71 | uint8_t startScrollPage = 1; 72 | uint8_t endScrollPage = 2; 73 | uint8_t startScrollColumn = 8; 74 | uint8_t endScrollColumn = startScrollColumn + width - 16; 75 | for (uint8_t x = 0; x < width - 16; x++) 76 | { 77 | delay(50); 78 | oled.scrollContentRight(startScrollPage, endScrollPage, startScrollColumn, endScrollColumn); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/Devices/64x48/64x48.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows a full screen rectangle, 8 | * writes the rectangle size inside the rectangle, 9 | * and scrolls the size off the screen. 10 | * 11 | */ 12 | 13 | #include 14 | 15 | uint8_t width = 64; 16 | uint8_t height = 48; 17 | 18 | void setup() { 19 | oled.begin(width, height, sizeof(tiny4koled_init_64x48br), tiny4koled_init_64x48br); 20 | oled.setFont(FONT8X16); 21 | drawScreen(); 22 | oled.on(); 23 | } 24 | 25 | void loop() { 26 | scrollScreen(); 27 | } 28 | 29 | void drawScreen() { 30 | // Set entire memory to hatched - if you see any of this hatching, then the display is not initialised correctly. 31 | for (uint8_t y = 0; y < 8; y++) { 32 | oled.setCursor(0, y); 33 | oled.startData(); 34 | for (uint8_t x=0; x<128; x += 2) { 35 | oled.sendData(0b10101010); 36 | oled.sendData(0b01010101); 37 | } 38 | oled.endData(); 39 | } 40 | 41 | oled.setCursor(0, 0); 42 | oled.startData(); 43 | oled.sendData(0b11111111); 44 | oled.repeatData(0b00000001, width - 2); 45 | oled.sendData(0b11111111); 46 | oled.endData(); 47 | 48 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 49 | oled.setCursor(0, y); 50 | oled.startData(); 51 | oled.sendData(0b11111111); 52 | oled.repeatData(0b00000000, width - 2); 53 | oled.sendData(0b11111111); 54 | oled.endData(); 55 | } 56 | 57 | oled.setCursor(0, (height - 8) / 8); 58 | oled.startData(); 59 | oled.sendData(0b11111111); 60 | oled.repeatData(0b10000000, width - 2); 61 | oled.sendData(0b11111111); 62 | oled.endData(); 63 | 64 | oled.setCursor(8, 1); 65 | oled.print(width); 66 | oled.print('x'); 67 | oled.print(height); 68 | } 69 | 70 | void scrollScreen() { 71 | uint8_t startScrollPage = 1; 72 | uint8_t endScrollPage = 2; 73 | uint8_t startScrollColumn = 8; 74 | uint8_t endScrollColumn = startScrollColumn + width - 16; 75 | for (uint8_t x = 0; x < width - 16; x++) 76 | { 77 | delay(50); 78 | oled.scrollContentRight(startScrollPage, endScrollPage, startScrollColumn, endScrollColumn); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/Devices/72x40/72x40.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows a full screen rectangle, 8 | * writes the rectangle size inside the rectangle, 9 | * and scrolls the size off the screen. 10 | * 11 | */ 12 | 13 | #include 14 | 15 | uint8_t width = 72; 16 | uint8_t height = 40; 17 | 18 | void setup() { 19 | oled.begin(width, height, sizeof(tiny4koled_init_72x40br), tiny4koled_init_72x40br); 20 | oled.setFont(FONT8X16); 21 | drawScreen(); 22 | oled.on(); 23 | } 24 | 25 | void loop() { 26 | scrollScreen(); 27 | } 28 | 29 | void drawScreen() { 30 | // Set entire memory to hatched - if you see any of this hatching, then the display is not initialised correctly. 31 | for (uint8_t y = 0; y < 8; y++) { 32 | oled.setCursor(0, y); 33 | oled.startData(); 34 | for (uint8_t x=0; x<128; x += 2) { 35 | oled.sendData(0b10101010); 36 | oled.sendData(0b01010101); 37 | } 38 | oled.endData(); 39 | } 40 | 41 | oled.setCursor(0, 0); 42 | oled.startData(); 43 | oled.sendData(0b11111111); 44 | oled.repeatData(0b00000001, width - 2); 45 | oled.sendData(0b11111111); 46 | oled.endData(); 47 | 48 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 49 | oled.setCursor(0, y); 50 | oled.startData(); 51 | oled.sendData(0b11111111); 52 | oled.repeatData(0b00000000, width - 2); 53 | oled.sendData(0b11111111); 54 | oled.endData(); 55 | } 56 | 57 | oled.setCursor(0, (height - 8) / 8); 58 | oled.startData(); 59 | oled.sendData(0b11111111); 60 | oled.repeatData(0b10000000, width - 2); 61 | oled.sendData(0b11111111); 62 | oled.endData(); 63 | 64 | oled.setCursor(8, 1); 65 | oled.print(width); 66 | oled.print('x'); 67 | oled.print(height); 68 | } 69 | 70 | void scrollScreen() { 71 | uint8_t startScrollPage = 1; 72 | uint8_t endScrollPage = 2; 73 | uint8_t startScrollColumn = 8; 74 | uint8_t endScrollColumn = startScrollColumn + width - 16; 75 | for (uint8_t x = 0; x < width - 16; x++) 76 | { 77 | delay(50); 78 | oled.scrollContentRight(startScrollPage, endScrollPage, startScrollColumn, endScrollColumn); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/Devices/128x32/128x32.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows a full screen rectangle, 8 | * writes the rectangle size inside the rectangle, 9 | * and scrolls the size off the screen. 10 | * 11 | */ 12 | 13 | #include 14 | 15 | uint8_t width = 128; 16 | uint8_t height = 32; 17 | 18 | void setup() { 19 | oled.begin(width, height, sizeof(tiny4koled_init_128x32br), tiny4koled_init_128x32br); 20 | oled.setFont(FONT8X16); 21 | drawScreen(); 22 | oled.on(); 23 | } 24 | 25 | void loop() { 26 | scrollScreen(); 27 | } 28 | 29 | void drawScreen() { 30 | // Set entire memory to hatched - if you see any of this hatching, then the display is not initialised correctly. 31 | for (uint8_t y = 0; y < 8; y++) { 32 | oled.setCursor(0, y); 33 | oled.startData(); 34 | for (uint8_t x=0; x<128; x += 2) { 35 | oled.sendData(0b10101010); 36 | oled.sendData(0b01010101); 37 | } 38 | oled.endData(); 39 | } 40 | 41 | oled.setCursor(0, 0); 42 | oled.startData(); 43 | oled.sendData(0b11111111); 44 | oled.repeatData(0b00000001, width - 2); 45 | oled.sendData(0b11111111); 46 | oled.endData(); 47 | 48 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 49 | oled.setCursor(0, y); 50 | oled.startData(); 51 | oled.sendData(0b11111111); 52 | oled.repeatData(0b00000000, width - 2); 53 | oled.sendData(0b11111111); 54 | oled.endData(); 55 | } 56 | 57 | oled.setCursor(0, (height - 8) / 8); 58 | oled.startData(); 59 | oled.sendData(0b11111111); 60 | oled.repeatData(0b10000000, width - 2); 61 | oled.sendData(0b11111111); 62 | oled.endData(); 63 | 64 | oled.setCursor(8, 1); 65 | oled.print(width); 66 | oled.print('x'); 67 | oled.print(height); 68 | } 69 | 70 | void scrollScreen() { 71 | uint8_t startScrollPage = 1; 72 | uint8_t endScrollPage = 2; 73 | uint8_t startScrollColumn = 8; 74 | uint8_t endScrollColumn = startScrollColumn + width - 16; 75 | for (uint8_t x = 0; x < width - 16; x++) 76 | { 77 | delay(50); 78 | oled.scrollContentRight(startScrollPage, endScrollPage, startScrollColumn, endScrollColumn); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/Devices/128x64/128x64.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows a full screen rectangle, 8 | * writes the rectangle size inside the rectangle, 9 | * and scrolls the size off the screen. 10 | * 11 | */ 12 | 13 | #include 14 | 15 | uint8_t width = 128; 16 | uint8_t height = 64; 17 | 18 | void setup() { 19 | oled.begin(width, height, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 20 | oled.setFont(FONT8X16); 21 | drawScreen(); 22 | oled.on(); 23 | } 24 | 25 | void loop() { 26 | scrollScreen(); 27 | } 28 | 29 | void drawScreen() { 30 | // Set entire memory to hatched - if you see any of this hatching, then the display is not initialised correctly. 31 | for (uint8_t y = 0; y < 8; y++) { 32 | oled.setCursor(0, y); 33 | oled.startData(); 34 | for (uint8_t x=0; x<128; x += 2) { 35 | oled.sendData(0b10101010); 36 | oled.sendData(0b01010101); 37 | } 38 | oled.endData(); 39 | } 40 | 41 | oled.setCursor(0, 0); 42 | oled.startData(); 43 | oled.sendData(0b11111111); 44 | oled.repeatData(0b00000001, width - 2); 45 | oled.sendData(0b11111111); 46 | oled.endData(); 47 | 48 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 49 | oled.setCursor(0, y); 50 | oled.startData(); 51 | oled.sendData(0b11111111); 52 | oled.repeatData(0b00000000, width - 2); 53 | oled.sendData(0b11111111); 54 | oled.endData(); 55 | } 56 | 57 | oled.setCursor(0, (height - 8) / 8); 58 | oled.startData(); 59 | oled.sendData(0b11111111); 60 | oled.repeatData(0b10000000, width - 2); 61 | oled.sendData(0b11111111); 62 | oled.endData(); 63 | 64 | oled.setCursor(8, 1); 65 | oled.print(width); 66 | oled.print('x'); 67 | oled.print(height); 68 | } 69 | 70 | void scrollScreen() { 71 | uint8_t startScrollPage = 1; 72 | uint8_t endScrollPage = 2; 73 | uint8_t startScrollColumn = 8; 74 | uint8_t endScrollColumn = startScrollColumn + width - 16; 75 | for (uint8_t x = 0; x < width - 16; x++) 76 | { 77 | delay(50); 78 | oled.scrollContentRight(startScrollPage, endScrollPage, startScrollColumn, endScrollColumn); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/CustomChineseFont/CustomChineseFont.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | //#include 14 | 15 | // To use the Adafruit's TinyWireM library: 16 | //#include 17 | 18 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 19 | //#include 20 | 21 | // The blue OLED screen requires a long initialization on power on. 22 | // The code to wait for it to be ready uses 20 bytes of program storage space 23 | // If you are using a white OLED, this can be reclaimed by uncommenting 24 | // the following line (before including Tiny4kOLED.h): 25 | //#define TINY4KOLED_QUICK_BEGIN 26 | 27 | #include 28 | #include "font16x16cn.h" 29 | // ============================================================================ 30 | 31 | void setup() { 32 | // put your setup code here, to run once: 33 | 34 | oled.begin(); 35 | 36 | // Two rotations are supported, 37 | // The begin() method sets the rotation to 1. 38 | //oled.setRotation(0); 39 | 40 | // Some newer devices do not contain an external current reference. 41 | // Older devices may also support using the internal curret reference, 42 | // which provides more consistent brightness across devices. 43 | // The internal current reference can be configured as either low current, or high current. 44 | // Using true as the parameter value choses the high current internal current reference, 45 | // resulting in a brighter display, and a more effective contrast setting. 46 | //oled.setInternalIref(true); 47 | 48 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 49 | // Other fonts are available from the TinyOLED-Fonts library 50 | // This example shows how to create and use your own font. 51 | // The font used here is of five chinese characters. 52 | oled.setFont(&TinyOLED4kfont16x16cn); 53 | 54 | oled.clear(); 55 | oled.setCursor(10, 1); 56 | oled.print(F("01234")); 57 | oled.on(); 58 | } 59 | 60 | void loop() { 61 | // put your main code here, to run repeatedly: 62 | delay(10000); 63 | } 64 | -------------------------------------------------------------------------------- /examples/CustomChineseFont/font16x16cn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved. 15 | * Distributed as open source software under MIT License, see LICENSE.txt file. 16 | * Please, as a favor, retain the link http://tinusaur.org to The Tinusaur Project. 17 | * 18 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 19 | * 20 | */ 21 | 22 | /**************************************************************** 23 | * 24 | * ���ļ����ڴ�����룬ASCII�ַ�����ʹ�ñ��ļ����ṩ�ģ� 25 | * ���ֺ�ͼƬ���밴���·�ʽȡģ��������������ʽ�����������; 26 | * �뽫û���õ�������ע�͵����������Խ�ԼFLASH�� 27 | * 28 | *****************************************************************/ 29 | 30 | #include 31 | 32 | /* 16*16 ����ȡ�ַ�ʽ��������������ʽ����������� */ 33 | const uint8_t ssd1306xled_font16x16cn [] PROGMEM = { 34 | 0x00,0x02,0x02,0xFA,0xFA,0xAA,0xAA,0xFF,0xFF,0xAA,0xAA,0xFA,0xFA,0x02,0x02,0x00, 35 | 0x00,0x42,0x72,0x72,0x3A,0x7A,0x42,0x4B,0x5B,0x52,0x62,0x62,0x13,0x77,0x66,0x00, // "��",0 36 | 37 | 0x20,0x3C,0x1C,0xFF,0xFF,0xB0,0xB4,0x24,0x24,0x3F,0x3F,0xE4,0xE4,0x24,0x24,0x20, 38 | 0x02,0x02,0x03,0xFF,0xFF,0x00,0x01,0x05,0x1D,0x59,0xC1,0xFF,0x7F,0x01,0x01,0x01, // "��",1 39 | 40 | 0x00,0x00,0x00,0xF8,0xF8,0x48,0x4C,0x4F,0x4B,0x4A,0x48,0x48,0xF8,0xF8,0x00,0x00, 41 | 0x00,0x00,0x00,0xFF,0xFF,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xFF,0xFF,0x00,0x00, // "��",2 42 | 43 | 0x20,0x24,0x24,0xE4,0xE4,0x24,0x24,0x24,0x30,0x10,0xFF,0xFF,0x10,0xF0,0xF0,0x00, 44 | 0x08,0x1C,0x1F,0x0B,0x0C,0x0D,0x4F,0x6E,0x34,0x1C,0x0F,0x23,0x60,0x7F,0x3F,0x00, // "��",3 45 | 46 | 0x80,0xC0,0x60,0xF8,0xFF,0x07,0x02,0x00,0xFF,0xFF,0xE0,0x70,0x3C,0x1C,0x08,0x00, 47 | 0x00,0x00,0x00,0x7F,0x7F,0x04,0x06,0x03,0x3F,0x7F,0x40,0x40,0x40,0x78,0x78,0x00, // "��",4 48 | }; 49 | 50 | 51 | const DCfont TinyOLED4kfont16x16cn = { 52 | (uint8_t *)ssd1306xled_font16x16cn, 53 | 16, // character width in pixels 54 | 2, // character height in pages (8 pixels) 55 | 48,52, // ASCII extents 56 | 0,0,0 // Unused for fixed width fonts 57 | }; 58 | 59 | -------------------------------------------------------------------------------- /examples/DoubleSizeText/DoubleSizeText.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | //#include 14 | 15 | // To use the Adafruit's TinyWireM library: 16 | //#include 17 | 18 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 19 | //#include 20 | 21 | // The blue OLED screen requires a long initialization on power on. 22 | // The code to wait for it to be ready uses 20 bytes of program storage space 23 | // If you are using a white OLED, this can be reclaimed by uncommenting 24 | // the following line (before including Tiny4kOLED.h): 25 | //#define TINY4KOLED_QUICK_BEGIN 26 | 27 | #include 28 | // ============================================================================ 29 | 30 | void setup() { 31 | // put your setup code here, to run once: 32 | 33 | // This example is for a 128x64 screen 34 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 35 | 36 | // Two rotations are supported, 37 | // The begin() method sets the rotation to 1. 38 | //oled.setRotation(0); 39 | 40 | // Some newer devices do not contain an external current reference. 41 | // Older devices may also support using the internal curret reference, 42 | // which provides more consistent brightness across devices. 43 | // The internal current reference can be configured as either low current, or high current. 44 | // Using true as the parameter value choses the high current internal current reference, 45 | // resulting in a brighter display, and a more effective contrast setting. 46 | //oled.setInternalIref(true); 47 | 48 | oled.clear(); 49 | normalSize(); 50 | doubleSize(); 51 | oled.on(); 52 | } 53 | 54 | void loop() { 55 | delay(10000); 56 | } 57 | 58 | void normalSize() { 59 | oled.setFont(FONT6X8P); 60 | oled.setCursor(0, 1); 61 | oled.print("Normal Size"); 62 | 63 | oled.setFont(FONT8X16P); 64 | oled.setCursor(64, 0); 65 | oled.print("Datacute"); 66 | } 67 | 68 | void doubleSize() { 69 | oled.setFontX2(FONT6X8P); 70 | oled.setCursor(0, 2); 71 | oled.print("Double Size"); 72 | 73 | oled.setFontX2(FONT8X16P); 74 | oled.setCursor(0, 4); 75 | oled.print("Datacute"); 76 | } 77 | -------------------------------------------------------------------------------- /examples/DoubleSizeSmoothText/DoubleSizeSmoothText.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | //#include 14 | 15 | // To use the Adafruit's TinyWireM library: 16 | //#include 17 | 18 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 19 | //#include 20 | 21 | // The blue OLED screen requires a long initialization on power on. 22 | // The code to wait for it to be ready uses 20 bytes of program storage space 23 | // If you are using a white OLED, this can be reclaimed by uncommenting 24 | // the following line (before including Tiny4kOLED.h): 25 | //#define TINY4KOLED_QUICK_BEGIN 26 | 27 | #include 28 | // ============================================================================ 29 | 30 | void setup() { 31 | // put your setup code here, to run once: 32 | 33 | // This example is for a 128x64 screen 34 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 35 | 36 | // Two rotations are supported, 37 | // The begin() method sets the rotation to 1. 38 | //oled.setRotation(0); 39 | 40 | // Some newer devices do not contain an external current reference. 41 | // Older devices may also support using the internal curret reference, 42 | // which provides more consistent brightness across devices. 43 | // The internal current reference can be configured as either low current, or high current. 44 | // Using true as the parameter value choses the high current internal current reference, 45 | // resulting in a brighter display, and a more effective contrast setting. 46 | //oled.setInternalIref(true); 47 | 48 | oled.clear(); 49 | normalSize(); 50 | doubleSizeSmooth(); 51 | oled.on(); 52 | } 53 | 54 | void loop() { 55 | delay(10000); 56 | } 57 | 58 | void normalSize() { 59 | oled.setFont(FONT6X8P); 60 | oled.setCursor(0, 1); 61 | oled.print("Normal Size"); 62 | 63 | oled.setFont(FONT8X16P); 64 | oled.setCursor(64, 0); 65 | oled.print("Datacute"); 66 | } 67 | 68 | void doubleSizeSmooth() { 69 | oled.setFontX2Smooth(FONT6X8P); 70 | oled.setCursor(0, 2); 71 | oled.print("Double Size"); 72 | 73 | oled.setFontX2Smooth(FONT8X16P); 74 | oled.setCursor(0, 4); 75 | oled.print("Datacute"); 76 | } 77 | -------------------------------------------------------------------------------- /examples/InverseText/InverseText.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows how the scrolling features work. 8 | * When scrolling, the double buffering of screens cannot be used. 9 | * 10 | */ 11 | 12 | // Choose your I2C implementation before including Tiny4kOLED.h 13 | // The default is selected is Wire.h 14 | 15 | // To use the Wire library: 16 | //#include 17 | 18 | // To use the Adafruit's TinyWireM library: 19 | //#include 20 | 21 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 22 | //#include 23 | 24 | // The blue OLED screen requires a long initialization on power on. 25 | // The code to wait for it to be ready uses 20 bytes of program storage space 26 | // If you are using a white OLED, this can be reclaimed by uncommenting 27 | // the following line (before including Tiny4kOLED.h): 28 | //#define TINY4KOLED_QUICK_BEGIN 29 | 30 | #include 31 | 32 | void setup() { 33 | oled.begin(); 34 | 35 | // Two rotations are supported, 36 | // The begin() method sets the rotation to 1. 37 | //oled.setRotation(0); 38 | 39 | // Some newer devices do not contain an external current reference. 40 | // Older devices may also support using the internal curret reference, 41 | // which provides more consistent brightness across devices. 42 | // The internal current reference can be configured as either low current, or high current. 43 | // Using true as the parameter value choses the high current internal current reference, 44 | // resulting in a brighter display, and a more effective contrast setting. 45 | //oled.setInternalIref(true); 46 | 47 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 48 | // Other fonts are available from the TinyOLED-Fonts library 49 | oled.setFont(FONT6X8); 50 | oled.clear(); 51 | oled.on(); 52 | } 53 | 54 | void loop() { 55 | 56 | oled.setCursor(0, 0); 57 | oled.invertOutput(false); 58 | oled.println("Normal"); 59 | delay(500); 60 | 61 | oled.invertOutput(true); 62 | oled.print("Inverse"); 63 | oled.clearToEOL(); 64 | delay(500); 65 | 66 | for (;;) 67 | { 68 | oled.setCursor(0, 2); 69 | oled.invertOutput(true); 70 | oled.print(" "); 71 | 72 | delay(500); 73 | 74 | oled.setCursor(0, 2); 75 | oled.invertOutput(false); 76 | oled.print(" "); 77 | 78 | delay(500); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /examples/Bitmap/Bitmap.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | //#include 14 | 15 | // To use the Adafruit's TinyWireM library: 16 | //#include 17 | 18 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 19 | //#include 20 | 21 | // The blue OLED screen requires a long initialization on power on. 22 | // The code to wait for it to be ready uses 20 bytes of program storage space 23 | // If you are using a white OLED, this can be reclaimed by uncommenting 24 | // the following line (before including Tiny4kOLED.h): 25 | //#define TINY4KOLED_QUICK_BEGIN 26 | 27 | #include 28 | #include "SolomonSystech.h" 29 | 30 | // ============================================================================ 31 | 32 | void setup() { 33 | // put your setup code here, to run once: 34 | 35 | oled.begin(); 36 | 37 | // Two rotations are supported, 38 | // The begin() method sets the rotation to 1. 39 | //oled.setRotation(0); 40 | 41 | // Some newer devices do not contain an external current reference. 42 | // Older devices may also support using the internal curret reference, 43 | // which provides more consistent brightness across devices. 44 | // The internal current reference can be configured as either low current, or high current. 45 | // Using true as the parameter value choses the high current internal current reference, 46 | // resulting in a brighter display, and a more effective contrast setting. 47 | //oled.setInternalIref(true); 48 | 49 | // This example does not use double buffering. 50 | 51 | // To save space, the bitmap is cropped left and right, 52 | // intended to be drawn onto a clear screen 53 | oled.clear(); 54 | 55 | // The display will show two bitmaps, 56 | // one of SOLOMON SYSTECH's logo 57 | // one of the text SOLOMON SYSTECH 58 | // The logo bitmap is 37 pixels wide 59 | // The text bitmap is 69 pixels wide 60 | // Both are 32 pixels (4 pages) high 61 | 62 | oled.bitmap(6, 0, 6 + 37, 4, solomon_systech_logo_bitmap); 63 | oled.bitmap(54, 0, 54 + 69, 4, solomon_systech_text_bitmap); 64 | 65 | // Now that the display is all setup, turn on the display 66 | oled.on(); 67 | } 68 | 69 | void loop() { 70 | // This example only shows a static image on the display. 71 | // The microcontroller could be turned off now. 72 | } 73 | -------------------------------------------------------------------------------- /src/Tiny4kOLED_bitbang.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This file adds support for the I2C implementation from https://github.com/evilnick/evilOLED 8 | * 9 | */ 10 | #ifndef TINY4KOLED_BITBANG_H 11 | #define TINY4KOLED_BITBANG_H 12 | 13 | #include "Tiny4kOLED_common.h" 14 | 15 | #ifndef DATACUTE_I2C_BITBANG 16 | #define DATACUTE_I2C_BITBANG 17 | 18 | static bool datacute_write_bitbang(uint8_t byte) { 19 | char i; 20 | for (i = 0; i < 8; i++) 21 | { 22 | if ((byte << i) & 0x80) { 23 | PORTB |= (1 << PB0);//digitalWrite(SDA, HIGH); 24 | } 25 | else { 26 | PORTB &= ~(1 << PB0);//digitalWrite(SDA, LOW); 27 | } 28 | PORTB |= (1 << PB2);//digitalWrite(SCL, HIGH); 29 | PORTB &= ~(1 << PB2);//digitalWrite(SCL, LOW); 30 | } 31 | 32 | PORTB |= (1 << PB0);//digitalWrite(SDA, HIGH); 33 | PORTB |= (1 << PB2);//digitalWrite(SCL, HIGH); 34 | PORTB &= ~(1 << PB2);//digitalWrite(SCL, LOW); 35 | return 1; 36 | } 37 | 38 | static uint8_t datacute_read_bitbang(void) __attribute__((unused)); 39 | static uint8_t datacute_read_bitbang(void) { 40 | return 0; 41 | } 42 | 43 | static void datacute_end_read_bitbang(void) __attribute__((unused)); 44 | static void datacute_end_read_bitbang(void) { 45 | PORTB &= ~(1 << PB2);//digitalWrite(SCL, LOW); 46 | PORTB &= ~(1 << PB0);//digitalWrite(SDA, LOW); 47 | PORTB |= (1 << PB2);//digitalWrite(SCL, HIGH); 48 | PORTB |= (1 << PB0);//digitalWrite(SDA, HIGH); 49 | } 50 | 51 | static uint8_t datacute_endTransmission_bitbang(void) { 52 | PORTB &= ~(1 << PB2);//digitalWrite(SCL, LOW); 53 | PORTB &= ~(1 << PB0);//digitalWrite(SDA, LOW); 54 | PORTB |= (1 << PB2);//digitalWrite(SCL, HIGH); 55 | PORTB |= (1 << PB0);//digitalWrite(SDA, HIGH); 56 | return 0; 57 | } 58 | 59 | #endif 60 | 61 | static bool tiny4koled_beginTransmission_bitbang(void) { 62 | PORTB |= (1 << PB2);//digitalWrite(SCL, HIGH); 63 | PORTB |= (1 << PB0);//digitalWrite(SDA, HIGH); 64 | PORTB &= ~(1 << PB0);//digitalWrite(SDA, LOW); 65 | PORTB &= ~(1 << PB2);//digitalWrite(SCL, LOW); 66 | datacute_write_bitbang(SSD1306<<1); 67 | return 0; 68 | } 69 | 70 | static void tiny4koled_begin_bitbang(void) { 71 | pinMode(SCL, OUTPUT); 72 | pinMode(SDA, OUTPUT); 73 | } 74 | 75 | 76 | #ifndef TINY4KOLED_NO_PRINT 77 | SSD1306PrintDevice oled(&tiny4koled_begin_bitbang, &tiny4koled_beginTransmission_bitbang, &datacute_write_bitbang, &datacute_endTransmission_bitbang); 78 | #else 79 | SSD1306Device oled(&tiny4koled_begin_bitbang, &tiny4koled_beginTransmission_bitbang, &datacute_write_bitbang, &datacute_endTransmission_bitbang); 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /examples/PacMan/PacManMap.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | 28 columns x 31 rows 4 | at 1 bit per square - requires 28 x 4 bytes = 112 bytes 5 | Could store a 112 byte background (wall/space) in flash (though the map is mirrored so only need to store one side of it) 6 | 7 | Pills could be stored as bits of the clear path to fill - takes 39 bytes but makes everything a lot more complicated 8 | Need to store current state as well as initial state. 9 | Maybe store the lines of pills? 7 horizontal x 26, 10 vertical x 22 (less efficient to put into bytes: 7 x 4 + 10 x 3 = 58) 10 | or 7 horizontal x 16, 10 vertical x 29 (more efficient in bytes: 7 x 2 + 10 x 4 = 54) 11 | 12 | Initial state is probably more efficent as an algorithm: 13 | If wall then not a pill 14 | Else if first 9 or last 11 rows then a pill 15 | Else if 7th or 22nd column then a pill 16 | Else not a pill 17 | 18 | The original uses x positions 0x3B to 0x20 19 | and y positions $21 to $3F 20 | 21 | ############################ 0 22 | #............##............# 1 23 | #.####.#####.##.#####.####.# 2 24 | #O####.#####.##.#####.####O# 3 25 | #.####.#####.##.#####.####.# 4 26 | #..........................# 5 27 | #.####.##.########.##.####.# 6 28 | #.####.##.########.##.####.# 7 29 | #......##....##....##......# 8 30 | ######.##### ## #####.###### 9 31 | #.##### ## #####.# 10 32 | #.## [] ##.# 11 33 | #.## ### ### ##.# 12 34 | ######.## # # ##.###### 13 35 | . #[][][]# . 14 36 | ######.## # # ##.###### 15 37 | #.## ######## ##.# 16 38 | #.## READY! ##.# 17 39 | #.## ######## ##.# 18 40 | ######.## ######## ##.###### 19 41 | #............##............# 20 42 | #.####.#####.##.#####.####.# 21 43 | #.####.#####.##.#####.####.# 22 44 | #O..##.......().......##..O# 23 45 | ###.##.##.########.##.##.### 24 46 | ###.##.##.########.##.##.### 25 47 | #......##....##....##......# 26 48 | #.##########.##.##########.# 27 49 | #.##########.##.##########.# 28 50 | #..........................# 29 51 | ############################ 30 52 | ()() 53 | 54 | The map is mirrored, so we only need to store one side of it: 55 | */ 56 | 57 | const uint8_t mirroredMap [] PROGMEM = { 58 | 0xFF,0x01,0xDD,0xDD,0xDD,0xDD,0x01,0xDD,0xDD,0x1D,0xDD,0xDD,0xC1,0xDF, 59 | 0xA3,0xA2,0xA2,0xA2,0xA2,0xBE,0x00,0xBF,0xBF,0x06,0xF6,0x16,0x10,0x07, 60 | 0xF8,0x08,0x68,0x68,0xE8,0xEF,0x00,0x6F,0x6F,0x60,0x6D,0x6D,0x0D,0x7D, 61 | 0x7F,0x43,0x5B,0x58,0x5B,0x5B,0x58,0x5F,0x5F,0x58,0x5B,0x5B,0x43,0x5F 62 | }; 63 | 64 | const uint8_t horizontalPelletRows [] = { 65 | 1,5,8,20,23,26,29 66 | }; 67 | const uint8_t horizontalPelletsInit [] PROGMEM = { 68 | 0xB4,0x0D,0xDB,0x02, 69 | 0xB4,0x6D,0xDB,0x02, 70 | 0x34,0x0C,0xC3,0x02, 71 | 0xB4,0x0D,0xDB,0x02, 72 | 0x84,0x0D,0x1B,0x02, 73 | 0x34,0x0C,0xC3,0x02, 74 | 0xB4,0x6D,0xDB,0x02, 75 | }; 76 | 77 | const uint8_t verticalPelletRows [] = { 78 | 1,3,6,9,12,15,18,21,24,26 79 | }; 80 | const uint8_t verticalPelletsInit [] PROGMEM = { 81 | 0xFE,0x01,0xF0,0x3C, 82 | 0x22,0x01,0x90,0x27, 83 | 0xFE,0xFF,0xFF,0x27, 84 | 0xE2,0x01,0x90,0x27, 85 | 0x3E,0x01,0xF0,0x3C, 86 | 0x3E,0x01,0xF0,0x3C, 87 | 0xE2,0x01,0x90,0x27, 88 | 0xFE,0xFF,0xFF,0x27, 89 | 0x22,0x01,0x90,0x27, 90 | 0xFE,0x01,0xF0,0x3C, 91 | }; 92 | -------------------------------------------------------------------------------- /examples/DatacuteBoxyFont/boxyfont.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | #include 10 | 11 | // Code Page 437 box drawing characters 12 | const uint8_t cp_437_box_drawing_font_bitmap [] PROGMEM = { 13 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 175 � » blank (for convenience - not blank in codepage 437 14 | 0x88,0x22,0x44,0x11,0x88,0x22,0x44,0x11, // 176 � ░ 15 | 0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55, // 177 � ▒ 16 | 0x77,0xDD,0xBB,0xEE,0x77,0xDD,0xBB,0xEE, // 178 � ▓ 17 | 0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00, // 179 � │ 18 | 0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00, // 180 � ┤ 19 | 0x24,0x24,0x24,0xFF,0xFF,0x00,0x00,0x00, // 181 � ╡ 20 | 0x18,0x18,0xFF,0x00,0x00,0xFF,0x00,0x00, // 182 � ╢ 21 | 0x18,0x18,0xF8,0x18,0x18,0xF8,0x00,0x00, // 183 � ╖ 22 | 0x24,0x24,0x24,0xFC,0xFC,0x00,0x00,0x00, // 184 � ╕ 23 | 0x24,0x24,0xE7,0x00,0x00,0xFF,0x00,0x00, // 185 � ╣ 24 | 0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00, // 186 � ║ 25 | 0x24,0x24,0xE4,0x04,0x04,0xFC,0x00,0x00, // 187 � ╗ 26 | 0x24,0x24,0x27,0x20,0x20,0x3F,0x00,0x00, // 188 � ╝ 27 | 0x18,0x18,0x1F,0x18,0x18,0x1F,0x00,0x00, // 189 � ╜ 28 | 0x24,0x24,0x24,0x3F,0x3F,0x00,0x00,0x00, // 190 � ╛ 29 | 0x18,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00, // 191 � ┐ 30 | 0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18, // 192 � └ 31 | 0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18, // 193 � ┴ 32 | 0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18, // 194 � ┬ 33 | 0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18, // 195 � ├ 34 | 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, // 196 � ─ 35 | 0x18,0x18,0x18,0xFF,0xFF,0x18,0x18,0x18, // 197 � ┼ 36 | 0x00,0x00,0x00,0xFF,0xFF,0x24,0x24,0x24, // 198 � ╞ 37 | 0x00,0x00,0xFF,0x00,0x00,0xFF,0x18,0x18, // 199 � ╟ 38 | 0x00,0x00,0x3F,0x20,0x20,0x27,0x24,0x24, // 200 � ╚ 39 | 0x00,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24, // 201 � ╔ 40 | 0x24,0x24,0x27,0x20,0x20,0x27,0x24,0x24, // 202 � ╩ 41 | 0x24,0x24,0xE4,0x04,0x04,0xE4,0x24,0x24, // 203 � ╦ 42 | 0x00,0x00,0xFF,0x00,0x00,0xE7,0x24,0x24, // 204 � ╠ 43 | 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // 205 � ═ 44 | 0x24,0x24,0xE7,0x00,0x00,0xE7,0x24,0x24, // 206 � ╬ 45 | 0x24,0x24,0x24,0x27,0x27,0x24,0x24,0x24, // 207 � ╧ 46 | 0x18,0x18,0x1F,0x18,0x18,0x1F,0x18,0x18, // 208 � ╨ 47 | 0x24,0x24,0x24,0xE4,0xE4,0x24,0x24,0x24, // 209 � ╤ 48 | 0x18,0x18,0xF8,0x18,0x18,0xF8,0x18,0x18, // 210 � ╥ 49 | 0x00,0x00,0x1F,0x18,0x18,0x1F,0x18,0x18, // 211 � ╙ 50 | 0x00,0x00,0x00,0x3F,0x3F,0x24,0x24,0x24, // 212 � ╘ 51 | 0x00,0x00,0x00,0xFC,0xFC,0x24,0x24,0x24, // 213 � ╒ 52 | 0x00,0x00,0xF8,0x18,0x18,0xF8,0x18,0x18, // 214 � ╓ 53 | 0x18,0x18,0xFF,0x00,0x00,0xFF,0x18,0x18, // 215 � ╫ 54 | 0x24,0x24,0x24,0xE7,0xE7,0x24,0x24,0x24, // 216 � ╪ 55 | 0x18,0x18,0x18,0x1F,0x1F,0x00,0x00,0x00, // 217 � ┘ 56 | 0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0x18, // 218 � ┌ 57 | 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // 219 � █ 58 | 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, // 220 � ▄ 59 | 0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00, // 221 � ▌ 60 | 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, // 222 � ▐ 61 | 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F // 223 � ▀ 62 | }; 63 | 64 | const DCfont cp_437_box_drawing_font = { 65 | (uint8_t *)cp_437_box_drawing_font_bitmap, 66 | 8, // character width in pixels 67 | 1, // character height in pages (8 pixels) 68 | 175,223, // ASCII extents 69 | 0,0,0 // Unused for fixed width fonts 70 | }; 71 | 72 | -------------------------------------------------------------------------------- /examples/PacMan/Graphics.h: -------------------------------------------------------------------------------- 1 | #define spriteBlank 0 2 | #define spritePacmanRight1 1 3 | #define spritePacmanRight2 2 4 | #define spritePacmanUp1 3 5 | #define spritePacmanUp2 4 6 | #define spritePacmanDown1 5 7 | #define spritePacmanDown2 6 8 | #define spriteGhostRightHunting 7 9 | #define spriteGhostRightRunning 8 10 | #define spritePellet 9 11 | #define spriteSuperPellet 10 12 | #define spriteWallRight 11 13 | #define spriteWallAbove 12 14 | #define spriteWallLeft 13 15 | #define spriteWallBelow 14 16 | 17 | #define spriteR 15 18 | #define spriteE 16 19 | #define spriteA 17 20 | #define spriteD 18 21 | #define spriteY 19 22 | #define spriteBang 20 23 | 24 | #define spriteEntering 0x20 25 | #define spriteShifted 0x40 26 | #define spriteReversed 0x80 27 | #define spriteMask 0x1F 28 | 29 | const uint8_t sprites [] PROGMEM = { 30 | // Empty passage 31 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 32 | // Pacman facing right, mouth open 33 | 0x3C,0x7E,0xFF,0xFB,0xEF,0xE7,0x62,0x20, // 1 34 | // Pacman facing right, mouth closed 35 | 0x3C,0x7E,0xFF,0xFB,0xFF,0xFF,0x7E,0x3C, // 2 36 | // Pacman going up, mouth open 37 | 0x3C,0x7E,0xEC,0xF8,0xF0,0xFF,0x7E,0x3C, // 3 38 | // Pacman going up, mouth closed 39 | 0x3C,0x7E,0xEF,0xFF,0xFF,0xFF,0x7E,0x3C, // 4 40 | // Pacman going down, mouth open 41 | 0x3C,0x7E,0xFF,0x0F,0x1F,0x37,0x7E,0x3C, // 5 42 | // Pacman going down, mouth closed 43 | 0x3C,0x7E,0xFF,0xFF,0xFF,0xF7,0x7E,0x3C, // 6 44 | 45 | // Ghost facing right, hunting 46 | 0xFC,0x7E,0x73,0xF7,0x7F,0xF3,0x77,0xFE, // 7 47 | // Ghost facing right, running 48 | 0xFC,0x42,0x41,0xC9,0x41,0xC9,0x41,0xFE, // 8 49 | // Pellet 50 | 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00, // 9 51 | // Power-up pellet 52 | 0x00,0x18,0x3C,0x7E,0x7E,0x3C,0x18,0x00, // 10 53 | 54 | // Wall with wall to right 55 | //0x00,0x18,0x24,0x42,0x42,0x66,0x7E,0x42, // 11 56 | 0x00,0x00,0x18,0x24,0x24,0x3C,0x24,0x24, // 11 57 | // Wall with wall above 58 | //0x00,0x1F,0x26,0x42,0x42,0x26,0x1F,0x00, // 12 59 | 0x00,0x00,0x1F,0x24,0x24,0x1F,0x00,0x00, // 12 60 | // Wall with wall to left 61 | //0x42,0x7E,0x66,0x42,0x42,0x24,0x18,0x00, // 13 62 | 0x24,0x24,0x3C,0x24,0x24,0x18,0x00,0x00, // 13 63 | // Wall with wall below 64 | //0x00,0xF8,0x64,0x42,0x42,0x64,0xF8,0x00, // 14 65 | 0x00,0x00,0xF8,0x24,0x24,0xF8,0x00,0x00, // 14 66 | 67 | // R 68 | 0x00,0x7F,0x7F,0x11,0x11,0x39,0x6E,0x4E, 69 | // E 70 | 0x00,0x00,0x7F,0x7F,0x49,0x49,0x49,0x41, 71 | // A 72 | 0x00,0x7C,0x7E,0x13,0x11,0x13,0x7E,0x7C, 73 | // D 74 | 0x00,0x7F,0x7F,0x41,0x41,0x63,0x3E,0x1C, 75 | // Y 76 | 0x00,0x00,0x07,0x0F,0x78,0x78,0x0F,0x07, 77 | // ! 78 | 0x00,0x00,0x40,0x1C,0x0F,0x07,0x03,0x00, 79 | 80 | // 0 81 | 0x7C,0x82,0x7C,0x00, 82 | // 1 83 | 0x84,0xFE,0x80,0x00, 84 | // 2 85 | 0xC4,0xA2,0x1C,0x00, 86 | // 3 87 | 0x44,0x92,0x6C,0x00, 88 | // 4 89 | 0x3E,0x20,0xF8,0x00, 90 | // 5 91 | 0x9E,0x92,0x62,0x00, 92 | // 6 93 | 0x7C,0x92,0x60,0x00, 94 | // 7 95 | 0x02,0xE2,0x1E,0x00, 96 | // 8 97 | 0x6C,0x92,0x6C,0x00, 98 | // 9 99 | 0x8C,0x92,0x7C,0x00, 100 | 101 | }; 102 | 103 | const uint8_t digitGlyphs [] PROGMEM = { 104 | // 0 105 | 0x7C,0x82,0x7C, 106 | // 1 107 | 0x84,0xFE,0x80, 108 | // 2 109 | 0xC4,0xA2,0x1C, 110 | // 3 111 | 0x44,0x92,0x6C, 112 | // 4 113 | 0x3E,0x20,0xF8, 114 | // 5 115 | 0x9E,0x92,0x62, 116 | // 6 117 | 0x7C,0x92,0x60, 118 | // 7 119 | 0x02,0xE2,0x1E, 120 | // 8 121 | 0x6C,0x92,0x6C, 122 | // 9 123 | 0x8C,0x92,0x7C, 124 | }; 125 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | SSD1306Device KEYWORD1 9 | DCfont KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | switchRenderFrame KEYWORD2 16 | switchDisplayFrame KEYWORD2 17 | switchFrame KEYWORD2 18 | currentRenderFrame KEYWORD2 19 | currentDisplayFrame KEYWORD2 20 | setFont KEYWORD2 21 | setFontX2 KEYWORD2 22 | setFontX2Smooth KEYWORD2 23 | setUnicodeFont KEYWORD2 24 | setUnicodeFontX2 KEYWORD2 25 | setUnicodeFontX2Smooth KEYWORD2 26 | setFontOnly KEYWORD2 27 | setSpacing KEYWORD2 28 | setCombineFunction KEYWORD2 29 | getExpectedUtf8Bytes KEYWORD2 30 | getCharacterDataOffset KEYWORD2 31 | getCharacterWidth KEYWORD2 32 | getTextWidth KEYWORD2 33 | setCursor KEYWORD2 34 | getCursorX KEYWORD2 35 | getCursorY KEYWORD2 36 | newLine KEYWORD2 37 | fill KEYWORD2 38 | fillToEOL KEYWORD2 39 | fillToEOP KEYWORD2 40 | fillLength KEYWORD2 41 | clear KEYWORD2 42 | clearToEOL KEYWORD2 43 | clearToEOP KEYWORD2 44 | bitmap KEYWORD2 45 | startData KEYWORD2 46 | sendData KEYWORD2 47 | repeatData KEYWORD2 48 | clearData KEYWORD2 49 | endData KEYWORD2 50 | setPages KEYWORD2 51 | setWidth KEYWORD2 52 | setHeight KEYWORD2 53 | setOffset KEYWORD2 54 | setRotation KEYWORD2 55 | clipText KEYWORD2 56 | clipTextP KEYWORD2 57 | invertOutput KEYWORD2 58 | ####################################### 59 | # SSD1306 1. Fundamental Command Table (KEYWORD2) 60 | ####################################### 61 | setContrast KEYWORD2 62 | setEntireDisplayOn KEYWORD2 63 | setInverse KEYWORD2 64 | setExternalIref KEYWORD2 65 | setInternalIref KEYWORD2 66 | off KEYWORD2 67 | on KEYWORD2 68 | ####################################### 69 | # SSD1306 2. Scrolling Command Table (KEYWORD2) 70 | ####################################### 71 | scrollRight KEYWORD2 72 | scrollLeft KEYWORD2 73 | scrollRightOffset KEYWORD2 74 | scrollLeftOffset KEYWORD2 75 | scrollContentRight KEYWORD2 76 | scrollContentLeft KEYWORD2 77 | deactivateScroll KEYWORD2 78 | activateScroll KEYWORD2 79 | setVerticalScrollArea KEYWORD2 80 | ####################################### 81 | # SSD1306 3. Addressing Setting Command Table (KEYWORD2) 82 | ####################################### 83 | setColumnStartAddress KEYWORD2 84 | setMemoryAddressingMode KEYWORD2 85 | setColumnAddress KEYWORD2 86 | setPageAddress KEYWORD2 87 | setPageStartAddress KEYWORD2 88 | ####################################### 89 | # SSD1306 4. Hardware Configuration (Panel resolution and layout related) Command Table (KEYWORD2) 90 | ####################################### 91 | setDisplayStartLine KEYWORD2 92 | setSegmentRemap KEYWORD2 93 | setMultiplexRatio KEYWORD2 94 | setComOutputDirection KEYWORD2 95 | setDisplayOffset KEYWORD2 96 | setComPinsHardwareConfiguration KEYWORD2 97 | ####################################### 98 | # SSD1306 5. Timing and Driving Scheme Setting Command Table (KEYWORD2) 99 | ####################################### 100 | setDisplayClock KEYWORD2 101 | setPrechargePeriod KEYWORD2 102 | setVcomhDeselectLevel KEYWORD2 103 | nop KEYWORD2 104 | ####################################### 105 | # SSD1306 6. Advance Graphic Command Table (KEYWORD2) 106 | ####################################### 107 | fadeOut KEYWORD2 108 | blink KEYWORD2 109 | disableFadeOutAndBlinking KEYWORD2 110 | enableZoomIn KEYWORD2 111 | disableZoomIn KEYWORD2 112 | ####################################### 113 | # SSD1306 Charge Pump Settings (KEYWORD2) 114 | ####################################### 115 | enableChargePump KEYWORD2 116 | disableChargePump KEYWORD2 117 | ####################################### 118 | # Instances (KEYWORD2) 119 | ####################################### 120 | oled KEYWORD2 121 | ####################################### 122 | # Constants (LITERAL1) 123 | ####################################### 124 | FONT6X8 LITERAL1 125 | FONT8X16 LITERAL1 126 | FONT8X16DIGITS LITERAL1 127 | FONT6X8P LITERAL1 128 | FONT8X16P LITERAL1 129 | FONT8X16CAPS LITERAL1 130 | FONT8X16CAPSP LITERAL1 131 | SSD1306_VOLTAGE_6_0 LITERAL1 132 | SSD1306_VOLTAGE_7_5 LITERAL1 133 | SSD1306_VOLTAGE_8_5 LITERAL1 134 | SSD1306_VOLTAGE_9_0 LITERAL1 135 | -------------------------------------------------------------------------------- /examples/DatacuteBoxyFont/DatacuteBoxyFont.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | //#include 14 | 15 | // To use the Adafruit's TinyWireM library: 16 | //#include 17 | 18 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 19 | //#include 20 | 21 | // The blue OLED screen requires a long initialization on power on. 22 | // The code to wait for it to be ready uses 20 bytes of program storage space 23 | // If you are using a white OLED, this can be reclaimed by uncommenting 24 | // the following line (before including Tiny4kOLED.h): 25 | //#define TINY4KOLED_QUICK_BEGIN 26 | 27 | #include 28 | #include "boxyfont.h" 29 | // ============================================================================ 30 | 31 | const char datacute1[17] = {(char)214,(char)196,(char)196,(char)191,(char)175,(char)175,(char)186,(char)175,(char)175,(char)175,(char)175,(char)175,(char)175,(char)186,(char)175,(char)175,(char)0}; 32 | const char datacute2[17] = {(char)186,(char)175,(char)175,(char)179,(char)218,(char)210,(char)215,(char)194,(char)183,(char)214,(char)196,(char)175,(char)196,(char)215,(char)210,(char)191,(char)0}; 33 | const char datacute3[17] = {(char)186,(char)175,(char)175,(char)179,(char)218,(char)182,(char)186,(char)218,(char)182,(char)186,(char)175,(char)179,(char)186,(char)186,(char)199,(char)217,(char)0}; 34 | const char datacute4[17] = {(char)211,(char)196,(char)196,(char)217,(char)192,(char)208,(char)208,(char)192,(char)208,(char)211,(char)196,(char)192,(char)208,(char)208,(char)211,(char)217,(char)0}; 35 | 36 | const char boxes1[16] = {(char)218,(char)194,(char)191,(char)175,(char)201,(char)203,(char)187,(char)175,(char)213,(char)209,(char)184,(char)175,(char)214,(char)210,(char)183,(char)0}; 37 | const char boxes2[16] = {(char)195,(char)197,(char)180,(char)175,(char)204,(char)206,(char)185,(char)175,(char)198,(char)216,(char)181,(char)175,(char)199,(char)215,(char)182,(char)0}; 38 | const char boxes3[16] = {(char)192,(char)193,(char)217,(char)175,(char)200,(char)202,(char)188,(char)175,(char)212,(char)207,(char)190,(char)175,(char)211,(char)208,(char)189,(char)0}; 39 | const char boxes4[16] = {(char)176,(char)177,(char)178,(char)219,(char)175,(char)220,(char)223,(char)175,(char)221,(char)222,(char)175,(char)196,(char)179,(char)205,(char)186,(char)0}; 40 | 41 | void setup() { 42 | // put your setup code here, to run once: 43 | 44 | oled.begin(); 45 | 46 | // Two rotations are supported, 47 | // The begin() method sets the rotation to 1. 48 | //oled.setRotation(0); 49 | 50 | // Some newer devices do not contain an external current reference. 51 | // Older devices may also support using the internal curret reference, 52 | // which provides more consistent brightness across devices. 53 | // The internal current reference can be configured as either low current, or high current. 54 | // Using true as the parameter value choses the high current internal current reference, 55 | // resulting in a brighter display, and a more effective contrast setting. 56 | //oled.setInternalIref(true); 57 | 58 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 59 | // Other fonts are available from the TinyOLED-Fonts library 60 | // This example shows how to create and use your own font. 61 | // The font used here is of the codepage 437 box drawing characters. 62 | oled.setFont(&cp_437_box_drawing_font); 63 | datacute(); 64 | oled.on(); 65 | oled.switchRenderFrame(); 66 | boxes(); 67 | } 68 | 69 | void loop() { 70 | delay(10000); 71 | oled.switchDisplayFrame(); 72 | } 73 | 74 | void datacute() { 75 | oled.clear(); 76 | oled.setCursor(0, 0); 77 | oled.print(datacute1); 78 | oled.setCursor(0, 1); 79 | oled.print(datacute2); 80 | oled.setCursor(0, 2); 81 | oled.print(datacute3); 82 | oled.setCursor(0, 3); 83 | oled.print(datacute4); 84 | } 85 | 86 | void boxes() { 87 | oled.clear(); 88 | oled.setCursor(4, 0); 89 | oled.print(boxes1); 90 | oled.setCursor(4, 1); 91 | oled.print(boxes2); 92 | oled.setCursor(4, 2); 93 | oled.print(boxes3); 94 | oled.setCursor(4, 3); 95 | oled.print(boxes4); 96 | } 97 | -------------------------------------------------------------------------------- /src/font6x8caps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 6x8 font */ 25 | const uint8_t ssd1306xled_font6x8_caps [] PROGMEM = { 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 27 | 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // ! 1 28 | 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // " 2 29 | 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 3 30 | 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 4 31 | 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, // % 5 32 | 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // & 6 33 | 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // ' 7 34 | 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // ( 8 35 | 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ) 9 36 | 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // * 10 37 | 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // + 11 38 | 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // , 12 39 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 13 40 | 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // . 14 41 | 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 15 42 | 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16 43 | 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 17 44 | 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 18 45 | 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19 46 | 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20 47 | 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 21 48 | 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22 49 | 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 23 50 | 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 24 51 | 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25 52 | 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // : 26 53 | 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ; 27 54 | 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // < 28 55 | 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // = 29 56 | 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // > 30 57 | 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ? 31 58 | 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32 59 | 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33 60 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B 34 61 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C 35 62 | 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36 63 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E 37 64 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F 38 65 | 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39 66 | 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40 67 | 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I 41 68 | 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J 42 69 | 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K 43 70 | 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L 44 71 | 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45 72 | 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46 73 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47 74 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P 48 75 | 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49 76 | 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R 50 77 | 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S 51 78 | 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T 52 79 | 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53 80 | 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54 81 | 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55 82 | 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X 56 83 | 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y 57 84 | 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z 58 85 | 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [ 59 86 | 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // \ 60 87 | 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ] 61 88 | 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62 89 | 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 63 90 | }; 91 | 92 | // ---------------------------------------------------------------------------- 93 | 94 | const DCfont TinyOLED4kfont6x8Caps = { 95 | (uint8_t *)ssd1306xled_font6x8_caps, 96 | 6, // character width in pixels 97 | 1, // character height in pages (8 pixels) 98 | 32,95, // ASCII extents 99 | 0,0,0 // Unused for fixed width fonts 100 | }; 101 | 102 | // for backwards compatibility 103 | #define FONT6X8CAPS (&TinyOLED4kfont6x8Caps) 104 | -------------------------------------------------------------------------------- /examples/ScrollingExample/ScrollingExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows how the scrolling features work. 8 | * When scrolling, the double buffering of screens cannot be used. 9 | * 10 | */ 11 | 12 | // Choose your I2C implementation before including Tiny4kOLED.h 13 | // The default is selected is Wire.h 14 | 15 | // To use the Wire library: 16 | //#include 17 | 18 | // To use the Adafruit's TinyWireM library: 19 | //#include 20 | 21 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 22 | //#include 23 | 24 | // The blue OLED screen requires a long initialization on power on. 25 | // The code to wait for it to be ready uses 20 bytes of program storage space 26 | // If you are using a white OLED, this can be reclaimed by uncommenting 27 | // the following line (before including Tiny4kOLED.h): 28 | //#define TINY4KOLED_QUICK_BEGIN 29 | 30 | #include 31 | 32 | void setup() { 33 | oled.begin(); 34 | 35 | // Two rotations are supported, 36 | // The begin() method sets the rotation to 1. 37 | //oled.setRotation(0); 38 | 39 | // Some newer devices do not contain an external current reference. 40 | // Older devices may also support using the internal curret reference, 41 | // which provides more consistent brightness across devices. 42 | // The internal current reference can be configured as either low current, or high current. 43 | // Using true as the parameter value choses the high current internal current reference, 44 | // resulting in a brighter display, and a more effective contrast setting. 45 | //oled.setInternalIref(true); 46 | 47 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 48 | // Other fonts are available from the TinyOLED-Fonts library 49 | oled.setFont(FONT6X8); 50 | 51 | // To clear all the memory, clear both rendering frames: 52 | oled.clear(); 53 | oled.switchRenderFrame(); 54 | oled.clear(); 55 | oled.switchRenderFrame(); 56 | 57 | // The SSD1306 refers to 8 rows of pixels as a 'page' 58 | 59 | // Page 0: One line of text at the top that is not scrolling 60 | oled.setCursor(13,0); // 13 pixels to center the following text 61 | oled.print(F("Scrolling Example")); // 17 characters x 6 pixels = 102 pixels 62 | 63 | // Page 1: One lines of graphics 64 | // For this example, the scrolled area is set up below to start after 11 rows. 65 | // The top three rows of pixels in this page are not scrolling 66 | // The bottom five rows of pixels are scrolling vertically 67 | oled.setCursor(0,1); 68 | oled.fillToEOL(0x02); 69 | 70 | // Pages 2 to 6: Five lines of text that are scrolling vertically 71 | oled.setCursor(0,2); 72 | oled.print(F("Top eleven rows fixed")); 73 | oled.setCursor(0,3); 74 | oled.print(F("Fifty rows vertically")); 75 | oled.setCursor(0,4); 76 | oled.print(F("+ 5 rows horizontally")); 77 | oled.setCursor(0,5); 78 | oled.print(F("Tiny4kOLED example by")); 79 | oled.setCursor(80,6); 80 | oled.print(F("Datacute")); 81 | 82 | // Page 7: Graphics at the bottom. 83 | // This page of 8 rows of pixels is all scrolling horizontally 84 | // For this example, the vertical scroll only extends down 5 rows into this page. 85 | // The effect is that it looks like only 5 rows are scrolling horizontally. 86 | // Consequently none of the data bytes below are larger than 0x1F 87 | oled.setCursor(0,7); 88 | oled.startData(); 89 | for (uint8_t i = 0; i < 16; i++) { 90 | oled.sendData(0x02); 91 | oled.sendData(0x02); 92 | oled.sendData(0x02); 93 | oled.sendData(0x0C); 94 | oled.sendData(0x10); 95 | oled.sendData(0x10); 96 | oled.sendData(0x10); 97 | oled.sendData(0x0C); 98 | } 99 | oled.endData(); 100 | 101 | // Scroll the bottom graphics on page 7 102 | // 'interval' is how quickly it scrolls. 103 | // 'offset' determines how far to scroll vertically for each horizontal movement 104 | // startPage = 7, interval = 1, endPage = 7, offset = 1 105 | oled.scrollLeftOffset(7,1,7,1); 106 | // 11 rows in the top fixed (non-scrolling) area 107 | // Vertically scroll 50 rows 108 | // The remaining 3 rows are not included in the scroll, and are never visible. 109 | oled.setVerticalScrollArea(11, 50); 110 | oled.activateScroll(); 111 | oled.on(); 112 | } 113 | 114 | void loop() { 115 | // The scrolling happens automatically, and is performed by rearranging the RAM contents. 116 | } 117 | -------------------------------------------------------------------------------- /examples/DoubleBufferedMillis/DoubleBufferedMillis.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | // This example compiles to 4402 bytes of program storage space 14 | // and 88 bytes of dynamic memory. 15 | //#include 16 | 17 | // To use the Adafruit's TinyWireM library: 18 | // (Saves about 350 bytes and 20 bytes of RAM over Wire.h) 19 | // (If you see a strange dot pattern then upgrade the TinyWireM 20 | // library to get the buffer overflow fix.) 21 | //#include 22 | 23 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 24 | // (Saves about 570 bytes and 40 bytes of RAM over Wire.h) 25 | //#include 26 | 27 | // The blue OLED screen requires a long initialization on power on. 28 | // The code to wait for it to be ready uses 20 bytes of program storage space 29 | // If you are using a white OLED, this can be reclaimed by uncommenting 30 | // the following line (before including Tiny4kOLED.h): 31 | //#define TINY4KOLED_QUICK_BEGIN 32 | 33 | #include 34 | 35 | // ============================================================================ 36 | 37 | // This example simply shows the number of milliseconds since reset 38 | // To show the double-buffering effect, the location where the timer 39 | // is displayed moves left and right, and the screen is completely cleared. 40 | 41 | // The number increases, so if the location was not moving, 42 | // we would not need to repeatedly clear and initialize the display. 43 | // But we are doing so to demonstrate the capability of the double 44 | // buffering code to result in a smooth animation 45 | 46 | // Uncomment this line to disable the code performing the double buffering 47 | //#define NO_DOUBLE_BUFFERING 48 | 49 | uint8_t location = 0; 50 | bool leftToRight = true; 51 | 52 | void setup() { 53 | // Send the initialization sequence to the oled. This leaves the display turned off. 54 | oled.begin(); 55 | 56 | // Two rotations are supported, 57 | // The begin() method sets the rotation to 1. 58 | //oled.setRotation(0); 59 | 60 | // Some newer devices do not contain an external current reference. 61 | // Older devices may also support using the internal curret reference, 62 | // which provides more consistent brightness across devices. 63 | // The internal current reference can be configured as either low current, or high current. 64 | // Using true as the parameter value choses the high current internal current reference, 65 | // resulting in a brighter display, and a more effective contrast setting. 66 | //oled.setInternalIref(true); 67 | 68 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 69 | // Other fonts are available from the TinyOLED-Fonts library 70 | // This example only uses a single font, so it can be set once here. 71 | // The characters in the 8x16 font are 8 pixels wide and 16 pixels tall. 72 | // 2 lines of 16 characters exactly fills 128x32. 73 | oled.setFont(FONT8X16); 74 | // Setup the first half of memory. 75 | updateDisplay(); 76 | #ifndef NO_DOUBLE_BUFFERING 77 | // Switch the half of RAM that we are writing to, to be the half that is non currently displayed. 78 | oled.switchRenderFrame(); 79 | // Setup the second half of memory. 80 | updateDisplay(); 81 | // Switch back to being ready to render on the first frame while displaying the second frame. 82 | oled.switchFrame(); 83 | #endif 84 | // Turn on the display. 85 | oled.on(); 86 | } 87 | 88 | void loop() { 89 | delay(50); 90 | if (leftToRight) { 91 | location++; 92 | if (location == 60) { 93 | leftToRight = false; 94 | } 95 | } else { 96 | location--; 97 | if (location == 0) { 98 | leftToRight = true; 99 | } 100 | } 101 | updateDisplay(); 102 | #ifndef NO_DOUBLE_BUFFERING 103 | // Swap which half of RAM is being written to, and which half is being displayed. 104 | // This is equivalent to calling both switchRenderFrame and switchDisplayFrame. 105 | // To see the benefit of double buffering, try this code again with this line commented out. 106 | oled.switchFrame(); 107 | #endif 108 | } 109 | 110 | void updateDisplay() { 111 | // Clear whatever random data has been left in memory. 112 | oled.clear(); 113 | // Position the text cursor 114 | // In order to keep the library size small, text can only be positioned 115 | // with the top of the font aligned with one of the four 8 bit high RAM pages. 116 | // The Y value therefore can only have the value 0, 1, 2, or 3. 117 | // usage: oled.setCursor(X IN PIXELS, Y IN ROWS OF 8 PIXELS STARTING WITH 0); 118 | oled.setCursor(location, 0); 119 | // Write text to oled RAM. 120 | oled.print(F("ms:")); 121 | // Write the number of milliseconds since power on. 122 | oled.print(millis()); 123 | // Write it again 124 | oled.setCursor(location, 2); 125 | oled.print(F("ms:")); 126 | oled.print(millis()); 127 | } 128 | -------------------------------------------------------------------------------- /examples/DoubleBufferedDisplay/DoubleBufferedDisplay.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | // This example compiles to 4402 bytes of program storage space 14 | // and 88 bytes of dynamic memory. 15 | //#include 16 | 17 | // To use the Adafruit's TinyWireM library: 18 | // (Saves about 350 bytes and 20 bytes of RAM over Wire.h) 19 | // (If you see a strange dot pattern then upgrade the TinyWireM 20 | // library to get the buffer overflow fix.) 21 | //#include 22 | 23 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 24 | // (Saves about 570 bytes and 40 bytes of RAM over Wire.h) 25 | //#include 26 | 27 | // The blue OLED screen requires a long initialization on power on. 28 | // The code to wait for it to be ready uses 20 bytes of program storage space 29 | // If you are using a white OLED, this can be reclaimed by uncommenting 30 | // the following line (before including Tiny4kOLED.h): 31 | //#define TINY4KOLED_QUICK_BEGIN 32 | 33 | #include 34 | 35 | // ============================================================================ 36 | 37 | void setup() { 38 | // Put your own setup code here, to run once. 39 | 40 | // Send the initialization sequence to the oled. This leaves the display turned off 41 | oled.begin(); 42 | 43 | // Two rotations are supported, 44 | // The begin() method sets the rotation to 1. 45 | //oled.setRotation(0); 46 | 47 | // Some newer devices do not contain an external current reference. 48 | // Older devices may also support using the internal curret reference, 49 | // which provides more consistent brightness across devices. 50 | // The internal current reference can be configured as either low current, or high current. 51 | // Using true as the parameter value choses the high current internal current reference, 52 | // resulting in a brighter display, and a more effective contrast setting. 53 | //oled.setInternalIref(true); 54 | 55 | // Clear the memory before turning on the display 56 | oled.clear(); 57 | 58 | // Turn on the display 59 | oled.on(); 60 | 61 | // Switch the half of RAM that we are writing to, to be the half that is non currently displayed 62 | oled.switchRenderFrame(); 63 | } 64 | 65 | void loop() { 66 | // put your main code here, to run repeatedly: 67 | 68 | /* ------------------------------ 69 | * Show screen with all pixels ON 70 | * ------------------------------ 71 | */ 72 | 73 | // Fill screen with color 74 | // As we're setting every pixel, there is no need to clear the previous contents. 75 | oled.fill(0xFF); 76 | 77 | // Swap which half of RAM is being written to, and which half is being displayed 78 | // This is equivalent to calling both switchRenderFrame and switchDisplayFrame 79 | oled.switchFrame(); 80 | 81 | delay(1000); 82 | 83 | /* ------------------------------- 84 | * Show screen with all pixels OFF 85 | * ------------------------------- 86 | */ 87 | 88 | // Clear the non-displayed half of the memory to all black 89 | oled.clear(); 90 | 91 | // Swap which half of RAM is being written to, and which half is being displayed 92 | oled.switchFrame(); 93 | 94 | delay(1000); 95 | 96 | /* ----------------------------------------- 97 | * Show screen with two different font sizes 98 | * ----------------------------------------- 99 | */ 100 | 101 | // Clear the non-displayed half of the memory to all black 102 | // (The previous clear only cleared the other half of RAM) 103 | oled.clear(); 104 | 105 | // The characters in the 8x16 font are 8 pixels wide and 16 pixels tall 106 | // 2 lines of 16 characters exactly fills 128x32 107 | oled.setFont(FONT8X16); 108 | 109 | // Position the cusror 110 | // usage: oled.setCursor(X IN PIXELS, Y IN ROWS OF 8 PIXELS STARTING WITH 0); 111 | oled.setCursor(32, 0); 112 | 113 | // Write the text to oled RAM (which is not currently being displayed) 114 | // Wrap strings in F() to save RAM! 115 | oled.print(F("Datacute")); 116 | 117 | // The characters in the 6x8 font are 6 pixels wide and 8 pixels tall 118 | // 4 lines of 21 characters only fills 126x32 119 | oled.setFont(FONT6X8); 120 | 121 | // Position the cusror 122 | // Two rows down because the 8x16 font used for the last text takes two rows of 8 pixels 123 | oled.setCursor(13, 2); 124 | 125 | // Write the text to oled RAM (which is not currently being displayed) 126 | oled.print(F("Acute Information")); 127 | 128 | // Position the cusror 129 | // Cursor X is in pixels, and does not need to be a multiple of the font width 130 | oled.setCursor(16, 3); 131 | 132 | // Write the text to oled RAM (which is not currently being displayed) 133 | oled.print(F("Revelation Tools")); 134 | 135 | // Swap which half of RAM is being written to, and which half is being displayed 136 | oled.switchFrame(); 137 | 138 | delay(3000); 139 | } 140 | -------------------------------------------------------------------------------- /examples/DoubleBufferedMillis128x64/DoubleBufferedMillis128x64.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | // Choose your I2C implementation before including Tiny4kOLED.h 10 | // The default is selected is Wire.h 11 | 12 | // To use the Wire library: 13 | // This example compiles to 4402 bytes of program storage space 14 | // and 88 bytes of dynamic memory. 15 | //#include 16 | 17 | // To use the Adafruit's TinyWireM library: 18 | // (Saves about 350 bytes and 20 bytes of RAM over Wire.h) 19 | // (If you see a strange dot pattern then upgrade the TinyWireM 20 | // library to get the buffer overflow fix.) 21 | //#include 22 | 23 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 24 | // (Saves about 570 bytes and 40 bytes of RAM over Wire.h) 25 | //#include 26 | 27 | // The blue OLED screen requires a long initialization on power on. 28 | // The code to wait for it to be ready uses 20 bytes of program storage space 29 | // If you are using a white OLED, this can be reclaimed by uncommenting 30 | // the following line (before including Tiny4kOLED.h): 31 | //#define TINY4KOLED_QUICK_BEGIN 32 | 33 | #include 34 | 35 | // ============================================================================ 36 | 37 | // This example simply shows the number of milliseconds since reset 38 | // To show the double-buffering effect, the location where the timer 39 | // is displayed moves left and right, and the screen is completely cleared. 40 | 41 | // The number increases, so if the location was not moving, 42 | // we would not need to repeatedly clear and initialize the display. 43 | // But we are doing so to demonstrate the capability of the double 44 | // buffering code to result in a smooth animation 45 | 46 | // Uncomment this line to disable the code performing the double buffering 47 | //#define NO_DOUBLE_BUFFERING 48 | 49 | uint8_t location = 0; 50 | bool leftToRight = true; 51 | 52 | void setup() { 53 | // Initialize the wire library, but do not send any initialization sequence to the oled. 54 | // This leaves the screen area being the default for 128x64 screens 55 | oled.begin(0,0); 56 | 57 | // The default state of the SSD1306 does not turn on the internal charge pump 58 | oled.enableChargePump(); 59 | 60 | // Two rotations are supported, 61 | // The begin() method sets the rotation to 1, 62 | // but the begin(0,0) method doe not include that initialization. 63 | oled.setRotation(1); 64 | 65 | // Some newer devices do not contain an external current reference. 66 | // Older devices may also support using the internal curret reference, 67 | // which provides more consistent brightness across devices. 68 | // The internal current reference can be configured as either low current, or high current. 69 | // Using true as the parameter value choses the high current internal current reference, 70 | // resulting in a brighter display, and a more effective contrast setting. 71 | //oled.setInternalIref(true); 72 | 73 | // In order to use double buffering on the 128x64 screen, 74 | // the zoom feature needs to be used, which doubles the height 75 | // of all pixels. 76 | oled.enableZoomIn(); 77 | 78 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 79 | // Other fonts are available from the TinyOLED-Fonts library 80 | // This example only uses a single font, so it can be set once here. 81 | // The characters in the 8x16 font are 8 pixels wide and 16 pixels tall. 82 | // 2 lines of 16 characters exactly fills 128x32. 83 | oled.setFont(FONT8X16); 84 | 85 | // Setup the first half of memory. 86 | updateDisplay(); 87 | 88 | #ifndef NO_DOUBLE_BUFFERING 89 | 90 | // Switch the half of RAM that we are writing to, to be the half that is non currently displayed. 91 | oled.switchRenderFrame(); 92 | 93 | // Setup the second half of memory. 94 | updateDisplay(); 95 | 96 | // Switch back to being ready to render on the first frame while displaying the second frame. 97 | oled.switchFrame(); 98 | 99 | #endif 100 | 101 | // Turn on the display. 102 | oled.on(); 103 | } 104 | 105 | void loop() { 106 | delay(50); 107 | if (leftToRight) { 108 | location++; 109 | if (location == 60) { 110 | leftToRight = false; 111 | } 112 | } else { 113 | location--; 114 | if (location == 0) { 115 | leftToRight = true; 116 | } 117 | } 118 | updateDisplay(); 119 | 120 | #ifndef NO_DOUBLE_BUFFERING 121 | 122 | // Swap which half of RAM is being written to, and which half is being displayed. 123 | // This is equivalent to calling both switchRenderFrame and switchDisplayFrame. 124 | // To see the benefit of double buffering, try this code again with this line commented out. 125 | oled.switchFrame(); 126 | 127 | #endif 128 | } 129 | 130 | void updateDisplay() { 131 | // Clear whatever random data has been left in memory. 132 | oled.clear(); 133 | 134 | // Position the text cursor 135 | // In order to keep the library size small, text can only be positioned 136 | // with the top of the font aligned with one of the four 8 bit high RAM pages. 137 | // The Y value therefore can only have the value 0, 1, 2, or 3. 138 | // usage: oled.setCursor(X IN PIXELS, Y IN ROWS OF 8 PIXELS STARTING WITH 0); 139 | oled.setCursor(location, 0); 140 | 141 | // Write text to oled RAM. 142 | oled.print(F("ms:")); 143 | 144 | // Write the number of milliseconds since power on. 145 | oled.print(millis()); 146 | 147 | // Write it again 148 | oled.setCursor(location, 2); 149 | oled.print(F("ms:")); 150 | oled.print(millis()); 151 | } 152 | -------------------------------------------------------------------------------- /src/font6x8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 6x8 font */ 25 | const uint8_t ssd1306xled_font6x8 [] PROGMEM = { 26 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 27 | 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // ! 1 28 | 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // " 2 29 | 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 3 30 | 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 4 31 | 0x00, 0x23, 0x13, 0x08, 0x64, 0x62, // % 5 32 | 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // & 6 33 | 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // ' 7 34 | 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // ( 8 35 | 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ) 9 36 | 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // * 10 37 | 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // + 11 38 | 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // , 12 39 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 13 40 | 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // . 14 41 | 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 15 42 | 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16 43 | 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 17 44 | 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 18 45 | 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19 46 | 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20 47 | 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 21 48 | 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22 49 | 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 23 50 | 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 24 51 | 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25 52 | 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // : 26 53 | 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ; 27 54 | 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // < 28 55 | 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // = 29 56 | 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // > 30 57 | 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ? 31 58 | 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32 59 | 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33 60 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B 34 61 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C 35 62 | 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36 63 | 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E 37 64 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F 38 65 | 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39 66 | 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40 67 | 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I 41 68 | 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J 42 69 | 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K 43 70 | 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L 44 71 | 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45 72 | 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46 73 | 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47 74 | 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P 48 75 | 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49 76 | 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R 50 77 | 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S 51 78 | 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T 52 79 | 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53 80 | 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54 81 | 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55 82 | 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X 56 83 | 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y 57 84 | 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z 58 85 | 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [ 59 86 | 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // \ 60 87 | 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ] 61 88 | 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62 89 | 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 63 90 | 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // ' 64 91 | 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a 65 92 | 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b 66 93 | 0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c 67 94 | 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d 68 95 | 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e 69 96 | 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f 70 97 | 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 71 98 | 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h 72 99 | 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i 73 100 | 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j 74 101 | 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k 75 102 | 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l 76 103 | 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m 77 104 | 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n 78 105 | 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o 79 106 | 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p 80 107 | 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q 81 108 | 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r 82 109 | 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s 83 110 | 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t 84 111 | 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 85 112 | 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 86 113 | 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 87 114 | 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x 88 115 | 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y 89 116 | 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z 90 117 | 0x00, 0x08, 0x36, 0x41, 0x41, 0x00, // { 91 118 | 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, // | 92 119 | 0x00, 0x00, 0x41, 0x41, 0x36, 0x08, // } 93 120 | 0x00, 0x08, 0x04, 0x08, 0x10, 0x08, // ~ 94 121 | }; 122 | 123 | // ---------------------------------------------------------------------------- 124 | 125 | const DCfont TinyOLED4kfont6x8 = { 126 | (uint8_t *)ssd1306xled_font6x8, 127 | 6, // character width in pixels 128 | 1, // character height in pages (8 pixels) 129 | 32,126, // ASCII extents 130 | 0,0,0 // Unused for fixed width fonts 131 | }; 132 | 133 | // for backwards compatibility 134 | #define FONT6X8 (&TinyOLED4kfont6x8) 135 | -------------------------------------------------------------------------------- /src/font6x8p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 6x8 proportional font */ 25 | const uint8_t Tiny4kOLED_font6x8 [] PROGMEM = { 26 | 0x00, 0x00, 0x00, 0x00, 0x00, // 0 27 | 0x2f, // ! 1 28 | 0x07, 0x00, 0x07, // " 2 29 | 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 3 30 | 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 4 31 | 0x23, 0x13, 0x08, 0x64, 0x62, // % 5 32 | 0x36, 0x49, 0x55, 0x22, 0x50, // & 6 33 | 0x05, 0x03, // ' 7 34 | 0x1c, 0x22, 0x41, // ( 8 35 | 0x41, 0x22, 0x1c, // ) 9 36 | 0x14, 0x08, 0x3E, 0x08, 0x14, // * 10 37 | 0x08, 0x08, 0x3E, 0x08, 0x08, // + 11 38 | 0xA0, 0x60, // , 12 39 | 0x08, 0x08, 0x08, 0x08, 0x08, // - 13 40 | 0x60, 0x60, // . 14 41 | 0x20, 0x10, 0x08, 0x04, 0x02, // / 15 42 | 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16 43 | 0x42, 0x7F, 0x40, // 1 17 44 | 0x42, 0x61, 0x51, 0x49, 0x46, // 2 18 45 | 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19 46 | 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20 47 | 0x27, 0x45, 0x45, 0x45, 0x39, // 5 21 48 | 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22 49 | 0x01, 0x71, 0x09, 0x05, 0x03, // 7 23 50 | 0x36, 0x49, 0x49, 0x49, 0x36, // 8 24 51 | 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25 52 | 0x36, 0x36, // : 26 53 | 0x56, 0x36, // ; 27 54 | 0x08, 0x14, 0x22, 0x41, // < 28 55 | 0x14, 0x14, 0x14, 0x14, 0x14, // = 29 56 | 0x41, 0x22, 0x14, 0x08, // > 30 57 | 0x02, 0x01, 0x51, 0x09, 0x06, // ? 31 58 | 0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32 59 | 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33 60 | 0x7F, 0x49, 0x49, 0x49, 0x36, // B 34 61 | 0x3E, 0x41, 0x41, 0x41, 0x22, // C 35 62 | 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36 63 | 0x7F, 0x49, 0x49, 0x49, 0x41, // E 37 64 | 0x7F, 0x09, 0x09, 0x09, 0x01, // F 38 65 | 0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39 66 | 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40 67 | 0x41, 0x7F, 0x41, // I 41 68 | 0x20, 0x40, 0x41, 0x3F, 0x01, // J 42 69 | 0x7F, 0x08, 0x14, 0x22, 0x41, // K 43 70 | 0x7F, 0x40, 0x40, 0x40, 0x40, // L 44 71 | 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45 72 | 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46 73 | 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47 74 | 0x7F, 0x09, 0x09, 0x09, 0x06, // P 48 75 | 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49 76 | 0x7F, 0x09, 0x19, 0x29, 0x46, // R 50 77 | 0x46, 0x49, 0x49, 0x49, 0x31, // S 51 78 | 0x01, 0x01, 0x7F, 0x01, 0x01, // T 52 79 | 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53 80 | 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54 81 | 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55 82 | 0x63, 0x14, 0x08, 0x14, 0x63, // X 56 83 | 0x07, 0x08, 0x70, 0x08, 0x07, // Y 57 84 | 0x61, 0x51, 0x49, 0x45, 0x43, // Z 58 85 | 0x7F, 0x41, 0x41, // [ 59 86 | 0x02, 0x04, 0x08, 0x10, 0x20, // \ 60 87 | 0x41, 0x41, 0x7F, // ] 61 88 | 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62 89 | 0x40, 0x40, 0x40, 0x40, 0x40, // _ 63 90 | 0x01, 0x02, 0x04, // ' 64 91 | 0x20, 0x54, 0x54, 0x54, 0x78, // a 65 92 | 0x7F, 0x48, 0x44, 0x44, 0x38, // b 66 93 | 0x38, 0x44, 0x44, 0x44, 0x20, // c 67 94 | 0x38, 0x44, 0x44, 0x48, 0x7F, // d 68 95 | 0x38, 0x54, 0x54, 0x54, 0x18, // e 69 96 | 0x08, 0x7E, 0x09, 0x01, 0x02, // f 70 97 | 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 71 98 | 0x7F, 0x08, 0x04, 0x04, 0x78, // h 72 99 | 0x44, 0x7D, 0x40, // i 73 100 | 0x40, 0x80, 0x84, 0x7D, // j 74 101 | 0x7F, 0x10, 0x28, 0x44, // k 75 102 | 0x41, 0x7F, 0x40, // l 76 103 | 0x7C, 0x04, 0x18, 0x04, 0x78, // m 77 104 | 0x7C, 0x08, 0x04, 0x04, 0x78, // n 78 105 | 0x38, 0x44, 0x44, 0x44, 0x38, // o 79 106 | 0xFC, 0x24, 0x24, 0x24, 0x18, // p 80 107 | 0x18, 0x24, 0x24, 0x18, 0xFC, // q 81 108 | 0x7C, 0x08, 0x04, 0x04, 0x08, // r 82 109 | 0x48, 0x54, 0x54, 0x54, 0x20, // s 83 110 | 0x04, 0x3F, 0x44, 0x40, 0x20, // t 84 111 | 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 85 112 | 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 86 113 | 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 87 114 | 0x44, 0x28, 0x10, 0x28, 0x44, // x 88 115 | 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y 89 116 | 0x44, 0x64, 0x54, 0x4C, 0x44, // z 90 117 | 0x08, 0x36, 0x41, 0x41, // { 91 118 | 0x7F, // | 92 119 | 0x41, 0x41, 0x36, 0x08, // } 93 120 | 0x08, 0x04, 0x08, 0x10, 0x08, // ~ 94 121 | }; 122 | 123 | const uint8_t Tiny4kOLED_font6x8_widths [] PROGMEM = { 124 | 5,1,3,5,5,5,5,2,3,3,5,5,2,5,2,5, 125 | 5,3,5,5,5,5,5,5,5,5,2,2,4,5,4,5, 126 | 5,5,5,5,5,5,5,5,5,3,5,5,5,5,5,5, 127 | 5,5,5,5,5,5,5,5,5,5,5,3,5,3,5,5, 128 | 3,5,5,5,5,5,5,5,5,3,4,4,3,5,5,5, 129 | 5,5,5,5,5,5,5,5,5,5,5,4,1,4,5 130 | }; 131 | 132 | const uint16_t Tiny4kOLED_font6x8_widths_16s [] PROGMEM = { 133 | 5+1+3+5+5+5+5+2+3+3+5+5+2+5+2+5, 134 | 5+3+5+5+5+5+5+5+5+5+2+2+4+5+4+5, 135 | 5+5+5+5+5+5+5+5+5+3+5+5+5+5+5+5, 136 | 5+5+5+5+5+5+5+5+5+5+5+3+5+3+5+5, 137 | 3+5+5+5+5+5+5+5+5+3+4+4+3+5+5+5, 138 | 5+5+5+5+5+5+5+5+5+5+5+4+1+4+5 139 | }; 140 | 141 | const DCfont Tiny4kOLEDfont6x8 = { 142 | (uint8_t *)Tiny4kOLED_font6x8, 143 | 0, // character width in pixels 144 | 1, // character height in pages (8 pixels) 145 | 32,126, // ASCII extents 146 | (uint16_t *)Tiny4kOLED_font6x8_widths_16s, 147 | (uint8_t *)Tiny4kOLED_font6x8_widths, 148 | 1 // spacing 149 | }; 150 | 151 | // for backwards compatibility 152 | #define FONT6X8P (&Tiny4kOLEDfont6x8) 153 | -------------------------------------------------------------------------------- /examples/ScrollingText/ScrollingText.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example shows how the scrolling features work. 8 | * When scrolling, the double buffering of screens cannot be used. 9 | * 10 | */ 11 | 12 | // Choose your I2C implementation before including Tiny4kOLED.h 13 | // The default is selected is Wire.h 14 | 15 | // To use the Wire library: 16 | //#include 17 | 18 | // To use the Adafruit's TinyWireM library: 19 | //#include 20 | 21 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 22 | //#include 23 | 24 | // The blue OLED screen requires a long initialization on power on. 25 | // The code to wait for it to be ready uses 20 bytes of program storage space 26 | // If you are using a white OLED, this can be reclaimed by uncommenting 27 | // the following line (before including Tiny4kOLED.h): 28 | //#define TINY4KOLED_QUICK_BEGIN 29 | 30 | #include 31 | 32 | // The F macro is not able to be used outside of methods. 33 | // The following two lines place a string in flash memory, 34 | // and get a reference to it as though it had been created as 35 | // F("This is an example of scrolling text. ") 36 | // while also allowing sizeof(textToScrollData) to return 37 | // the length of the string (including the null terminating character). 38 | const char textToScrollData[] PROGMEM = { "This is an example of scrolling text. " }; 39 | DATACUTE_F_MACRO_T * textToScroll = FPSTR(textToScrollData); 40 | 41 | uint16_t nextRowOfTextToDraw; 42 | 43 | void setup() { 44 | oled.begin(); 45 | 46 | // Two rotations are supported, 47 | // The begin() method sets the rotation to 1. 48 | //oled.setRotation(0); 49 | 50 | // Some newer devices do not contain an external current reference. 51 | // Older devices may also support using the internal curret reference, 52 | // which provides more consistent brightness across devices. 53 | // The internal current reference can be configured as either low current, or high current. 54 | // Using true as the parameter value choses the high current internal current reference, 55 | // resulting in a brighter display, and a more effective contrast setting. 56 | //oled.setInternalIref(true); 57 | 58 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 59 | // Other fonts are available from the TinyOLED-Fonts library 60 | oled.setFont(FONT8X16); 61 | 62 | // This example does not use the double buffering ability of 128x32 OLED screens 63 | // so the display should be set up, rather than just cleared, before turing on 64 | setupInitialDisplay(); 65 | 66 | // If the text to scroll needs to start on-screen, it can be initialized, 67 | // clipped to the scrolling window 68 | oled.setCursor(5, 1); 69 | // Start drawing the text from the beginning pixel, clip at 118 pixels. 70 | oled.clipText(0, 118, textToScroll); 71 | nextRowOfTextToDraw = 118; 72 | 73 | oled.on(); 74 | } 75 | 76 | void loop() { 77 | // Content scrolling is controlled by the microcontroller. 78 | // Each request to scroll content results in the content shifting one pixel left or right 79 | 80 | // The parameters are start page, end page, start column, end column 81 | oled.scrollContentLeft(1, 2, 5, 122); 82 | 83 | // However the scroll happens after the command is given, and a delay is required before 84 | // the edge of the scrolled content can be safely overwritten. 85 | // The length of the delay is 2 divided by the refresh rate. 86 | // So if the refresh rate is 100 Hz, then the delay required is 20ms. 87 | // Unfortunately the refresh rate is not easy to determine. 88 | // The SSD1306 is capable of refresh rates between 4 and 489 Hz. 89 | // The default refresh rate for a 128x32 screen is 215.5 Hz, requiring a delay of 9.3ms 90 | // The default refresh rate for a 128x64 screen is 107.8 Hz, requiring a delay of 18.6ms 91 | delay(10); 92 | 93 | // Draw one column of the text at the right hand end of the scrolling window. 94 | oled.setCursor(122, 1); 95 | oled.clipText(nextRowOfTextToDraw++, 1, textToScroll); 96 | 97 | // Wrap the text... 98 | // sizeof(textToScrollData) is 1 byte longer than the text 99 | // (in includes the end of string marker) 100 | // The font width is 8 pixels 101 | if (nextRowOfTextToDraw >= (sizeof(textToScrollData) - 1) * 8) { 102 | nextRowOfTextToDraw = 0; 103 | } 104 | 105 | // Fastest scrolling speed is slightly too quick, lets add another delay: 106 | delay(20); 107 | } 108 | 109 | void setupInitialDisplay() { 110 | // Draw a border around the screen, to demonstrate scrolling the region within it. 111 | oled.setCursor(0, 0); 112 | oled.startData(); 113 | oled.sendData(0xFF); 114 | oled.sendData(0xFF); 115 | oled.sendData(0x7F); 116 | oled.sendData(0x3F); 117 | oled.sendData(0x1F); 118 | oled.sendData(0x0F); 119 | oled.sendData(0x07); 120 | oled.repeatData(0x03, 128-14); 121 | oled.sendData(0x07); 122 | oled.sendData(0x0F); 123 | oled.sendData(0x1F); 124 | oled.sendData(0x3F); 125 | oled.sendData(0x7F); 126 | oled.sendData(0xFF); 127 | oled.sendData(0xFF); 128 | oled.endData(); 129 | 130 | oled.setCursor(0, 1); 131 | oled.startData(); 132 | oled.sendData(0xFF); 133 | oled.sendData(0xFF); 134 | oled.repeatData(0x00, 128-4); 135 | oled.sendData(0xFF); 136 | oled.sendData(0xFF); 137 | oled.endData(); 138 | 139 | oled.setCursor(0, 2); 140 | oled.startData(); 141 | oled.sendData(0xFF); 142 | oled.sendData(0xFF); 143 | oled.repeatData(0x00, 128-4); 144 | oled.sendData(0xFF); 145 | oled.sendData(0xFF); 146 | oled.endData(); 147 | 148 | oled.setCursor(0, 3); 149 | oled.startData(); 150 | oled.sendData(0xFF); 151 | oled.sendData(0xFF); 152 | oled.sendData(0xFE); 153 | oled.sendData(0xFC); 154 | oled.sendData(0xF8); 155 | oled.sendData(0xF0); 156 | oled.sendData(0xE0); 157 | oled.repeatData(0xC0, 128-14); 158 | oled.sendData(0xE0); 159 | oled.sendData(0xF0); 160 | oled.sendData(0xF8); 161 | oled.sendData(0xFC); 162 | oled.sendData(0xFE); 163 | oled.sendData(0xFF); 164 | oled.sendData(0xFF); 165 | oled.endData(); 166 | } 167 | -------------------------------------------------------------------------------- /src/font8x16caps.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 8x16 font */ 25 | const uint8_t ssd1306xled_font8x16_caps [] PROGMEM = { 26 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 27 | 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00, // ! 1 28 | 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // " 2 29 | 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00, // # 3 30 | 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00, // $ 4 31 | 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00, // % 5 32 | 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10, // & 6 33 | 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' 7 34 | 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00, // ( 8 35 | 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00, // ) 9 36 | 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00, // * 10 37 | 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00, // + 11 38 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00, // , 12 39 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, // - 13 40 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00, // . 14 41 | 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00, // / 15 42 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, // 0 16 43 | 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // 1 17 44 | 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, // 2 18 45 | 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, // 3 19 46 | 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, // 4 20 47 | 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, // 5 21 48 | 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, // 6 22 49 | 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, // 7 23 50 | 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, // 8 24 51 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, // 9 25 52 | 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, // : 26 53 | 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00, // ; 27 54 | 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00, // < 28 55 | 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00, // = 29 56 | 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00, // > 30 57 | 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00, // ? 31 58 | 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00, // @ 32 59 | 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, // A 33 60 | 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00, // B 34 61 | 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00, // C 35 62 | 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00, // D 36 63 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00, // E 37 64 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00, // F 38 65 | 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00, // G 39 66 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20, // H 40 67 | 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // I 41 68 | 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00, // J 42 69 | 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00, // K 43 70 | 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00, // L 44 71 | 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00, // M 45 72 | 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00, // N 46 73 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00, // O 47 74 | 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00, // P 48 75 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00, // Q 49 76 | 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20, // R 50 77 | 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00, // S 51 78 | 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00, // T 52 79 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, // U 53 80 | 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00, // V 54 81 | 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00, // W 55 82 | 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20, // X 56 83 | 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00, // Y 57 84 | 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00, // Z 58 85 | 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00, // [ 59 86 | 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00, // \ 60 87 | 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, // ] 61 88 | 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^ 62 89 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // _ 63 90 | }; 91 | 92 | // ---------------------------------------------------------------------------- 93 | 94 | const DCfont TinyOLED4kfont8x16Caps = { 95 | (uint8_t *)ssd1306xled_font8x16_caps, 96 | 8, // character width in pixels 97 | 2, // character height in pages (8 pixels) 98 | 32,95, // ASCII extents 99 | 0,0,0 // Unused for fixed width fonts 100 | }; 101 | 102 | // for backwards compatibility 103 | #define FONT8X16CAPS (&TinyOLED4kfont8x16Caps) 104 | -------------------------------------------------------------------------------- /src/font8x16capsp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 8x16 font */ 25 | const uint8_t Tiny4kOLED_font8x16_caps [] PROGMEM = { 26 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 27 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 28 | 29 | 0xF8,0x00, 30 | 0x33,0x30, // ! 1 31 | 32 | 0x10,0x0C,0x06,0x10,0x0C,0x06, 33 | 0x00,0x00,0x00,0x00,0x00,0x00, // " 2 34 | 35 | 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40, 36 | 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04, // # 3 37 | 38 | 0x70,0x88,0xFC,0x08,0x30, 39 | 0x18,0x20,0xFF,0x21,0x1E, // $ 4 40 | 41 | 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00, 42 | 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E, // % 5 43 | 44 | 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 45 | 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10, // & 6 46 | 47 | 0x10,0x16,0x0E, 48 | 0x00,0x00,0x00, // ' 7 49 | 50 | 0xE0,0x18,0x04,0x02, 51 | 0x07,0x18,0x20,0x40, // ( 8 52 | 53 | 0x02,0x04,0x18,0xE0, 54 | 0x40,0x20,0x18,0x07, // ) 9 55 | 56 | 0x40,0x40,0x80,0xF0,0x80,0x40,0x40, 57 | 0x02,0x02,0x01,0x0F,0x01,0x02,0x02, // * 10 58 | 59 | 60 | 0x00,0x00,0x00,0xF0,0x00,0x00,0x00, 61 | 0x01,0x01,0x01,0x1F,0x01,0x01,0x01, // + 11 62 | 63 | 0x00,0x00,0x00, 64 | 0x80,0xB0,0x70, // , 12 65 | 66 | 0x00,0x00,0x00,0x00,0x00,0x00, 67 | 0x01,0x01,0x01,0x01,0x01,0x01, // - 13 68 | 69 | 0x00,0x00, 70 | 0x30,0x30, // . 14 71 | 72 | 0x00,0x00,0x00,0x80,0x60,0x18,0x04, 73 | 0x60,0x18,0x06,0x01,0x00,0x00,0x00, // / 15 74 | 75 | 0xE0,0x10,0x08,0x08,0x10,0xE0, 76 | 0x0F,0x10,0x20,0x20,0x10,0x0F, // 0 16 77 | 78 | 0x10,0x10,0xF8,0x00,0x00, 79 | 0x20,0x20,0x3F,0x20,0x20, // 1 17 80 | 81 | 0x70,0x08,0x08,0x08,0x88,0x70, 82 | 0x30,0x28,0x24,0x22,0x21,0x30, // 2 18 83 | 84 | 0x30,0x08,0x88,0x88,0x48,0x30, 85 | 0x18,0x20,0x20,0x20,0x11,0x0E, // 3 19 86 | 87 | 0x00,0xC0,0x20,0x10,0xF8,0x00, 88 | 0x07,0x04,0x24,0x24,0x3F,0x24, // 4 20 89 | 90 | 0xF8,0x08,0x88,0x88,0x08,0x08, 91 | 0x19,0x21,0x20,0x20,0x11,0x0E, // 5 21 92 | 93 | 0xE0,0x10,0x88,0x88,0x18,0x00, 94 | 0x0F,0x11,0x20,0x20,0x11,0x0E, // 6 22 95 | 96 | 0x38,0x08,0x08,0xC8,0x38,0x08, 97 | 0x00,0x00,0x3F,0x00,0x00,0x00, // 7 23 98 | 99 | 0x70,0x88,0x08,0x08,0x88,0x70, 100 | 0x1C,0x22,0x21,0x21,0x22,0x1C, // 8 24 101 | 102 | 0xE0,0x10,0x08,0x08,0x10,0xE0, 103 | 0x00,0x31,0x22,0x22,0x11,0x0F, // 9 25 104 | 105 | 0xC0,0xC0, 106 | 0x30,0x30, // : 26 107 | 108 | 0x00,0x80, 109 | 0x80,0x60, // ; 27 110 | 111 | 0x00,0x80,0x40,0x20,0x10,0x08, 112 | 0x01,0x02,0x04,0x08,0x10,0x20, // < 28 113 | 114 | 0x40,0x40,0x40,0x40,0x40,0x40,0x40, 115 | 0x04,0x04,0x04,0x04,0x04,0x04,0x04, // = 29 116 | 117 | 0x08,0x10,0x20,0x40,0x80,0x00, 118 | 0x20,0x10,0x08,0x04,0x02,0x01, // > 30 119 | 120 | 0x70,0x48,0x08,0x08,0x08,0xF0, 121 | 0x00,0x00,0x30,0x36,0x01,0x00, // ? 31 122 | 123 | 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0, 124 | 0x07,0x18,0x27,0x24,0x23,0x14,0x0B, // @ 32 125 | 126 | 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 127 | 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, // A 33 128 | 129 | 0x08,0xF8,0x88,0x88,0x88,0x70,0x00, 130 | 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E, // B 34 131 | 132 | 0xC0,0x30,0x08,0x08,0x08,0x08,0x38, 133 | 0x07,0x18,0x20,0x20,0x20,0x10,0x08, // C 35 134 | 135 | 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0, 136 | 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F, // D 36 137 | 138 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10, 139 | 0x20,0x3F,0x20,0x20,0x23,0x20,0x18, // E 37 140 | 141 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10, 142 | 0x20,0x3F,0x20,0x00,0x03,0x00,0x00, // F 38 143 | 144 | 0xC0,0x30,0x08,0x08,0x08,0x38,0x00, 145 | 0x07,0x18,0x20,0x20,0x22,0x1E,0x02, // G 39 146 | 147 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 148 | 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20, // H 40 149 | 150 | 0x08,0x08,0xF8,0x08,0x08, 151 | 0x20,0x20,0x3F,0x20,0x20, // I 41 152 | 153 | 0x00,0x00,0x08,0x08,0xF8,0x08,0x08, 154 | 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00, // J 42 155 | 156 | 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08, 157 | 0x20,0x3F,0x20,0x01,0x26,0x38,0x20, // K 43 158 | 159 | 0x08,0xF8,0x08,0x00,0x00,0x00,0x00, 160 | 0x20,0x3F,0x20,0x20,0x20,0x20,0x30, // L 44 161 | 162 | 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08, 163 | 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20, // M 45 164 | 165 | 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 166 | 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00, // N 46 167 | 168 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0, 169 | 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F, // O 47 170 | 171 | 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0, 172 | 0x20,0x3F,0x21,0x01,0x01,0x01,0x00, // P 48 173 | 174 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0, 175 | 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F, // Q 49 176 | 177 | 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 178 | 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20, // R 50 179 | 180 | 0x70,0x88,0x08,0x08,0x08,0x38, 181 | 0x38,0x20,0x21,0x21,0x22,0x1C, // S 51 182 | 183 | 0x18,0x08,0x08,0xF8,0x08,0x08,0x18, 184 | 0x00,0x00,0x20,0x3F,0x20,0x00,0x00, // T 52 185 | 186 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 187 | 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, // U 53 188 | 189 | 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 190 | 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00, // V 54 191 | 192 | 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8, 193 | 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03, // W 55 194 | 195 | 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 196 | 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20, // X 56 197 | 198 | 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08, 199 | 0x00,0x00,0x20,0x3F,0x20,0x00,0x00, // Y 57 200 | 201 | 0x10,0x08,0x08,0x08,0xC8,0x38,0x08, 202 | 0x20,0x38,0x26,0x21,0x20,0x20,0x18, // Z 58 203 | 204 | 0xFE,0x02,0x02,0x02, 205 | 0x7F,0x40,0x40,0x40, // [ 59 206 | 207 | 0x0C,0x30,0xC0,0x00,0x00,0x00, 208 | 0x00,0x00,0x01,0x06,0x38,0xC0, // \ 60 209 | 210 | 0x02,0x02,0x02,0xFE,0x00,0x00, 211 | 0x40,0x40,0x40,0x7F,0x00,0x00, // ] 61 212 | 213 | 0x04,0x02,0x02,0x02,0x04, 214 | 0x00,0x00,0x00,0x00,0x00, // ^ 62 215 | 216 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 217 | 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // _ 63 218 | }; 219 | 220 | // ---------------------------------------------------------------------------- 221 | 222 | const uint8_t Tiny4kOLED_font8x16_caps_widths [] PROGMEM = { 223 | 7,2,6,7,5,7,8,3,4,4,7,7,3,6,2,7, 224 | 6,5,6,6,6,6,6,6,6,6,2,2,6,7,6,6, 225 | 7,8,7,7,7,7,7,7,8,5,7,7,7,7,8,7, 226 | 7,7,8,6,7,8,8,7,8,7,7,4,6,6,5,8 227 | }; 228 | 229 | const uint16_t Tiny4kOLED_font8x16_caps_widths_16s [] PROGMEM = { 230 | 7+2+6+7+5+7+8+3+4+4+7+7+3+6+2+7, 231 | 6+5+6+6+6+6+6+6+6+6+2+2+6+7+6+6, 232 | 7+8+7+7+7+7+7+7+8+5+7+7+7+7+8+7, 233 | 7+7+8+6+7+8+8+7+8+7+7+4+6+6+5+8 234 | }; 235 | 236 | const DCfont Tiny4kOLEDfont8x16Caps = { 237 | (uint8_t *)Tiny4kOLED_font8x16_caps, 238 | 0, // character width in pixels 239 | 2, // character height in pages (8 pixels) 240 | 32,95, // ASCII extents 241 | (uint16_t *)Tiny4kOLED_font8x16_caps_widths_16s, 242 | (uint8_t *)Tiny4kOLED_font8x16_caps_widths, 243 | 1 // spacing 244 | }; 245 | 246 | // for backwards compatibility 247 | #define FONT8X16CAPSP (&Tiny4kOLEDfont8x16Caps) 248 | -------------------------------------------------------------------------------- /examples/Bitmap/SolomonSystech.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | 9 | #ifndef SOLOMON_SYSTECH_H 10 | #define SOLOMON_SYSTECH_H 11 | 12 | // The SSD1306 is designed by SOLOMON SYSTECH. 13 | // So to demonstrate drawing bitmaps, I chose their logo. 14 | 15 | // The oled.bitmap method expects the array it is given, to be in flash memory 16 | // The PROGMEM in the next line is important, it puts the array in flash memory 17 | const uint8_t solomon_systech_logo_bitmap[] PROGMEM = { 18 | // The image was converted to a 64 x 32 pixel image 19 | 20 | // Each set of eight rows get set as a sequence of bytes 21 | // in the first eight rows, the first pixel is set on the 17th column 22 | // so the data starts with 16 zeroes. 23 | // All rows start with 6 zeroes, and end with 21 zeroes, 24 | // so to save space that data is not stored here, 25 | // and the image size is 37 x 32 pixels 26 | 27 | // The 8 bit encoding of the data for 8 pixels has least significant bit at the top 28 | // and the most significant bit at the bottom 29 | 30 | // ................................................................ 0 1 Page 1 31 | // ................................................................ 1 2 32 | // ................................................................ 2 4 33 | // ...........................########............................. 3 8 34 | // .......................###############.......................... 4 16 35 | // ....................####################........................ 5 32 36 | // .................########################....................... 6 64 37 | // ................####################............................ 7 128 38 | // ..............#.....##########.................................. 0 1 Page 2 39 | // ..................########...................................... 1 2 40 | // ................#######......................................... 2 4 41 | // ...............#####.................######..................... 3 8 42 | // .............#####............#############..................... 4 16 43 | // ...........####..........##################..................... 5 32 44 | // ..........###........#####################...................... 6 64 45 | // .........##......#########################...................... 7 128 46 | // .......##....############################....................... 0 1 Page 3 47 | // ......#...###############################....................... 1 2 48 | // .......#####...............#############........................ 2 4 49 | // ..........................#############......................... 3 8 50 | // .........................#############.......................... 4 16 51 | // ........................#############........................... 5 32 52 | // .......................#############............................ 6 64 53 | // .....................##############............................. 7 128 54 | // ...................##############............................... 0 1 Page 4 55 | // ................###############................................. 1 2 56 | // ..........###################................................... 2 4 57 | // ..........################...................................... 3 8 58 | // ............##########.......................................... 4 16 59 | // ................................................................ 5 32 60 | // ................................................................ 6 64 61 | // ................................................................ 7 128 62 | 63 | /* 64 | 65 | After removing the entirely blank rows at the left... 66 | The leftmost pixels set in the first eight rows of pixels (shown as page 1 above) are coded as 67 | 128, 192, 192, 192, 224, etc 68 | In hexidecimal, you can see these in the data below 69 | 0x80,0xC0,0xC0,0xC0,0xE0,etc 70 | 71 | The first column with data has a single pixel in the second row of page 3 corresponding to 72 | 0x00 in Page 1 73 | 0x00 in Page 2 74 | 0x02 in Page 3 75 | 0x00 in Page 4 76 | */ 77 | 78 | // Here's the data... 79 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0xE0,0xE0,0xE0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF0,0x70,0x70,0x60,0x60,0x40,0x00,0x00, 80 | 0x00,0x00,0x00,0x80,0xC0,0x60,0x60,0x30,0x31,0x18,0x1C,0x9C,0x8E,0x8E,0x87,0xC7,0xC7,0xC3,0xC3,0xE3,0xE1,0xE1,0xE1,0xE1,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF8,0xF8,0xF8,0xF8,0xF8,0x38, 81 | 0x02,0x05,0x05,0x04,0x06,0x06,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x83,0x83,0xC3,0xE3,0xF3,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x1F,0x0F,0x07,0x03,0x00,0x00, 82 | 0x00,0x00,0x00,0x00,0x0C,0x0C,0x1C,0x1C,0x1C,0x1C,0x1E,0x1E,0x1E,0x1F,0x1F,0x1F,0x0F,0x0F,0x0F,0x0F,0x07,0x07,0x07,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 83 | }; 84 | 85 | // Here's the data for the second "SOLOMON SYSTECH" image, 69 pixels wide x 4 pages 86 | const uint8_t solomon_systech_text_bitmap[] PROGMEM = { 87 | 0x78,0xFC,0xFE,0xC6,0xC6,0x9E,0x9C,0x18,0x00,0xE0,0xFC,0xFC,0x0E,0x06,0x0E,0xFC,0xFC,0xF8,0x00,0x00,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0xE0,0xFC,0xFC,0x0E,0x06,0x06,0xFC,0xFC,0xF8,0x00,0x00,0xFE,0xFE,0x3C,0xFC,0xE0,0x00,0xF0,0xFC,0x3C,0xFE,0xFC,0x00,0x00,0xF8,0xFC,0xFE,0x06,0x06,0x1E,0xFC,0xFC,0x00,0x00,0xFE,0xFE,0xFC,0x7C,0xE0,0x00,0xFE,0xFE, 88 | 0x1C,0x1C,0x3C,0x31,0x31,0x3F,0x1F,0x0F,0x00,0x03,0x1F,0x1F,0x38,0x30,0x38,0x3F,0x1F,0x0F,0x00,0x00,0x3F,0x3F,0x38,0x38,0x38,0x38,0x10,0x03,0x1F,0x1F,0x38,0x30,0x30,0x3F,0x1F,0x0F,0x00,0x00,0x3F,0x3F,0x00,0x01,0x1F,0x3F,0x1F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x0F,0x1F,0x3F,0x30,0x30,0x3C,0x1F,0x1F,0x00,0x00,0x3F,0x3F,0x1F,0x00,0x07,0x1F,0x3F,0x3F, 89 | 0x00,0x00,0x00,0x00,0xF0,0xF8,0xD8,0x88,0x18,0x38,0x38,0x20,0x00,0x38,0xF8,0xF8,0xC0,0xC0,0xF8,0x78,0x18,0x00,0xF0,0xF8,0xF8,0x88,0x18,0x38,0x38,0x20,0x00,0x18,0x18,0xF8,0xF8,0xF8,0x18,0x18,0x00,0x00,0xF8,0xF8,0xB8,0x18,0x18,0x18,0x18,0x00,0xE0,0xF8,0xF8,0x18,0x08,0x18,0x78,0x70,0x00,0x00,0xF8,0xF8,0xF8,0x80,0x80,0xF8,0xF8,0xF8,0x00,0x00,0x00, 90 | 0x00,0x00,0x00,0x00,0x39,0x79,0x63,0x63,0x67,0x7F,0x3E,0x1C,0x00,0x00,0x00,0x2F,0x7F,0x7F,0x03,0x00,0x00,0x00,0x38,0x79,0x73,0x63,0x67,0x7F,0x3E,0x1C,0x00,0x00,0x00,0x7F,0x7F,0x7F,0x00,0x00,0x00,0x00,0x7F,0x7F,0x73,0x63,0x63,0x63,0x61,0x00,0x1F,0x3F,0x7F,0x60,0x60,0x70,0x7C,0x3C,0x00,0x00,0x7F,0x7F,0x7F,0x03,0x03,0x7F,0x7F,0x7F,0x00,0x00,0x00 91 | }; 92 | 93 | /* 94 | 95 | Update - I found an online converter that produces the required format: http://www.majer.ch/lcd/adf_bitmap.php 96 | That's much easier than rotating images and transforming text! 97 | So ignore the below. 98 | 99 | An online tool was used in the creation of these images. 100 | https://marlinfw.org/tools/u8glib/converter.html 101 | 102 | By rotating the images, the right data bytes were produced but in the wrong layout: 103 | 104 | 0x00,0x00,0x1C,0x78, // ...................###...####... 105 | 0x00,0x00,0x1C,0xFC, // ...................###..######.. 106 | 0x00,0x00,0x3C,0xFE, // ..................####..#######. 107 | 0x00,0x00,0x31,0xC6, // ..................##...###...##. 108 | 0x39,0xF0,0x31,0xC6, // ..###..#####......##...###...##. 109 | 0x79,0xF8,0x3F,0x9E, // .####..######.....#######..####. 110 | 0x63,0xD8,0x1F,0x9C, // .##...####.##......######..###.. 111 | 0x63,0x88,0x0F,0x18, // .##...###...#.......####...##... 112 | 0x67,0x18,0x00,0x00, // .##..###...##................... 113 | etc. 114 | 115 | The columns were then converted into rows. 116 | 117 | Perhaps an efficient bitmap drawing routine could be written, 118 | that used bitmap data in the same format as u8glib, 119 | but for now, in order to have a really small library, 120 | more work has to go in to preparing the data. 121 | 122 | */ 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /examples/Devices/Identify/Identify.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | * This example attempts to identify your screen. 8 | * When the screen shows a rectangle with a number in it, 9 | * find that number in this source file to see how to use the 10 | * Tiny4kOLED library with your screen. 11 | * 12 | */ 13 | 14 | #include 15 | 16 | #define pinPrevious 3 17 | #define pinNext 4 18 | 19 | // The values shown here are the default values at reset. 20 | // As this example changes lots of values, 21 | // this sequence is sent between each init sequence 22 | // The screen SHOWN as sequence 0 is sending this sequence, 23 | // then the libraries default sequence (for a 128 x 32 screen) 24 | static const uint8_t ssd1306_init_sequence0 [] PROGMEM = { // Initialization Sequence 25 | 0xAE, // Display OFF (sleep mode) 26 | 0x2E, // Disable scroll 27 | 0x20, 0b10, // Set Memory Addressing Mode 28 | // 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode; 29 | // 10=Page Addressing Mode (RESET); 11=Invalid 30 | 0xB0, // Set Page Start Address for Page Addressing Mode, 0-7 31 | 0xC0, // Set COM Output Scan Direction 32 | 0x00, // Set low nibble of column address 33 | 0x10, // Set high nibble of column address 34 | 0x40, // Set display start line address 35 | 0x81, 0x7F, // Set contrast control register 36 | 0xA0, // Set Segment Re-map. A0=column 0 mapped to SEG0; A1=column 127 mapped to SEG0. 37 | 0xA6, // Set display mode. A6=Normal; A7=Inverse 38 | 0xA8, 0x3F, // Set multiplex ratio(1 to 64) 39 | 0xA4, // Output RAM to Display 40 | // 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content 41 | 0xD3, 0x00, // Set display offset. 00 = no offset 42 | 0xD5, 0x80, // --set display clock divide ratio/oscillator frequency 43 | 0xD9, 0x22, // Set pre-charge period 44 | 0xDA, 0x12, // Set com pins hardware configuration 45 | 0xDB, 0x20, // --set vcomh 0x20 = 0.77xVcc 46 | 0xAD, 0x00, // Select external IREF 47 | 0x8D, 0x10 // DC-DC disabled 48 | }; 49 | 50 | // Initialization sequence for 128 x 32 screen 51 | static const uint8_t ssd1306_init_sequence1 [] PROGMEM = { 52 | 0xA8, 0x1F, // Multiplex ratio 53 | 0xDA, 0x02, // HW pin configuration 54 | // If you are copying this, include the common_post_init_sequence values to here 55 | }; 56 | 57 | // Initialization sequence for rotated 128 x 32 screen 58 | static const uint8_t ssd1306_init_sequence2 [] PROGMEM = { 59 | 0xC8, // Set COM Output Scan Direction 60 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 61 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 62 | 0xDA, 0x02, // HW pin configuration 63 | // If you are copying this, include the common_post_init_sequence values to here 64 | }; 65 | 66 | // Initialization sequence for 128 x 64 screen 67 | static const uint8_t ssd1306_init_sequence3 [] PROGMEM = { 68 | // If you are copying this, include the common_post_init_sequence values to here 69 | }; 70 | 71 | // Initialization sequence for rotated 128 x 64 screen 72 | static const uint8_t ssd1306_init_sequence4 [] PROGMEM = { 73 | 0xC8, // Set COM Output Scan Direction 74 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 75 | // If you are copying this, include the common_post_init_sequence values to here 76 | }; 77 | 78 | // Initialization sequence for 64 x 48 screen 79 | static const uint8_t ssd1306_init_sequence5 [] PROGMEM = { 80 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 81 | // If you are copying this, include the common_post_init_sequence values to here 82 | }; 83 | 84 | // Initialization sequence for rotated 64 x 48 screen 85 | static const uint8_t ssd1306_init_sequence6 [] PROGMEM = { 86 | 0xC8, // Set COM Output Scan Direction 87 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 88 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 89 | // If you are copying this, include the common_post_init_sequence values to here 90 | }; 91 | 92 | // Initialization sequence for 72 x 40 screen 93 | static const uint8_t ssd1306_init_sequence7 [] PROGMEM = { 94 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 95 | // If you are copying this, include the common_post_init_sequence values to here 96 | }; 97 | 98 | // Initialization sequence for rotated 72 x 40 screen 99 | static const uint8_t ssd1306_init_sequence8 [] PROGMEM = { 100 | 0xC8, // Set COM Output Scan Direction 101 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 102 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 103 | // If you are copying this, include the common_post_init_sequence values to here 104 | }; 105 | 106 | // Initialization sequence for 64 x 32 screen 107 | static const uint8_t ssd1306_init_sequence9 [] PROGMEM = { 108 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 109 | // If you are copying this, include the common_post_init_sequence values to here 110 | }; 111 | 112 | // Initialization sequence for rotated 64 x 32 screen 113 | static const uint8_t ssd1306_init_sequence10 [] PROGMEM = { 114 | 0xC8, // Set COM Output Scan Direction 115 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 116 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 117 | // If you are copying this, include the common_post_init_sequence values to here 118 | }; 119 | 120 | const uint8_t numScreens = 11; 121 | 122 | // Common Initialization sequence left at reset values 123 | static const uint8_t common_post_init_sequence [] PROGMEM = { 124 | 0xAD, 0x30, // Select internal IREF and higher current 125 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 126 | }; 127 | 128 | uint8_t screen = 0; 129 | uint8_t minx = 0; 130 | uint8_t miny = 0; 131 | uint8_t width = 128; 132 | uint8_t height = 32; 133 | 134 | struct { 135 | const uint8_t minx; 136 | const uint8_t miny; 137 | const uint8_t width; 138 | const uint8_t height; 139 | const uint8_t init_sequence_length; 140 | const uint8_t * init_sequence; 141 | } const screens[numScreens] = { 142 | { 0, 0, 128, 32, sizeof(ssd1306_init_sequence0), ssd1306_init_sequence0}, 143 | { 0, 0, 128, 32, sizeof(ssd1306_init_sequence1), ssd1306_init_sequence1}, 144 | { 0, 0, 128, 32, sizeof(ssd1306_init_sequence2), ssd1306_init_sequence2}, 145 | { 0, 0, 128, 64, sizeof(ssd1306_init_sequence3), ssd1306_init_sequence3}, 146 | { 0, 0, 128, 64, sizeof(ssd1306_init_sequence4), ssd1306_init_sequence4}, 147 | {32, 0, 64, 48, sizeof(ssd1306_init_sequence5), ssd1306_init_sequence5}, 148 | {32, 0, 64, 48, sizeof(ssd1306_init_sequence6), ssd1306_init_sequence6}, 149 | {28, 0, 72, 40, sizeof(ssd1306_init_sequence7), ssd1306_init_sequence7}, 150 | {28, 0, 72, 40, sizeof(ssd1306_init_sequence8), ssd1306_init_sequence8}, 151 | {32, 0, 64, 32, sizeof(ssd1306_init_sequence9), ssd1306_init_sequence9}, 152 | {32, 0, 64, 32, sizeof(ssd1306_init_sequence10), ssd1306_init_sequence10} 153 | }; 154 | 155 | void setup() { 156 | oled.setFont(FONT6X8); 157 | pinMode(pinPrevious, INPUT_PULLUP); 158 | pinMode(pinNext, INPUT_PULLUP); 159 | } 160 | 161 | void loop() { 162 | // Set everything back to default values at reset 163 | oled.begin(sizeof(ssd1306_init_sequence0), ssd1306_init_sequence0); 164 | 165 | if (screen == 0) { 166 | oled.begin(); 167 | } else { 168 | oled.begin(screens[screen].init_sequence_length, screens[screen].init_sequence); 169 | oled.begin(sizeof(common_post_init_sequence), common_post_init_sequence); 170 | } 171 | drawScreen(); 172 | oled.on(); 173 | scrollScreen(); 174 | nextScreen(); 175 | } 176 | 177 | void drawScreen() { 178 | // Set entire memory to hatched 179 | for (uint8_t y = 0; y < 8; y++) { 180 | oled.setCursor(0, y); 181 | oled.startData(); 182 | for (uint8_t x=0; x<128; x += 2) { 183 | oled.sendData(0b10101010); 184 | oled.sendData(0b01010101); 185 | } 186 | oled.endData(); 187 | } 188 | 189 | oled.setCursor(minx, (miny / 8)); 190 | oled.startData(); 191 | oled.sendData(0b11111111); 192 | oled.repeatData(0b00000001, width - 2); 193 | oled.sendData(0b11111111); 194 | oled.endData(); 195 | 196 | for (uint8_t y = 1; y < (height - 8) / 8; y++) { 197 | oled.setCursor(minx, y + (miny / 8)); 198 | oled.startData(); 199 | oled.sendData(0b11111111); 200 | oled.repeatData(0b00000000, width - 2); 201 | oled.sendData(0b11111111); 202 | oled.endData(); 203 | } 204 | 205 | oled.setCursor(minx, (height + miny - 8) / 8); 206 | oled.startData(); 207 | oled.sendData(0b11111111); 208 | oled.repeatData(0b10000000, width - 2); 209 | oled.sendData(0b11111111); 210 | oled.endData(); 211 | 212 | oled.setCursor(8 + minx, 1 + (miny / 8)); 213 | oled.print(screen); 214 | oled.setCursor(8 + minx, 2 + (miny / 8)); 215 | oled.print(width); 216 | oled.print('x'); 217 | oled.print(height); 218 | } 219 | 220 | void scrollScreen() { 221 | uint8_t startScrollPage = 1 + (miny / 8); 222 | uint8_t endSCrollPage = startScrollPage + 1; 223 | uint8_t startScrollColumn = 8 + minx; 224 | uint8_t endScrollColumn = startScrollColumn + width - 16; 225 | for (uint8_t x = 0; x < width - 16; x++) 226 | { 227 | delay(50); 228 | if (digitalRead(pinPrevious) == 0) { 229 | if (screen == 0) screen = numScreens - 2; 230 | else screen -= 2; 231 | break; 232 | } 233 | if (digitalRead(pinNext) == 0) break; 234 | oled.scrollContentRight(startScrollPage, endSCrollPage, startScrollColumn, endScrollColumn); 235 | } 236 | } 237 | 238 | void nextScreen() { 239 | screen += 1; 240 | if (screen == numScreens) screen = 0; 241 | minx = screens[screen].minx; 242 | miny = screens[screen].miny; 243 | width = screens[screen].width; 244 | height = screens[screen].height; 245 | } -------------------------------------------------------------------------------- /src/font8x16.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | /* 9 | * SSD1306xLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x64 displays 10 | * 11 | * @created: 2014-08-12 12 | * @author: Neven Boyanov 13 | * 14 | * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled 15 | * 16 | */ 17 | 18 | // ---------------------------------------------------------------------------- 19 | 20 | #include 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 8x16 font */ 25 | const uint8_t ssd1306xled_font8x16 [] PROGMEM = { 26 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 27 | 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00, // ! 1 28 | 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // " 2 29 | 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00, // # 3 30 | 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00, // $ 4 31 | 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00, // % 5 32 | 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10, // & 6 33 | 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' 7 34 | 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00, // ( 8 35 | 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00, // ) 9 36 | 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00, // * 10 37 | 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00, // + 11 38 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00, // , 12 39 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, // - 13 40 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00, // . 14 41 | 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00, // / 15 42 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00, // 0 16 43 | 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // 1 17 44 | 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00, // 2 18 45 | 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00, // 3 19 46 | 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00, // 4 20 47 | 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00, // 5 21 48 | 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00, // 6 22 49 | 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00, // 7 23 50 | 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00, // 8 24 51 | 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00, // 9 25 52 | 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, // : 26 53 | 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00, // ; 27 54 | 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00, // < 28 55 | 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00, // = 29 56 | 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00, // > 30 57 | 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00, // ? 31 58 | 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00, // @ 32 59 | 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, // A 33 60 | 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00, // B 34 61 | 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00, // C 35 62 | 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00, // D 36 63 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00, // E 37 64 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00, // F 38 65 | 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00, // G 39 66 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20, // H 40 67 | 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // I 41 68 | 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00, // J 42 69 | 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00, // K 43 70 | 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00, // L 44 71 | 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00, // M 45 72 | 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00, // N 46 73 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00, // O 47 74 | 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00, // P 48 75 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00, // Q 49 76 | 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20, // R 50 77 | 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00, // S 51 78 | 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00, // T 52 79 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, // U 53 80 | 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00, // V 54 81 | 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00, // W 55 82 | 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20, // X 56 83 | 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00, // Y 57 84 | 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00, // Z 58 85 | 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00, // [ 59 86 | 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00, // \ 60 87 | 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, // ] 61 88 | 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ^ 62 89 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // _ 63 90 | 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ` 64 91 | 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20, // a 65 92 | 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00, // b 66 93 | 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00, // c 67 94 | 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20, // d 68 95 | 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00, // e 69 96 | 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // f 70 97 | 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00, // g 71 98 | 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, // h 72 99 | 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // i 73 100 | 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00, // j 74 101 | 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00, // k 75 102 | 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // l 76 103 | 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F, // m 77 104 | 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, // n 78 105 | 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, // o 79 106 | 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00, // p 80 107 | 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80, // q 81 108 | 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00, // r 82 109 | 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00, // s 83 110 | 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00, // t 84 111 | 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20, // u 85 112 | 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00, // v 86 113 | 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00, // w 87 114 | 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00, // x 88 115 | 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00, // y 89 116 | 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00, // z 90 117 | 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40, // { 91 118 | 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, // | 92 119 | 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00, // } 93 120 | 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 94 121 | }; 122 | 123 | // ---------------------------------------------------------------------------- 124 | 125 | const DCfont TinyOLED4kfont8x16 = { 126 | (uint8_t *)ssd1306xled_font8x16, 127 | 8, // character width in pixels 128 | 2, // character height in pages (8 pixels) 129 | 32,126, // ASCII extents 130 | 0,0,0 // Unused for fixed width fonts 131 | }; 132 | 133 | // for backwards compatibility 134 | #define FONT8X16 (&TinyOLED4kfont8x16) 135 | -------------------------------------------------------------------------------- /examples/BatteryMonitor/BatteryMonitor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Power Monitor 3 | * 4 | * Records the power supply voltage every hour, logged in EEPROM. 5 | * When a button is pressed the last voltage is displayed in a large font. 6 | * A graph of the last five days readings is shown over the readout. 7 | * The graph's y axis range is from 0 to 6 volts. 8 | * 9 | * When using Spence Konde's ATTinyCore https://github.com/SpenceKonde/ATTinyCore 10 | * and using a chip without Optiboot, with LTO enabled, this sketch takes 5952 bytes of flash. 11 | * 12 | * The battery level is measured roughly every hour 13 | * and the measured voltages are stored in EEPROM 14 | * 15 | * When a button is pressed, the display shows a graph of the latest readings. 16 | * 17 | * Power on: 18 | * check eeprom is set up to record log of voltages 19 | * record current voltage 20 | * set up wake up interupts on button press and watch dog timer 21 | * set up the screen and display the graph and latest voltage 22 | * Go to sleep 23 | * 24 | * Every 8 seconds the watch dog timer wakes up the device 25 | * If the number of wake-ups means an hour has passed, 26 | * then the current voltage is logged. 27 | * If the screen has been on for 2 wake-ups then turn off the screen. 28 | * Go to sleep 29 | * 30 | * If a button is pressed, the screen is turned on, 31 | * and the device goes back to sleep. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "eeprom_contents.h" 39 | 40 | // Large font containing only digits. 41 | // TinyOLED-Fonts library needed. 42 | // https://github.com/datacute/TinyOLED-Fonts 43 | #include "Sansita_Swashed_Regular_57_Digits.h" 44 | 45 | // Routines to set and clear bits (used in the sleep code) 46 | #ifndef cbi 47 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 48 | #endif 49 | #ifndef sbi 50 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 51 | #endif 52 | 53 | static bool eepromOk = false; 54 | static uint8_t currentContrast = BATTERY_DEFAULT_CONTRAST; 55 | 56 | static uint8_t currentAddress = BATTERY_READINGS_ADDRESS; 57 | 58 | #define MAIN_BUTTON 4 59 | #define ENTER_BUTTON 3 60 | 61 | // Variables for the Sleep/power down modes: 62 | volatile boolean f_wdt = 0; 63 | static int wdt_counter = 0; 64 | static int graph_display_counter = 0; 65 | 66 | // The watch dog timer wakes up the device every 8 seconds 67 | // The device graphs the last 120 readings 68 | // 10800 * 8 seconds = 1 day. 120 days = 4 months, mark every 7th or 30th 69 | // 450 * 8 seconds = 1 hour. 120 hours = 5 days, mark every 24th 70 | // 75 * 8 seconds = 10 minutes. 1200 minutes = 20 hours, mark every 6th 71 | // 15 * 8 seconds = 2 minutes. 240 minutes = 4 hours, mark every 30th 72 | #define REPORT_PERIOD 450 73 | #define GRAPH_TICK_COUNT 24 74 | 75 | // Watchdog Interrupt Service / is executed when watchdog timed out 76 | ISR(WDT_vect) { 77 | f_wdt=1; // set global flag 78 | } 79 | 80 | ISR(PCINT0_vect) {} 81 | 82 | void setup() { 83 | setupADC(); 84 | setupInputs(); 85 | setupOLED(); 86 | setupFromEEPROM(); 87 | setupWDT(); 88 | oled.setContrast(currentContrast); 89 | displayGraph(); 90 | } 91 | 92 | static void setupADC() { 93 | ADMUX = 0b1100< 9 ) ii=9; 129 | bb=ii & 7; 130 | if (ii > 7) bb|= (1<<5); 131 | //bb|= (1< 0) { 152 | graph_display_counter--; 153 | if (graph_display_counter == 0) { 154 | oled.off(); 155 | } 156 | } 157 | } 158 | } 159 | 160 | bool processButtonInputs(void) { 161 | bool mainButtonIsDown = digitalRead(MAIN_BUTTON) == LOW; 162 | if (mainButtonIsDown) { 163 | displayGraph(); 164 | } 165 | bool enterButtonIsDown = digitalRead(ENTER_BUTTON) == LOW; 166 | if (enterButtonIsDown) { 167 | displayGraph(); 168 | } 169 | return mainButtonIsDown || enterButtonIsDown; 170 | } 171 | 172 | static uint8_t ticks[] = { 173 | 0x04, // 5.5V to 6.2V 174 | 0x10, // 4.7V to 5.4V 175 | 0x40, // 3.9V to 4.6V 176 | 0x00, // 3.1V to 3.8V 177 | 0x01, // 2.3V to 3.0V 178 | 0x04, // 1.5V to 2.2V 179 | 0x10, // 0.7V to 1.4V 180 | 0x40 // bottom ticks line, 0.0 to 0.6 V 181 | }; 182 | 183 | static uint8_t overlayGraph(uint8_t x, uint8_t y, uint8_t b) { 184 | int itemAddress = currentAddress + x - 2; 185 | if (itemAddress >= 128) itemAddress -= (128 - BATTERY_READINGS_ADDRESS); 186 | uint8_t bottomBit = (7-y) << 3; 187 | uint8_t reading = EEPROM.read(itemAddress); 188 | uint8_t v = reading; // mask out pixel below graph 189 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 190 | b &= ~(1 << (7 - (v - bottomBit))); 191 | } 192 | v++; // Shift graph up 1 pixel above ticks line 193 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 194 | b |= 1 << (7 - (v - bottomBit)); 195 | } 196 | v++;// mask out pixel above graph 197 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 198 | b &= ~(1 << (7 - (v - bottomBit))); 199 | } 200 | return b; 201 | } 202 | 203 | static void displayGraph() { 204 | uint8_t reading; 205 | for (uint8_t line = 0; line < 8; line++) { 206 | uint8_t bottomBit = (7-line) << 3; 207 | oled.setCursor(0,line); 208 | oled.startData(); 209 | oled.sendData(ticks[line]); 210 | oled.sendData(0xFF); 211 | int itemAddress = currentAddress; // oldest reading 212 | uint8_t tick_column = 0; 213 | do { 214 | reading = EEPROM.read(itemAddress); 215 | uint8_t v = reading + 1; // Shift graph up 1 pixel above ticks line 216 | uint8_t b = 0; 217 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 218 | b = 1 << (7 - (v - bottomBit)); 219 | } 220 | if (line == 7) { 221 | b |= 0x40; 222 | tick_column++; 223 | if (tick_column == GRAPH_TICK_COUNT) { 224 | b |= 0x80; 225 | tick_column = 0; 226 | } 227 | } 228 | oled.sendData(b); 229 | itemAddress++; 230 | if (itemAddress >= 128) itemAddress = BATTERY_READINGS_ADDRESS; 231 | } while (itemAddress != currentAddress); 232 | oled.sendData(0xFF); 233 | oled.sendData(ticks[line]); 234 | oled.endData(); 235 | } 236 | // This can be made more efficient by not drawing the following large portion of the graph twice. 237 | oled.setCursor(27,1); 238 | oled.setCombineFunction(&overlayGraph); 239 | oled.print((float)reading/10.0, 1); 240 | oled.setCombineFunction(NULL); 241 | oled.on(); 242 | graph_display_counter = 2; 243 | } 244 | /* 245 | static void setContrast(void) { 246 | oled.setContrast(currentContrast); 247 | if (eepromOk) { 248 | EEPROM.write(BATTERY_CONTRAST_ADDRESS, currentContrast); 249 | } 250 | } 251 | */ 252 | void settingsResetAction(void) { 253 | // EEPROM Header 254 | for (uint16_t offset = 0; offset < sizeof(header); offset++) { 255 | EEPROM.write(offset, pgm_read_byte(&header[offset])); 256 | } 257 | // Default all readings to current voltage value 258 | uint16_t result = readADC(); 259 | //result = 1126400L / result; // Calculate Vcc (in mV); 1.1*1024*1000 260 | result = 11264L / result; // 10ths of a volt 261 | 262 | for (uint16_t address = sizeof(header); address < 128; address++) { 263 | EEPROM.write(address, (byte)result); 264 | } 265 | eepromOk = true; 266 | currentAddress = BATTERY_READINGS_ADDRESS; 267 | currentContrast = BATTERY_DEFAULT_CONTRAST; 268 | } 269 | 270 | static void recordVoltage(void) { 271 | uint16_t result = readADC(); 272 | //result = 1126400L / result; // Calculate Vcc (in mV); 1.1*1024*1000 273 | result = 11264L / result; // 10ths of a volt 274 | EEPROM.write(currentAddress, (byte)result); 275 | currentAddress++; 276 | if (currentAddress >= 128) { 277 | currentAddress = BATTERY_READINGS_ADDRESS; 278 | } 279 | EEPROM.write(BATTERY_CURRENT_ADDRESS, currentAddress); 280 | } 281 | 282 | static uint16_t readADC() { 283 | uint8_t low,high; 284 | sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON 285 | ADCSRA = ADCSRA | 1< 21 | 22 | // ---------------------------------------------------------------------------- 23 | 24 | /* Standard ASCII 8x16 proportional font */ 25 | const uint8_t Tiny4kOLED_font8x16 [] PROGMEM = { 26 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, 27 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0 28 | 29 | 0xF8,0x00, 30 | 0x33,0x30, // ! 1 31 | 32 | 0x10,0x0C,0x06,0x10,0x0C,0x06, 33 | 0x00,0x00,0x00,0x00,0x00,0x00, // " 2 34 | 35 | 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40, 36 | 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04, // # 3 37 | 38 | 0x70,0x88,0xFC,0x08,0x30, 39 | 0x18,0x20,0xFF,0x21,0x1E, // $ 4 40 | 41 | 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00, 42 | 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E, // % 5 43 | 44 | 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, 45 | 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10, // & 6 46 | 47 | 0x10,0x16,0x0E, 48 | 0x00,0x00,0x00, // ' 7 49 | 50 | 0xE0,0x18,0x04,0x02, 51 | 0x07,0x18,0x20,0x40, // ( 8 52 | 53 | 0x02,0x04,0x18,0xE0, 54 | 0x40,0x20,0x18,0x07, // ) 9 55 | 56 | 0x40,0x40,0x80,0xF0,0x80,0x40,0x40, 57 | 0x02,0x02,0x01,0x0F,0x01,0x02,0x02, // * 10 58 | 59 | 60 | 0x00,0x00,0x00,0xF0,0x00,0x00,0x00, 61 | 0x01,0x01,0x01,0x1F,0x01,0x01,0x01, // + 11 62 | 63 | 0x00,0x00,0x00, 64 | 0x80,0xB0,0x70, // , 12 65 | 66 | 0x00,0x00,0x00,0x00,0x00,0x00, 67 | 0x01,0x01,0x01,0x01,0x01,0x01, // - 13 68 | 69 | 0x00,0x00, 70 | 0x30,0x30, // . 14 71 | 72 | 0x00,0x00,0x00,0x80,0x60,0x18,0x04, 73 | 0x60,0x18,0x06,0x01,0x00,0x00,0x00, // / 15 74 | 75 | 0xE0,0x10,0x08,0x08,0x10,0xE0, 76 | 0x0F,0x10,0x20,0x20,0x10,0x0F, // 0 16 77 | 78 | 0x10,0x10,0xF8,0x00,0x00, 79 | 0x20,0x20,0x3F,0x20,0x20, // 1 17 80 | 81 | 0x70,0x08,0x08,0x08,0x88,0x70, 82 | 0x30,0x28,0x24,0x22,0x21,0x30, // 2 18 83 | 84 | 0x30,0x08,0x88,0x88,0x48,0x30, 85 | 0x18,0x20,0x20,0x20,0x11,0x0E, // 3 19 86 | 87 | 0x00,0xC0,0x20,0x10,0xF8,0x00, 88 | 0x07,0x04,0x24,0x24,0x3F,0x24, // 4 20 89 | 90 | 0xF8,0x08,0x88,0x88,0x08,0x08, 91 | 0x19,0x21,0x20,0x20,0x11,0x0E, // 5 21 92 | 93 | 0xE0,0x10,0x88,0x88,0x18,0x00, 94 | 0x0F,0x11,0x20,0x20,0x11,0x0E, // 6 22 95 | 96 | 0x38,0x08,0x08,0xC8,0x38,0x08, 97 | 0x00,0x00,0x3F,0x00,0x00,0x00, // 7 23 98 | 99 | 0x70,0x88,0x08,0x08,0x88,0x70, 100 | 0x1C,0x22,0x21,0x21,0x22,0x1C, // 8 24 101 | 102 | 0xE0,0x10,0x08,0x08,0x10,0xE0, 103 | 0x00,0x31,0x22,0x22,0x11,0x0F, // 9 25 104 | 105 | 0xC0,0xC0, 106 | 0x30,0x30, // : 26 107 | 108 | 0x00,0x80, 109 | 0x80,0x60, // ; 27 110 | 111 | 0x00,0x80,0x40,0x20,0x10,0x08, 112 | 0x01,0x02,0x04,0x08,0x10,0x20, // < 28 113 | 114 | 0x40,0x40,0x40,0x40,0x40,0x40,0x40, 115 | 0x04,0x04,0x04,0x04,0x04,0x04,0x04, // = 29 116 | 117 | 0x08,0x10,0x20,0x40,0x80,0x00, 118 | 0x20,0x10,0x08,0x04,0x02,0x01, // > 30 119 | 120 | 0x70,0x48,0x08,0x08,0x08,0xF0, 121 | 0x00,0x00,0x30,0x36,0x01,0x00, // ? 31 122 | 123 | 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0, 124 | 0x07,0x18,0x27,0x24,0x23,0x14,0x0B, // @ 32 125 | 126 | 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, 127 | 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20, // A 33 128 | 129 | 0x08,0xF8,0x88,0x88,0x88,0x70,0x00, 130 | 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E, // B 34 131 | 132 | 0xC0,0x30,0x08,0x08,0x08,0x08,0x38, 133 | 0x07,0x18,0x20,0x20,0x20,0x10,0x08, // C 35 134 | 135 | 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0, 136 | 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F, // D 36 137 | 138 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10, 139 | 0x20,0x3F,0x20,0x20,0x23,0x20,0x18, // E 37 140 | 141 | 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10, 142 | 0x20,0x3F,0x20,0x00,0x03,0x00,0x00, // F 38 143 | 144 | 0xC0,0x30,0x08,0x08,0x08,0x38,0x00, 145 | 0x07,0x18,0x20,0x20,0x22,0x1E,0x02, // G 39 146 | 147 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 148 | 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20, // H 40 149 | 150 | 0x08,0x08,0xF8,0x08,0x08, 151 | 0x20,0x20,0x3F,0x20,0x20, // I 41 152 | 153 | 0x00,0x00,0x08,0x08,0xF8,0x08,0x08, 154 | 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00, // J 42 155 | 156 | 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08, 157 | 0x20,0x3F,0x20,0x01,0x26,0x38,0x20, // K 43 158 | 159 | 0x08,0xF8,0x08,0x00,0x00,0x00,0x00, 160 | 0x20,0x3F,0x20,0x20,0x20,0x20,0x30, // L 44 161 | 162 | 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08, 163 | 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20, // M 45 164 | 165 | 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, 166 | 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00, // N 46 167 | 168 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0, 169 | 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F, // O 47 170 | 171 | 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0, 172 | 0x20,0x3F,0x21,0x01,0x01,0x01,0x00, // P 48 173 | 174 | 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0, 175 | 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F, // Q 49 176 | 177 | 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, 178 | 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20, // R 50 179 | 180 | 0x70,0x88,0x08,0x08,0x08,0x38, 181 | 0x38,0x20,0x21,0x21,0x22,0x1C, // S 51 182 | 183 | 0x18,0x08,0x08,0xF8,0x08,0x08,0x18, 184 | 0x00,0x00,0x20,0x3F,0x20,0x00,0x00, // T 52 185 | 186 | 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, 187 | 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00, // U 53 188 | 189 | 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, 190 | 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00, // V 54 191 | 192 | 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8, 193 | 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03, // W 55 194 | 195 | 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, 196 | 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20, // X 56 197 | 198 | 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08, 199 | 0x00,0x00,0x20,0x3F,0x20,0x00,0x00, // Y 57 200 | 201 | 0x10,0x08,0x08,0x08,0xC8,0x38,0x08, 202 | 0x20,0x38,0x26,0x21,0x20,0x20,0x18, // Z 58 203 | 204 | 0xFE,0x02,0x02,0x02, 205 | 0x7F,0x40,0x40,0x40, // [ 59 206 | 207 | 0x0C,0x30,0xC0,0x00,0x00,0x00, 208 | 0x00,0x00,0x01,0x06,0x38,0xC0, // \ 60 209 | 210 | 0x02,0x02,0x02,0xFE,0x00,0x00, 211 | 0x40,0x40,0x40,0x7F,0x00,0x00, // ] 61 212 | 213 | 0x04,0x02,0x02,0x02,0x04, 214 | 0x00,0x00,0x00,0x00,0x00, // ^ 62 215 | 216 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 217 | 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // _ 63 218 | 219 | 0x02,0x02,0x04, 220 | 0x00,0x00,0x00, // ` 64 221 | 222 | 0x00,0x80,0x80,0x80,0x80,0x00,0x00, 223 | 0x19,0x24,0x22,0x22,0x22,0x3F,0x20, // a 65 224 | 225 | 0x08,0xF8,0x00,0x80,0x80,0x00,0x00, 226 | 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E, // b 66 227 | 228 | 0x00,0x00,0x80,0x80,0x80,0x00, 229 | 0x0E,0x11,0x20,0x20,0x20,0x11, // c 67 230 | 231 | 0x00,0x00,0x80,0x80,0x88,0xF8,0x00, 232 | 0x0E,0x11,0x20,0x20,0x10,0x3F,0x20, // d 68 233 | 234 | 0x00,0x80,0x80,0x80,0x80,0x00, 235 | 0x1F,0x22,0x22,0x22,0x22,0x13, // e 69 236 | 237 | 0x80,0x80,0xF0,0x88,0x88,0x88,0x18, 238 | 0x20,0x20,0x3F,0x20,0x20,0x00,0x00, // f 70 239 | 240 | 0x00,0x80,0x80,0x80,0x80,0x80, 241 | 0x6B,0x94,0x94,0x94,0x93,0x60, // g 71 242 | 243 | 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, 244 | 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, // h 72 245 | 246 | 0x80,0x98,0x98,0x00,0x00, 247 | 0x20,0x20,0x3F,0x20,0x20, // i 73 248 | 249 | 0x00,0x00,0x80,0x98,0x98, 250 | 0xC0,0x80,0x80,0x80,0x7F, // j 74 251 | 252 | 0x08,0xF8,0x00,0x00,0x80,0x80,0x80, 253 | 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20, // k 75 254 | 255 | 0x08,0x08,0xF8,0x00,0x00, 256 | 0x20,0x20,0x3F,0x20,0x20, // l 76 257 | 258 | 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, 259 | 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F, // m 77 260 | 261 | 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00, 262 | 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20, // n 78 263 | 264 | 0x00,0x80,0x80,0x80,0x80,0x00, 265 | 0x1F,0x20,0x20,0x20,0x20,0x1F, // o 79 266 | 267 | 0x80,0x80,0x00,0x80,0x80,0x00,0x00, 268 | 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E, // p 80 269 | 270 | 0x00,0x00,0x80,0x80,0x80,0x80,0x00, 271 | 0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80, // q 81 272 | 273 | 0x80,0x80,0x80,0x00,0x80,0x80,0x80, 274 | 0x20,0x20,0x3F,0x21,0x20,0x00,0x01, // r 82 275 | 276 | 0x00,0x80,0x80,0x80,0x80,0x80, 277 | 0x33,0x24,0x24,0x24,0x24,0x19, // s 83 278 | 279 | 0x80,0x80,0xE0,0x80,0x80, 280 | 0x00,0x00,0x1F,0x20,0x20, // t 84 281 | 282 | 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, 283 | 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20, // u 85 284 | 285 | 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 286 | 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00, // v 86 287 | 288 | 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, 289 | 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00, // w 87 290 | 291 | 0x80,0x80,0x00,0x80,0x80,0x80, 292 | 0x20,0x31,0x2E,0x0E,0x31,0x20, // x 88 293 | 294 | 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, 295 | 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00, // y 89 296 | 297 | 0x80,0x80,0x80,0x80,0x80,0x80, 298 | 0x21,0x30,0x2C,0x22,0x21,0x30, // z 90 299 | 300 | 0x80,0x7C,0x02,0x02, 301 | 0x00,0x3F,0x40,0x40, // { 91 302 | 303 | 0xFF, 304 | 0xFF, // | 92 305 | 306 | 0x02,0x02,0x7C,0x80, 307 | 0x40,0x40,0x3F,0x00, // } 93 308 | 309 | 0x06,0x01,0x01,0x02,0x02,0x04,0x04, 310 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ~ 94 311 | }; 312 | 313 | const uint8_t Tiny4kOLED_font8x16_widths [] PROGMEM = { 314 | 7,2,6,7,5,7,8,3,4,4,7,7,3,6,2,7, 315 | 6,5,6,6,6,6,6,6,6,6,2,2,6,7,6,6, 316 | 7,8,7,7,7,7,7,7,8,5,7,7,7,7,8,7, 317 | 7,7,8,6,7,8,8,7,8,7,7,4,6,6,5,8, 318 | 3,7,7,6,7,6,7,6,8,5,5,7,5,8,8,6, 319 | 7,7,7,6,5,8,8,8,6,8,6,4,1,4,7 320 | }; 321 | 322 | const uint16_t Tiny4kOLED_font8x16_widths_16s [] PROGMEM = { 323 | 7+2+6+7+5+7+8+3+4+4+7+7+3+6+2+7, 324 | 6+5+6+6+6+6+6+6+6+6+2+2+6+7+6+6, 325 | 7+8+7+7+7+7+7+7+8+5+7+7+7+7+8+7, 326 | 7+7+8+6+7+8+8+7+8+7+7+4+6+6+5+8, 327 | 3+7+7+6+7+6+7+6+8+5+5+7+5+8+8+6, 328 | 7+7+7+6+5+8+8+8+6+8+6+4+1+4+7 329 | }; 330 | 331 | const DCfont Tiny4kOLEDfont8x16 = { 332 | (uint8_t *)Tiny4kOLED_font8x16, 333 | 0, // character width in pixels 334 | 2, // character height in pages (8 pixels) 335 | 32,126, // ASCII extents 336 | (uint16_t *)Tiny4kOLED_font8x16_widths_16s, 337 | (uint8_t *)Tiny4kOLED_font8x16_widths, 338 | 1 // spacing 339 | }; 340 | 341 | // for backwards compatibility 342 | #define FONT8X16P (&Tiny4kOLEDfont8x16) 343 | -------------------------------------------------------------------------------- /examples/TemperatureMonitor/TemperatureMonitor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Temperature Monitor 3 | * 4 | * Records the ATTiny85 internal temperature every hour, logged in EEPROM. 5 | * When a button is pressed the last temperature is displayed in a large font. 6 | * A graph of the last five days readings is shown over the readout. 7 | * The graph's y axis range is from -10 to 50 degrees C. 8 | * 9 | * When using Spence Konde's ATTinyCore https://github.com/SpenceKonde/ATTinyCore 10 | * and using a chip without Optiboot, with LTO enabled, this sketch takes 5572 bytes of flash. 11 | * 12 | * The temperature is measured roughly every hour 13 | * and the measured temperatues are stored in EEPROM 14 | * 15 | * When a button is pressed, the display shows a graph of the latest readings. 16 | * 17 | * Power on: 18 | * check eeprom is set up to record log of temperatures 19 | * record current temperature 20 | * set up wake up interrupts on button press and watch dog timer 21 | * set up the screen and display the graph and latest temperature 22 | * Go to sleep 23 | * 24 | * Every 8 seconds the watch dog timer wakes up the device 25 | * If the number of wake-ups means an hour has passed, 26 | * then the current temperature is logged. 27 | * If the screen has been on for 2 wake-ups then turn off the screen. 28 | * Go to sleep 29 | * 30 | * If a button is pressed, the screen is turned on, 31 | * and the device goes back to sleep. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "eeprom_contents.h" 39 | 40 | // Large font containing only digits. 41 | // TinyOLED-Fonts library needed. 42 | // https://github.com/datacute/TinyOLED-Fonts 43 | #include "Sansita_Swashed_Regular_57_Digits.h" 44 | 45 | // Routines to set and clear bits (used in the sleep code) 46 | #ifndef cbi 47 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 48 | #endif 49 | #ifndef sbi 50 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 51 | #endif 52 | 53 | static bool eepromOk = false; 54 | static uint8_t currentContrast = TEMPERATURE_DEFAULT_CONTRAST; 55 | 56 | static uint8_t currentAddress = TEMPERATURE_READINGS_ADDRESS; 57 | 58 | #define MAIN_BUTTON 4 59 | #define ENTER_BUTTON 3 60 | 61 | // Variables for the Sleep/power down modes: 62 | volatile boolean f_wdt = 0; 63 | static int wdt_counter = 0; 64 | static int graph_display_counter = 0; 65 | 66 | // The watch dog timer wakes up the device every 8 seconds 67 | // The device graphs the last 120 readings 68 | // 10800 * 8 seconds = 1 day. 120 days = 4 months, mark every 7th or 30th 69 | // 450 * 8 seconds = 1 hour. 120 hours = 5 days, mark every 24th 70 | // 75 * 8 seconds = 10 minutes. 1200 minutes = 20 hours, mark every 6th 71 | // 15 * 8 seconds = 2 minutes. 240 minutes = 4 hours, mark every 30th 72 | // 1 * 8 seconds = 8 seconds. 960 seconds = 16 minutes, mark every 38th 73 | #define REPORT_PERIOD 450 74 | #define GRAPH_TICK_COUNT 24 75 | 76 | #define TEMP_CALIBRATION_OFFSET 288.0f 77 | #define TEMP_CALIBRATION_GAIN 1.0f 78 | 79 | // Watchdog Interrupt Service / is executed when watchdog timed out 80 | ISR(WDT_vect) { 81 | f_wdt=1; // set global flag 82 | } 83 | 84 | ISR(PCINT0_vect) {} 85 | 86 | ISR(ADC_vect) { 87 | // ADC conversion complete 88 | } 89 | 90 | void setup() { 91 | setupInputs(); 92 | setupOLED(); 93 | setupFromEEPROM(); 94 | setupWDT(); 95 | oled.setContrast(currentContrast); 96 | displayGraph(); 97 | } 98 | 99 | void setupInputs() { 100 | pinMode(MAIN_BUTTON, INPUT_PULLUP); 101 | pinMode(ENTER_BUTTON, INPUT_PULLUP); 102 | GIMSK = 1 << PCIE; // Enable pin-change interrupt 103 | PCMSK = (1 << MAIN_BUTTON) | (1 << ENTER_BUTTON); 104 | } 105 | 106 | void setupOLED(void) { 107 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 108 | oled.clear(); 109 | oled.setFont(FONTSANSITASWASHEDREGULAR57DIGITS); 110 | } 111 | 112 | static void setupFromEEPROM() { 113 | eepromOk = EEPROM.read(TEMPERATURE_MAGIC_ADDRESS ) == TEMPERATURE_MAGIC0 && 114 | EEPROM.read(TEMPERATURE_MAGIC_ADDRESS + 1) == TEMPERATURE_MAGIC1 && 115 | EEPROM.read(TEMPERATURE_MAGIC_ADDRESS + 2) == TEMPERATURE_MAGIC2 && 116 | EEPROM.read(TEMPERATURE_MAGIC_ADDRESS + 3) == TEMPERATURE_MAGIC3; 117 | if (eepromOk) { 118 | currentContrast = EEPROM.read(TEMPERATURE_CONTRAST_ADDRESS); 119 | currentAddress = EEPROM.read(TEMPERATURE_CURRENT_ADDRESS); 120 | recordTemperature(); // Write a new value at power-on 121 | } else { 122 | settingsResetAction(); 123 | } 124 | } 125 | 126 | static void setupWDT(void) { 127 | int ii = 9; 128 | byte bb; 129 | if (ii > 9 ) ii=9; 130 | bb=ii & 7; 131 | if (ii > 7) bb|= (1<<5); 132 | //bb|= (1< 0) { 153 | graph_display_counter--; 154 | if (graph_display_counter == 0) { 155 | oled.off(); 156 | } 157 | } 158 | } 159 | } 160 | 161 | bool processButtonInputs(void) { 162 | bool mainButtonIsDown = digitalRead(MAIN_BUTTON) == LOW; 163 | if (mainButtonIsDown) { 164 | displayGraph(); 165 | } 166 | bool enterButtonIsDown = digitalRead(ENTER_BUTTON) == LOW; 167 | if (enterButtonIsDown) { 168 | displayGraph(); 169 | } 170 | return mainButtonIsDown || enterButtonIsDown; 171 | } 172 | 173 | static uint8_t ticks[] = { 174 | 0x04, 175 | 0x10, 176 | 0x40, 177 | 0x00, 178 | 0x01, 179 | 0x04, 180 | 0x10, 181 | 0x40 182 | }; 183 | 184 | static uint8_t overlayGraph(uint8_t x, uint8_t y, uint8_t b) { 185 | int itemAddress = currentAddress + x - 2; 186 | if (itemAddress >= 128) itemAddress -= (128 - TEMPERATURE_READINGS_ADDRESS); 187 | uint8_t bottomBit = (7-y) << 3; 188 | int8_t reading = EEPROM.read(itemAddress); 189 | //if (reading < 0) reading = 0; 190 | //if (reading > 60) reading = 60; 191 | uint8_t v = (reading * 2); // mask out pixel below graph 192 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 193 | b &= ~(1 << (7 - (v - bottomBit))); 194 | } 195 | v++; // Shift graph up 1 pixel above ticks line 196 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 197 | b |= 1 << (7 - (v - bottomBit)); 198 | } 199 | v++;// mask out pixel above graph 200 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 201 | b &= ~(1 << (7 - (v - bottomBit))); 202 | } 203 | return b; 204 | } 205 | 206 | static void displayGraph() { 207 | int8_t reading; 208 | for (uint8_t line = 0; line < 8; line++) { 209 | uint8_t bottomBit = (7-line) << 3; 210 | oled.setCursor(0,line); 211 | oled.startData(); 212 | oled.sendData(ticks[line]); 213 | oled.sendData(0xFF); 214 | int itemAddress = currentAddress; // oldest reading 215 | uint8_t tick_column = 0; 216 | do { 217 | reading = EEPROM.read(itemAddress); 218 | //if (reading < 0) reading = 0; 219 | //if (reading > 60) reading = 60; 220 | uint8_t v = (reading * 2) + 1; // Shift graph up 1 pixel above ticks line 221 | uint8_t b = 0; 222 | if ((v >= bottomBit) && (v < (bottomBit + 8))) { 223 | b = 1 << (7 - (v - bottomBit)); 224 | } 225 | if (line == 7) { 226 | b |= 0x40; 227 | tick_column++; 228 | if (tick_column == GRAPH_TICK_COUNT) { 229 | b |= 0x80; 230 | tick_column = 0; 231 | } 232 | } 233 | oled.sendData(b); 234 | itemAddress++; 235 | if (itemAddress >= 128) itemAddress = TEMPERATURE_READINGS_ADDRESS; 236 | } while (itemAddress != currentAddress); 237 | oled.sendData(0xFF); 238 | oled.sendData(ticks[line]); 239 | oled.endData(); 240 | } 241 | // This can be made more efficient by not drawing the following large portion of the graph twice. 242 | oled.setCursor(27,1); 243 | oled.setCombineFunction(&overlayGraph); 244 | oled.print(reading); 245 | oled.setCombineFunction(NULL); 246 | oled.on(); 247 | graph_display_counter = 2; 248 | } 249 | /* 250 | static void setContrast(void) { 251 | oled.setContrast(currentContrast); 252 | if (eepromOk) { 253 | EEPROM.write(TEMPERATURE_CONTRAST_ADDRESS, currentContrast); 254 | } 255 | } 256 | */ 257 | void settingsResetAction(void) { 258 | // EEPROM Header 259 | for (uint16_t offset = 0; offset < sizeof(header); offset++) { 260 | EEPROM.write(offset, pgm_read_byte(&header[offset])); 261 | } 262 | // Default all readings to current temperature value 263 | byte result = readTemperature(); 264 | 265 | for (uint16_t address = sizeof(header); address < 128; address++) { 266 | EEPROM.write(address, result); 267 | } 268 | eepromOk = true; 269 | currentAddress = TEMPERATURE_READINGS_ADDRESS; 270 | currentContrast = TEMPERATURE_DEFAULT_CONTRAST; 271 | } 272 | 273 | static void recordTemperature(void) { 274 | int8_t result = readTemperature(); 275 | 276 | EEPROM.write(currentAddress, (byte)result); 277 | currentAddress++; 278 | if (currentAddress >= 128) { 279 | currentAddress = TEMPERATURE_READINGS_ADDRESS; 280 | } 281 | EEPROM.write(TEMPERATURE_CURRENT_ADDRESS, currentAddress); 282 | } 283 | 284 | static int8_t readTemperature(void) { 285 | return getChipTemperatureCelsius(); 286 | } 287 | 288 | /* below code based on https://github.com/jordan-public/Thermometer-Attiny85/blob/master/Thermometer-Attiny85.ino */ 289 | 290 | // From: http://21stdigitalhome.blogspot.com/2014/10/trinket-attiny85-internal-temperature.html 291 | int8_t getChipTemperatureCelsius() { 292 | int8_t t_celsius; 293 | uint16_t rawTemp; 294 | /* 295 | // Measure temperature 296 | ADCSRA |= _BV(ADEN); // Enable AD and start conversion 297 | ADMUX = 0xF | _BV( REFS1 ); // ADC4 (Temp Sensor) and Ref voltage = 1.1V; 298 | delay(100); // Settling time min 1 ms, wait 100 ms 299 | 300 | rawTemp = (float)getADC(); // use next sample as initial average 301 | ADCSRA &= ~(_BV(ADEN)); // disable ADC 302 | */ 303 | GIMSK &= ~(_BV(PCIE)); // Disable pin-change interrupt 304 | WDTCR &= ~(_BV(WDIE)); 305 | ADCSRA = 1< 60) converted = 60; 330 | if (converted < 0) converted = 0; 331 | return (int8_t)converted; 332 | } 333 | 334 | // Common code for both sources of an ADC conversion 335 | int getADC() { 336 | ADCSRA |=_BV(ADSC); // Start conversion 337 | while((ADCSRA & _BV(ADSC))); // Wait until conversion is finished 338 | return ADC; 339 | } 340 | 341 | /* above code based on https://github.com/jordan-public/Thermometer-Attiny85/blob/master/Thermometer-Attiny85.ino */ 342 | 343 | void system_sleep() { 344 | set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here 345 | //sleep_enable(); 346 | sleep_mode(); // System actually sleeps here 347 | //sleep_disable(); // System continues execution here when watchdog timed out 348 | } 349 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tiny4kOLED 2 | 3 | This is a library for an ATTiny85 to use an SSD1306 powered, 128x64 pixel OLED, over I2C, with double buffering support for the common 128x32 sized screen. 4 | 5 | The SSD1306 has enough RAM to support a 128 by 64 pixel display, and most SSD1306 controlled OLEDs are 128 by 64 pixels. However there are also other display sizes available. With a 128 by 32 pixel display, only half of the SSD1306's RAM is used, and the other half can be used as a frame buffer. This results in being able to have a slow ATTiny85 gradually update the display, then switch it into view when it is ready. 6 | 7 | This library is an adaption of [DigisparkOLED](https://github.com/digistump/DigistumpArduino/tree/master/digistump-avr/libraries/DigisparkOLED) 8 | which in turn is a modification of the [Tinusaur](http://tinusaur.org) project's [SSD1306xLED library](https://bitbucket.org/tinusaur/ssd1306xled). 9 | I have extensively re-written it, with the following changes: 10 | 11 | - Replaced digistump's [Wire](https://github.com/digistump/DigistumpArduino/tree/master/digistump-avr/libraries/Wire) with [TinyWireM](https://github.com/adafruit/TinyWireM) (Digistump's Wire is a rename of TinyWireM, but Adafruit's includes a necessary bug fix.) 12 | - Fixed the sending of multiple bytes per I2C transmission. 13 | - Changed the initialization to be two I2C transmissions, instead of using a transmission per command byte. 14 | - Left the display off in the initialization, so that the display could be cleared before being shown. 15 | - Altered the library to be for a 128x32 display. 16 | - Added double buffering control code. 17 | - Exposed all of the SSD1306 features, with example code (in v1.2). 18 | - Optimised font usage, enabling custom fonts. (See [TinyOLED-Fonts](https://github.com/datacute/TinyOLED-Fonts)) 19 | - Optimised code size. 20 | - Exposed the blink and fade SSD1306 features documented in revision 1.2 of the SSD1306 Specification. 21 | - v1.1 Support three different I2C interfaces: 22 | - Spence Konde's Wire.h that comes with [ATTinyCore](https://github.com/SpenceKonde/ATTinyCore) 23 | - Adafruit's [TinyWireM](https://github.com/adafruit/TinyWireM) 24 | - David Johnson-Davies / Technoblogy's [TinyI2C](https://github.com/technoblogy/tiny-i2c) 25 | - v1.3 Added back support for 128x64 screens, including double buffering when 'zoom' is enabled (32 lines are each drawn twice). 26 | - v1.4 Added support for SSD1306B documented features: 27 | - Ability to select internal current reference, providing consistent, bright displays. 72x40 displays typically do not include an external current reference. 28 | - Ability to select the voltage used by the internal charge pump (results in a minor difference in brightness). 29 | - Ability to horizontally scroll a portion of the display by one pixel (`scrollContentLeft` and `scrollContentRight`). 30 | - v1.5 Added init sequences and offsets for 128x64, 128x32, 72x40, 64x48, and 64x32 resolution screens. 31 | - v2.0 Extended the format used for fonts, adding support for: 32 | - Proportional fonts. 33 | - Multiple font subsets and unicode ranges. 34 | - UTF-8 encoded strings. 35 | - Printing double size text, with and without smoothing. 36 | - Option to reduce memory usage if print functions are not required. 37 | - v2.1 Added support for a user callback function to combine images. See the BatteryMonitor example. 38 | - v2.2 Replaced double size printing methods with double sized font selection methods. 39 | - Standard print methods, Unicode fonts, and new lines now work correctly with double sized text. See [Refactoring to support double sized rendering](https://github.com/datacute/Tiny4kOLED/wiki/Refactoring-to-support-double-sized-rendering). (Note: Double size text only works with fonts up to 16 pixels high.) 40 | - Added clearToEOP and fillToEOP where P stands for page, and fixed issue #10 so the EOL methods work with font heights larger than 8 pixels (1 page). 41 | - Added a 4th I2C interface to do raw bit-banging, but ignoring all the I2C rules. 42 | - Fixed double size text when double buffering (Issue [#41](https://github.com/datacute/Tiny4kOLED/issues/41)) (v2.2.2) 43 | - v2.3 Fixed % character in FONT6X8 and derivatives (Issue [#55](https://github.com/datacute/Tiny4kOLED/issues/55)) 44 | 45 | ## I2C Speeds and External Pullup Resistors 46 | 47 | v2.2 added an I2C speed test example, which can be used as a simple (but rough) guide to the performance of your solution. It display the number of ms it takes to fill the screen. 48 | 49 | Important Notes: 50 | 51 | - Spence Konde (Author and maintainer of the best AVR Cores) has done more analysis of write speeds (see Issue [#52](https://github.com/datacute/Tiny4kOLED/issues/52)), and showing the importance of ensuring your I2C lines have the correct external pullup resisters. 52 | - This section used to have a table of times for different I2C implementations, using an ATTiny85 with nothing but a single random SSD1306 OLED module connected, and NO EXTERNAL PULLUPS. Unfortunately it made the Wire library look bad. The Wire library is the default for Tiny4kOLED as it is the best for a wide range of I2C scenarios. Other implementations take shortcuts or make compromises that may result in incorrect behaviour depending on your hardware configuration choices. 53 | 54 | ## Online Simulator 55 | 56 | The Wokwi Online Arduino Simulator has quite good support for the core features of the 128x64 SSD1306. Here are links to some of the Tiny4kOLED examples: 57 | 58 | - [Bitmap](https://wokwi.com/arduino/projects/319464359609762388) 59 | - [Custom Chinese Font](https://wokwi.com/arduino/projects/319464288025576020) 60 | - [Datacute Boxy Font](https://wokwi.com/arduino/projects/319464228287152724) 61 | - [Devices-128x32](https://wokwi.com/arduino/projects/319464160996885075) 62 | - [Devices-128x64](https://wokwi.com/arduino/projects/319464123042628178) 63 | - [Features Menu](https://wokwi.com/arduino/projects/319463831239656019) 64 | - [Double Buffered Display](https://wokwi.com/arduino/projects/319463992706728532) 65 | - [Unicode Font](https://wokwi.com/arduino/projects/319465327109866067) 66 | - [Double-Size Smooth Text](https://wokwi.com/arduino/projects/319466098578686547) 67 | - [Battery Monitor](https://wokwi.com/arduino/projects/321659614952161874) 68 | 69 | ## 128x64 / 128x32 / 72x40 / 64x48 / 64x32 70 | 71 | The screens with a resolution of 128 by 64 pixels support a feature called 'zoom' where each row is drawn twice. This also only uses half the memory, and so the double buffering technique can be used when the screen is in that mode. 72 | 73 | The double buffering technique doesn't have to be used, and library works with SSD1306 screens of different resolutions, however the default init sequence in this library is for a screen with 32 rows of pixel. Custom init sequences can be supplied. An empty init sequence can also be used with `oled.begin(0,0);` so the SSD1306 can be initialized by your own code. 74 | 75 | The `clear` and `fill` commands, and the wrapping of lines of text by this library, use the screen's height in `pages` (a `page` is 8 rows of pixels). This library defaults the number of `pages` to 4. For screens with other geometries call the `setPages` method, or use the `begin` settings appropriate for your display. 76 | 77 | The following `begin` parameters are supported for the various display resolutions. 78 | The `b` at the end means `b`right. The `r` at the end means `r`otated. 79 | 80 | ```c 81 | // this is equivalent to tiny4koled_init_128x32r 82 | oled.begin(); 83 | 84 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64), tiny4koled_init_128x64); 85 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64b), tiny4koled_init_128x64b); 86 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64r), tiny4koled_init_128x64r); 87 | oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); 88 | 89 | oled.begin(128, 32, sizeof(tiny4koled_init_128x32), tiny4koled_init_128x32); 90 | oled.begin(128, 32, sizeof(tiny4koled_init_128x32b), tiny4koled_init_128x32b); 91 | oled.begin(128, 32, sizeof(tiny4koled_init_128x32r), tiny4koled_init_128x32r); 92 | oled.begin(128, 32, sizeof(tiny4koled_init_128x32br), tiny4koled_init_128x32br); 93 | 94 | oled.begin(72, 40, sizeof(tiny4koled_init_72x40), tiny4koled_init_72x40); 95 | oled.begin(72, 40, sizeof(tiny4koled_init_72x40b), tiny4koled_init_72x40b); 96 | oled.begin(72, 40, sizeof(tiny4koled_init_72x40r), tiny4koled_init_72x40r); 97 | oled.begin(72, 40, sizeof(tiny4koled_init_72x40br), tiny4koled_init_72x40br); 98 | 99 | oled.begin(64, 48, sizeof(tiny4koled_init_64x48), tiny4koled_init_64x48); 100 | oled.begin(64, 48, sizeof(tiny4koled_init_64x48b), tiny4koled_init_64x48b); 101 | oled.begin(64, 48, sizeof(tiny4koled_init_64x48r), tiny4koled_init_64x48r); 102 | oled.begin(64, 48, sizeof(tiny4koled_init_64x48br), tiny4koled_init_64x48br); 103 | 104 | oled.begin(64, 32, sizeof(tiny4koled_init_64x32), tiny4koled_init_64x32); 105 | oled.begin(64, 32, sizeof(tiny4koled_init_64x32b), tiny4koled_init_64x32b); 106 | oled.begin(64, 32, sizeof(tiny4koled_init_64x32r), tiny4koled_init_64x32r); 107 | oled.begin(64, 32, sizeof(tiny4koled_init_64x32br), tiny4koled_init_64x32br); 108 | ``` 109 | 110 | The SSD1306 remembers many of its settings even when powered off. After experimenting with various features, it can be useful to reset all the settings to the default values, which can be done with the following initialization sequence (Note: by default the charge pump is turned off): 111 | 112 | ```c 113 | oled.begin(128, 64, sizeof(tiny4koled_init_defaults), tiny4koled_init_defaults); 114 | oled.enableChargePump(); // The default is off, but most boards need this. 115 | oled.setRotation(1); // The default orientation is not the most commonly used. 116 | ``` 117 | 118 | ## Example Usage 119 | 120 | ```c 121 | // Choose your I2C implementation before including Tiny4kOLED.h 122 | // The default is selected is Wire.h 123 | 124 | // To use the Wire library: 125 | //#include 126 | 127 | // To use the Adafruit's TinyWireM library: 128 | //#include 129 | 130 | // To use the TinyI2C library from https://github.com/technoblogy/tiny-i2c 131 | //#include 132 | 133 | // The blue OLED screen requires a long initialization on power on. 134 | // The code to wait for it to be ready uses 20 bytes of program storage space 135 | // If you are using a white OLED, this can be reclaimed by uncommenting 136 | // the following line (before including Tiny4kOLED.h): 137 | //#define TINY4KOLED_QUICK_BEGIN 138 | 139 | #include 140 | 141 | void setup() { 142 | // Send the initialization sequence to the oled. This leaves the display turned off 143 | oled.begin(); 144 | 145 | // Two rotations are supported, 146 | // The begin() method sets the rotation to 1. 147 | //oled.setRotation(0); 148 | 149 | // Some newer devices do not contain an external current reference. 150 | // Older devices may also support using the internal curret reference, 151 | // which provides more consistent brightness across devices. 152 | // The internal current reference can be configured as either low current, or high current. 153 | // Using true as the parameter value choses the high current internal current reference, 154 | // resulting in a brighter display, and a more effective contrast setting. 155 | //oled.setInternalIref(true); 156 | 157 | // Two fonts are supplied with this library, FONT8X16 and FONT6X8 158 | // Other fonts are available from the TinyOLED-Fonts library 159 | oled.setFont(FONT8X16); 160 | 161 | // Clear the memory before turning on the display 162 | oled.clear(); 163 | 164 | // Turn on the display 165 | oled.on(); 166 | 167 | // Switch the half of RAM that we are writing to, to be the half that is non currently displayed 168 | oled.switchRenderFrame(); 169 | } 170 | 171 | void loop() { 172 | updateDisplay(); 173 | delay(50); 174 | } 175 | 176 | void updateDisplay() { 177 | // Clear the half of memory not currently being displayed. 178 | oled.clear(); 179 | 180 | // Position the text cursor 181 | // In order to keep the library size small, text can only be positioned 182 | // with the top of the font aligned with one of the four 8 bit high RAM pages. 183 | // The Y value therefore can only have the value 0, 1, 2, or 3. 184 | // usage: oled.setCursor(X IN PIXELS, Y IN ROWS OF 8 PIXELS STARTING WITH 0); 185 | oled.setCursor(0, 1); 186 | 187 | // Write text to oled RAM (which is not currently being displayed). 188 | oled.print(F("ms: ")); 189 | 190 | // Write the number of milliseconds since power on. 191 | oled.print(millis()); 192 | 193 | // Swap which half of RAM is being written to, and which half is being displayed. 194 | // This is equivalent to calling both switchRenderFrame and switchDisplayFrame. 195 | oled.switchFrame(); 196 | } 197 | ``` 198 | 199 | *The 4k in the project name is because 128 multiplied by 32 is 4096. This library is for a display with only 4096 pixels, not for UHD displays.* 200 | -------------------------------------------------------------------------------- /src/Tiny4kOLED_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays 3 | * 4 | * Based on ssd1306xled, re-written and extended by Stephen Denne 5 | * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED 6 | * 7 | */ 8 | #include 9 | #include 10 | 11 | #ifndef TINY4KOLEDCOMMON_H 12 | #define TINY4KOLEDCOMMON_H 13 | 14 | typedef struct DCfont { 15 | uint8_t *bitmap; // character bitmaps data 16 | uint8_t width; // character width in pixels 17 | uint8_t height; // character height in pages (8 pixels) 18 | uint8_t first, last; // the lower byte of the unicode block range 19 | // If width above is 0, then that indicates a proportional font 20 | uint16_t *widths16s; 21 | uint8_t *widths; 22 | uint8_t spacing; // number of blank columns of pixels to write between characters 23 | } DCfont; 24 | 25 | // Unicode Blocks are NOT bits 8 to 15 of the codepoint, but this library pretends that they are. 26 | typedef struct DCUnicodeFontRef { 27 | uint8_t unicode_plane; // the unicode plane number 28 | uint8_t unicode_block; // the upper byte of the unicode block 29 | const DCfont *font; // font glyphs within this unicode block 30 | } DCUnicodeFontRef; 31 | 32 | typedef struct DCUnicodeFont { 33 | uint8_t space_width; // the width of the space character, which does not need to be included in the font glyphs. 34 | uint8_t num_fonts; // number of character ranges in this unicode font 35 | const DCUnicodeFontRef * fonts; // the font references 36 | } DCUnicodeFont; 37 | 38 | union DCUnicodeCodepoint { 39 | uint32_t codepoint; 40 | struct { 41 | uint8_t offset; 42 | uint8_t block; 43 | uint8_t plane; 44 | uint8_t unused; 45 | } unicode; 46 | }; 47 | 48 | // included fonts, The space isn't used unless it is needed 49 | #include "font6x8.h" 50 | #include "font6x8p.h" 51 | #include "font6x8digits.h" 52 | #include "font6x8caps.h" 53 | #include "font8x16.h" 54 | #include "font8x16p.h" 55 | #include "font8x16caps.h" 56 | #include "font8x16capsp.h" 57 | #include "font8x16digits.h" 58 | 59 | // ---------------------------------------------------------------------------- 60 | 61 | #ifndef SSD1306 62 | #define SSD1306 0x3C // Slave address 63 | #endif 64 | 65 | #define SSD1306_VOLTAGE_6_0 0x15 66 | #define SSD1306_VOLTAGE_7_5 0x14 67 | #define SSD1306_VOLTAGE_8_5 0x94 68 | #define SSD1306_VOLTAGE_9_0 0x95 69 | 70 | // ---------------------------------------------------------------------------- 71 | 72 | // Spence Konde's ATTinyCore defines the F macro as 73 | // #define F(string_literal) (reinterpret_cast(PSTR(string_literal))) 74 | 75 | // Digistump uses 76 | // # define F(s) ((fstr_t*)PSTR(s)) 77 | 78 | #ifndef DATACUTE_F_MACRO_T 79 | #ifdef ARDUINO_AVR_DIGISPARK 80 | #define DATACUTE_F_MACRO_T fstr_t 81 | #else 82 | #define DATACUTE_F_MACRO_T const __FlashStringHelper 83 | #endif 84 | #endif 85 | 86 | #ifndef FPSTR 87 | #define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) 88 | #endif 89 | 90 | // ---------------------------------------------------------------------------- 91 | 92 | class SSD1306Device { 93 | 94 | public: 95 | SSD1306Device(void (*wireBeginFunc)(void), bool (*wireBeginTransmissionFunc)(void), bool (*wireWriteFunc)(uint8_t byte), uint8_t (*wireEndTransmissionFunc)(void)); 96 | 97 | void begin(void); 98 | void begin(uint8_t init_sequence_length, const uint8_t init_sequence []); 99 | void begin(uint8_t width, uint8_t height, uint8_t init_sequence_length, const uint8_t init_sequence []); 100 | void begin(uint8_t xOffset, uint8_t yOffset, uint8_t width, uint8_t height, uint8_t init_sequence_length, const uint8_t init_sequence []); 101 | void switchRenderFrame(void); 102 | void switchDisplayFrame(void); 103 | void switchFrame(void); 104 | uint8_t currentRenderFrame(void); 105 | uint8_t currentDisplayFrame(void); 106 | void setFont(const DCfont *font); 107 | void setUnicodeFont(const DCUnicodeFont *unicode_font); 108 | void setFontX2(const DCfont *font); 109 | void setUnicodeFontX2(const DCUnicodeFont *unicode_font); 110 | void setFontX2Smooth(const DCfont *font); 111 | void setUnicodeFontX2Smooth(const DCUnicodeFont *unicode_font); 112 | // If your code does not call oled.print then you can save space by calling setFontOnly instead of the above. 113 | void setFontOnly(const DCfont *font); 114 | void setSpacing(uint8_t spacing); 115 | void setCombineFunction(uint8_t (*combineFunc)(uint8_t, uint8_t, uint8_t)); 116 | uint8_t getExpectedUtf8Bytes(void); 117 | uint16_t getCharacterDataOffset(uint8_t c); 118 | uint8_t getCharacterWidth(uint8_t c); 119 | uint16_t getTextWidth(DATACUTE_F_MACRO_T *text); 120 | void setCursor(uint8_t x, uint8_t y); 121 | uint8_t getCursorX(); 122 | uint8_t getCursorY(); 123 | void newLine(); 124 | void fill(uint8_t fill); 125 | void fillToEOL(uint8_t fill); 126 | void fillToEOP(uint8_t fill); 127 | void fillLength(uint8_t fill, uint8_t length); 128 | void clear(void); 129 | void clearToEOL(void); 130 | void clearToEOP(void); 131 | void bitmap(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, const uint8_t bitmap[]); 132 | void startData(void); 133 | void sendData(const uint8_t data); 134 | void repeatData(uint8_t data, uint8_t length); 135 | void clearData(uint8_t length); 136 | void endData(void); 137 | void setPages(uint8_t pages); 138 | void setWidth(uint8_t width); 139 | void setHeight(uint8_t height); 140 | void setOffset(uint8_t xOffset, uint8_t yOffset); 141 | void setRotation(uint8_t rotation); 142 | void clipText(uint16_t startPixel, uint8_t width, DATACUTE_F_MACRO_T *text); 143 | void clipTextP(uint16_t startPixel, uint8_t width, DATACUTE_F_MACRO_T *text); 144 | void invertOutput(bool enable); 145 | 146 | // 1. Fundamental Command Table 147 | 148 | void setContrast(uint8_t contrast); 149 | void setEntireDisplayOn(bool enable); 150 | void setInverse(bool enable); 151 | void setExternalIref(void); 152 | void setInternalIref(bool bright); 153 | void off(void); 154 | void on(void); 155 | 156 | // 2. Scrolling Command Table 157 | 158 | void scrollRight(uint8_t startPage, uint8_t interval, uint8_t endPage, uint8_t startColumn = 0x00, uint8_t endColumn = 0xFF); 159 | void scrollLeft(uint8_t startPage, uint8_t interval, uint8_t endPage, uint8_t startColumn = 0x00, uint8_t endColumn = 0xFF); 160 | void scrollRightOffset(uint8_t startPage, uint8_t interval, uint8_t endPage, uint8_t offset); 161 | void scrollLeftOffset(uint8_t startPage, uint8_t interval, uint8_t endPage, uint8_t offset); 162 | void scrollContentRight(uint8_t startPage, uint8_t endPage, uint8_t startColumn, uint8_t endColumn); 163 | void scrollContentLeft(uint8_t startPage, uint8_t endPage, uint8_t startColumn, uint8_t endColumn); 164 | void deactivateScroll(void); 165 | void activateScroll(void); 166 | void setVerticalScrollArea(uint8_t top, uint8_t rows); 167 | 168 | // 3. Addressing Setting Command Table 169 | void setColumnStartAddress(uint8_t startAddress); 170 | void setMemoryAddressingMode(uint8_t mode); 171 | void setColumnAddress(uint8_t startAddress, uint8_t endAddress); 172 | void setPageAddress(uint8_t startPage, uint8_t endPage); 173 | void setPageStartAddress(uint8_t startPage); 174 | 175 | // 4. Hardware Configuration (Panel resolution and layout related) Command Table 176 | 177 | void setDisplayStartLine(uint8_t startLine); 178 | void setSegmentRemap(uint8_t remap); 179 | void setMultiplexRatio(uint8_t mux); 180 | void setComOutputDirection(uint8_t direction); 181 | void setDisplayOffset(uint8_t offset); 182 | void setComPinsHardwareConfiguration(uint8_t alternative, uint8_t enableLeftRightRemap); 183 | 184 | // 5. Timing and Driving Scheme Setting Command table 185 | 186 | void setDisplayClock(uint8_t divideRatio, uint8_t oscillatorFrequency); 187 | void setPrechargePeriod(uint8_t phaseOnePeriod, uint8_t phaseTwoPeriod); 188 | void setVcomhDeselectLevel(uint8_t level); 189 | void nop(void); 190 | 191 | // 6. Advance Graphic Command table 192 | 193 | void fadeOut(uint8_t interval); 194 | void blink(uint8_t interval); 195 | void disableFadeOutAndBlinking(void); 196 | void enableZoomIn(void); 197 | void disableZoomIn(void); 198 | 199 | // Charge Pump Settings 200 | 201 | void enableChargePump(uint8_t voltage = SSD1306_VOLTAGE_7_5); 202 | void disableChargePump(void); 203 | 204 | size_t write(byte c); 205 | 206 | private: 207 | void newLine(uint8_t fontHeight); 208 | void decodeAsciiInternal(uint8_t c); 209 | void decodeUtf8Internal(uint8_t c); 210 | void RenderUnicodeSpace(void); 211 | bool SelectUnicodeBlock(void); 212 | void renderOriginalSize(uint8_t c); 213 | void renderDoubleSize(uint8_t c); 214 | void renderDoubleSizeSmooth(uint8_t c); 215 | void sendDoubleBits(uint32_t doubleBits); 216 | 217 | }; 218 | 219 | class SSD1306PrintDevice: public Print, public SSD1306Device { 220 | public: 221 | SSD1306PrintDevice(void (*wireBeginFunc)(void), bool (*wireBeginTransmissionFunc)(void), bool (*wireWriteFunc)(uint8_t byte), uint8_t (*wireEndTransmissionFunc)(void)) : 222 | SSD1306Device(wireBeginFunc, wireBeginTransmissionFunc, wireWriteFunc, wireEndTransmissionFunc) {}; 223 | size_t write(byte c) { 224 | return SSD1306Device::write(c); 225 | }; 226 | using Print::write; 227 | }; 228 | 229 | // ---------------------------------------------------------------------------- 230 | 231 | static const uint8_t tiny4koled_init_defaults [] PROGMEM = { // Initialization Sequence 232 | 0xAE, // Display OFF (sleep mode) 233 | 0x20, 0b10, // Set Memory Addressing Mode 234 | // 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode; 235 | // 10=Page Addressing Mode (RESET); 11=Invalid 236 | 0xB0, // Set Page Start Address for Page Addressing Mode, 0-7 237 | 0xC0, // Set COM Output Scan Direction 238 | 0x00, // Set low nibble of column address 239 | 0x10, // Set high nibble of column address 240 | 0x40, // Set display start line address 241 | 0x81, 0x7F, // Set contrast control register 242 | 0xA0, // Set Segment Re-map. A0=column 0 mapped to SEG0; A1=column 127 mapped to SEG0. 243 | 0xA6, // Set display mode. A6=Normal; A7=Inverse 244 | 0xA8, 0x3F, // Set multiplex ratio(1 to 64) 245 | 0xA4, // Output RAM to Display 246 | // 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content 247 | 0xD3, 0x00, // Set display offset. 00 = no offset 248 | 0xD5, 0x80, // --set display clock divide ratio/oscillator frequency 249 | 0xD9, 0x22, // Set pre-charge period 250 | 0xDA, 0x12, // Set com pins hardware configuration 251 | 0xDB, 0x20, // --set vcomh 0x20 = 0.77xVcc 252 | 0xAD, 0x00, // Select external IREF. 0x10 or 0x30 for Internal current reference at 19uA or 30uA 253 | 0x8D, 0x10 // Set DC-DC disabled 254 | }; 255 | 256 | // Naming configuration for initialisation sequences: 257 | // tiny4koled_init_{x}x{y}{b}{r} 258 | // x = width in pixels 259 | // y = height in pixels 260 | // b = bright - turns on internal current reference set to the high current setting 261 | // r = rotated - rotates the display 180 degrees. 262 | 263 | // the four combinations of bright and rotated are supported for each of the following resolutions: 264 | // 128 x 64 265 | // 128 x 32 266 | // 72 x 40 (These typically require the use of the internal current refference) 267 | // 64 x 48 268 | // 64 x 32 269 | 270 | // Initialization sequence for 128 x 64 screen 271 | static const uint8_t tiny4koled_init_128x64 [] PROGMEM = { 272 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 273 | }; 274 | 275 | // Initialization sequence for bright 128 x 64 screen 276 | static const uint8_t tiny4koled_init_128x64b [] PROGMEM = { 277 | 0xAD, 0x30, // Select internal IREF and higher current 278 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 279 | }; 280 | 281 | // Initialization sequence for rotated 128 x 64 screen 282 | static const uint8_t tiny4koled_init_128x64r [] PROGMEM = { 283 | 0xC8, // Set COM Output Scan Direction 284 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 285 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 286 | }; 287 | 288 | // Initialization sequence for bright rotated 128 x 64 screen 289 | static const uint8_t tiny4koled_init_128x64br [] PROGMEM = { 290 | 0xC8, // Set COM Output Scan Direction 291 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 292 | 0xAD, 0x30, // Select internal IREF and higher current 293 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 294 | }; 295 | 296 | // Initialization sequence for 128 x 32 screen 297 | static const uint8_t tiny4koled_init_128x32 [] PROGMEM = { 298 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 299 | 0xDA, 0x02, // Set com pins hardware configuration 300 | 0x8D, 0x14 // Set DC-DC enable 301 | }; 302 | 303 | // Initialization sequence for bright 128 x 32 screen 304 | static const uint8_t tiny4koled_init_128x32b [] PROGMEM = { 305 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 306 | 0xDA, 0x02, // Set com pins hardware configuration 307 | 0xAD, 0x30, // Select external IREF. 0x10 or 0x30 for Internal current reference at 19uA or 30uA 308 | 0x8D, 0x14 // Set DC-DC enable 309 | }; 310 | 311 | // Initialization sequence for rotated 128 x 32 screen 312 | static const uint8_t tiny4koled_init_128x32r [] PROGMEM = { 313 | 0xC8, // Set COM Output Scan Direction 314 | 0xA1, // Set Segment Re-map. A0=column 0 mapped to SEG0; A1=column 127 mapped to SEG0. 315 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 316 | 0xDA, 0x02, // Set com pins hardware configuration 317 | 0x8D, 0x14 // Set DC-DC enable 318 | }; 319 | 320 | // Initialization sequence for bright rotated 128 x 32 screen 321 | static const uint8_t tiny4koled_init_128x32br [] PROGMEM = { 322 | 0xC8, // Set COM Output Scan Direction 323 | 0xA1, // Set Segment Re-map. A0=column 0 mapped to SEG0; A1=column 127 mapped to SEG0. 324 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 325 | 0xDA, 0x02, // Set com pins hardware configuration 326 | 0xAD, 0x30, // Select external IREF. 0x10 or 0x30 for Internal current reference at 19uA or 30uA 327 | 0x8D, 0x14 // Set DC-DC enable 328 | }; 329 | 330 | // Initialization sequence for 72 x 40 screen 331 | static const uint8_t tiny4koled_init_72x40 [] PROGMEM = { 332 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 333 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 334 | }; 335 | 336 | // Initialization sequence for bright 72 x 40 screen 337 | static const uint8_t tiny4koled_init_72x40b [] PROGMEM = { 338 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 339 | 0xAD, 0x30, // Select internal IREF and higher current 340 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 341 | }; 342 | 343 | // Initialization sequence for rotated 72 x 40 screen 344 | static const uint8_t tiny4koled_init_72x40r [] PROGMEM = { 345 | 0xC8, // Set COM Output Scan Direction 346 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 347 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 348 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 349 | }; 350 | 351 | // Initialization sequence for bright rotated 72 x 40 screen 352 | static const uint8_t tiny4koled_init_72x40br [] PROGMEM = { 353 | 0xC8, // Set COM Output Scan Direction 354 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 355 | 0xA8, 0x27, // Set multiplex ratio(1 to 64) 356 | 0xAD, 0x30, // Select internal IREF and higher current 357 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 358 | }; 359 | 360 | // Initialization sequence for 64 x 48 screen 361 | static const uint8_t tiny4koled_init_64x48 [] PROGMEM = { 362 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 363 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 364 | }; 365 | 366 | // Initialization sequence for bright 64 x 48 screen 367 | static const uint8_t tiny4koled_init_64x48b [] PROGMEM = { 368 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 369 | 0xAD, 0x30, // Select internal IREF and higher current 370 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 371 | }; 372 | 373 | // Initialization sequence for rotated 64 x 48 screen 374 | static const uint8_t tiny4koled_init_64x48r [] PROGMEM = { 375 | 0xC8, // Set COM Output Scan Direction 376 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 377 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 378 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 379 | }; 380 | 381 | // Initialization sequence for bright rotated 64 x 48 screen 382 | static const uint8_t tiny4koled_init_64x48br [] PROGMEM = { 383 | 0xC8, // Set COM Output Scan Direction 384 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 385 | 0xA8, 0x2F, // Set multiplex ratio(1 to 64) 386 | 0xAD, 0x30, // Select internal IREF and higher current 387 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 388 | }; 389 | 390 | // Initialization sequence for 64 x 32 screen 391 | static const uint8_t tiny4koled_init_64x32 [] PROGMEM = { 392 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 393 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 394 | }; 395 | 396 | // Initialization sequence for bright 64 x 32 screen 397 | static const uint8_t tiny4koled_init_64x32b [] PROGMEM = { 398 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 399 | 0xAD, 0x30, // Select internal IREF and higher current 400 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 401 | }; 402 | 403 | // Initialization sequence for rotated 64 x 32 screen 404 | static const uint8_t tiny4koled_init_64x32r [] PROGMEM = { 405 | 0xC8, // Set COM Output Scan Direction 406 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 407 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 408 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 409 | }; 410 | 411 | // Initialization sequence for bright rotated 64 x 32 screen 412 | static const uint8_t tiny4koled_init_64x32br [] PROGMEM = { 413 | 0xC8, // Set COM Output Scan Direction 414 | 0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped. 415 | 0xA8, 0x1F, // Set multiplex ratio(1 to 64) 416 | 0xAD, 0x30, // Select internal IREF and higher current 417 | 0x8D, 0x14 // Set DC-DC enable 7.5V (We can't see the screen without the charge pump on) 418 | }; 419 | 420 | #endif 421 | --------------------------------------------------------------------------------