Giter Club home page Giter Club logo

ssd1306ascii's People

Contributors

biank88 avatar greiman avatar reaper7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ssd1306ascii's Issues

QUESTION:"refresh rate"

Is it possible to have only one line refreshing instead of whole screen?

I have data coming from a sensor, there are few lines displayed on screen which dont need to be refreshed(text) , but data from sensor should be updated every time it changes. So is there a way to make just one "line" refresh or to smooth out the refreshing (of the whole screen) or make it faster?

Thanks

P.S. I have just started arduino and you made a great library for oled, thank you once again

Compatability with SH1106

I was wondering if I could have help getting a version of this library that is compatible with the SH1106 driver which is 132 pixels wide, and causes the display to be cut off on the left side.

begin with Slow i2c 100kHz mode

Hi,
as I'm not interested in using high speed 400kHz i2c mode to drive the display,
I actually add a beginSlow() in SSD1306AsciiAvrI2c.h
There's another, method to don't use the fast mode?

void beginSlow(const DevType* dev, uint8_t i2cAddr) {
    m_nData = 0;
    m_i2cAddr = i2cAddr;

    m_i2c.begin(false);
    init(dev);    

 }

SSD1306AsciiAvrI2c.setCursor() is using pixels instead of columns to set cursor

I have found out that SSD1306AsciiAvrI2c.setCursor(column, row) is properly setting row properly, but for columns it uses pixels instead of columns. I.e. SSD1306AsciiAvrI2c.setCursor(10,3) will set cursor to 3rd row and 10th pixel instead of 3rd row and 10th column.

This is sample code from git( just removed 2x enlargement) to reproduce:

#include "SSD1306Ascii.h"
#include "SSD1306AsciiAvrI2c.h"

// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiAvrI2c oled;
//------------------------------------------------------------------------------
void setup() {

#if RST_PIN >= 0
  oled.begin(&Adafruit128x32, I2C_ADDRESS, RST_PIN);
#else // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif // RST_PIN >= 0
  // Call oled.setI2cClock(frequency) to change from the default frequency.

  oled.setFont(System5x7);

  uint32_t m = micros();

  oled.clear();

  // first row
  oled.println("set1X test");

  /* 
second row, this guy will show A in the middle of the screen(128x64) for the 5x7 font. For columns this coordinates are not acceptable at all. You can try setting it to setCursor(13,3) -- it will be slightly shifted from the left corner, instead of being set almost to the middle of the 128x64 screen.
*/  
oled.setCursor(62,3);
  oled.println("A");

  // third row
  oled.set1X();
  oled.print("micros: ");
  oled.print(micros() - m);
}
//------------------------------------------------------------------------------
void loop() {}

SSD1306 flashes on and off on waking from deepsleep . Any workaround ?

I am using a ESP32 Dev Module and the 128x64 I2C SSD1306 using your library. My program needs to deepsleep and wake up twice every second. On every wake the SSD is sent a screen reset and so my display blinks twice every second. Not very pleasant

Can I do something to stop that ?

Thanks

Adding library

Real newbie question...

How do I install your library into the Arduino IDE? I have tried downloading as Zip, then in IDE: Sketch/Include Library/Add .ZIP library but the IDE complains it's not a valid library zip

Are umlauts supported?

First of all, thank you very much for this great library!
Does it also support umlauts like ö,ä,ü... ? I did not find any solution.

"warning set400kHz() disabled for this CPU" using an ESP8266 board

When using SSD1306AsciiWire.h in an Arduino sketch on an Esp8266 board the following warning is given:

 #warning set400kHz() disabled for this CPU.

I see in SSD1306AsciiWire.h that this warning is given unless an AVR or SAM3X8E is recognized.

Despite this warning the library works fine on my ESP8266 :-)

X and Y

I have been looking everywhere for a way to print a line to a specific X and Y but I can't seem to find the function. The closest thing I could find in the example sketches was

oled.setCursor(0, 10);

but that doesn't seem to do anything. If anyone could help me out I would appreciate it.

inverted colors (monochrome)

Hey, im not a programmer, but i needed an 'active' state for my gui elements, so i've hacked your lib with a few lines here:

SSD1306Ascii.h:

  • at initialization: SSD1306Ascii() : m_magFactor(1), m_font(0), m_invert(false) {}
  • somewhere near set2X(): void invert() {m_invert = !m_invert;}
  • and at the bottom vars: bool m_invert;

and here SSD1306Ascii.cpp, function write:

  • after the uint8_t b = readFontByte(base + c + r*w);
    line: if (m_invert) b = 0xFF - b;
  • and replaced the ssd1306WriteRamBuf(0); few lines below with
    uint8_t v = m_invert ? 0xFF : 0;
    ssd1306WriteRamBuf(v);

Then within my sketch i can turn on and off this inverted colors like such:

oled.println("Hello world!."); // white on black
oled.invert();
oled.println("inverted"); // black on white
oled.invert();
oled.println("A long line may be truncated"); // white on black again

I am aware this is a dirty dirty hack, but you could include a similar functionality in the library since it doesn't take much space and is potentially quite useful...

cheers!

More features

Hello,

I've been looking for a debugging solution for my arduino mega without connecting it to my laptop for Serial, and I came across this wonderful library! It was an easy setup to display text on my tiny oled screen. I know it's still in development, so here are some features I'd love to see some day:

  • When printing a long line, instead of truncating, break it down and print in multiple lines
  • Rotate screen. If it would helpful to use the screen as 64x128 instead of 128x64

Despite my limited programming knowledge, I will try to figure this out and post it here. Thanks for the library!

flickering screen

Trying to run some printlns and then clear in loop{} and the screen will show the text but flicker as it does so.

Request : Add scroll feature to PRINTLN

Hi,

I use your library mainly as a replacement for the Arduino Serial Monitor, using the print and println statements. Works brilliantly.

In the current version println fills the screen up to the last line on the display, and subsequent println statements also outputs on the last line of the display.

For me the wanted behavior would be the display to scroll up the content of the display when using println on the bottom line of the display.

I added some "proof of concept" code to the function "write" in the file Ssd1306Ascii.cpp (see below). This works fine, but has the flaw that the screen starts scrolling immediately after EVERY println statement, instead of scrolling ONLY at a println on the last line.

Perhaps you would consider to add a properly integrated scroll feature, so I can throw my own non-perfect code away :-)

Thanks.

Proof of concept code for println scroll feature

I replaced

    if (ch == '\n') {
      setCursor(0, m_row + m_magFactor*nr);
      return 1;
    }

with

    if (ch == '\n') {
      m_row = m_row + m_magFactor*nr;
      // when m_row > 7 reset to 0
      if (m_row > 7) m_row=0;
      setCursor(0, m_row);
      // clear the line from old content
      clearToEOL();
      // scroll the entire screen 8 pixels up
      ssd1306WriteCmd(SSD1306_SETDISPLAYOFFSET);
      ssd1306WriteCmd( (m_row +1) * 8);
      return 1;
    }

Working with Heltec Wifi Kit 32

This library is exactly what I'm looking for, but I tried your basic example (WireI2c128x64.ino) for the Heltec Wifii Kit 32 with .96" OLED display, and I can't get it to work. It compiles and downloads to the board without a problem, but never displays anything. I'm guessing it's because there's not a DevType defined for that board, and some of the initialization settings aren't correct. Ditto for the I2C pin's hex number. My problem, being pretty new to all of this, is trying to figure out how to modify an existing DevType to work with this board, and to determine its I2C pin hex number.

I tried both the AdaFruit DevType and the SH1106_128x64, with the same result: compiles and loads, doesn't display anything. I changed the reset pin to 16 (that's what it is on this board) - no help.

I ran a simple I2C scanner sketch on the board and it said "No I2C devices found" - but surely this OLED display has an I2C interface?

I've been able to get the board / display to work with the u8x8 library (part of the U8g2 library). (I would much rather user YOUR library, though!) The constructor that works from that library is U8X8_SSD1306_128X64_NONAME_SW_I2C. Here's what the constructor looks like, if that gives you any clues:
U8X8_SSD1306_128X64_NONAME_SW_I2C(uint8_t clock, uint8_t data, uint8_t reset = U8X8_PIN_NONE) : U8X8() {
u8x8_Setup(getU8x8(), u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_i2c, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_arduino);
u8x8_SetPin_SW_I2C(getU8x8(), clock, data, reset);

This is the github page for the board itself. https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series

Here's the schematic of the board, showing the pins of the OLED - I'm hoping the answer is in here somewhere?
https://github.com/Heltec-Aaron-Lee/WiFi_Kit_series/blob/master/SchematicDiagram/WIFI_Kit_32_Schematic_diagram.PDF

What do I need to know to make this board work with this library? Thanks!

initializing problem?

Hi,
at first thank you very much for this tiny lib. I am using it with an adafruit 128x32 IIC display. It work almost perfect for me, but I have trouble to get the display running after connecting power to the arduino. I started using your lib after some examples of the ada lib. Creating a sketch with this lib is very simple and works fine until disconecting power and switch on again. Then the display shows only some waste pixels. The only possibility to get the display working again is to use a ada-lib example. After this I can use the sketch with your lib again until switching off power. Do you have any idea what is going wrong here? Thank you very much.
kind regards, Kay

DISPLAYON, DISPLAYOFF

Hi,
I'm using the Library with Arduino pro mini and ESP8266 and an OLED-Display 128x64.

Everthing works so far and now I want to put the Display off over night and on at the beginning of the next day, to increase the lifetime of the OLED.

What would you recomment to do?
Which command would be the best?

Regards
Volker

Have a way to test if an SSD1306 Oled display is present

My project can use several displays and an SSD1306 OLED display is not mandatory. But if I try to call the begin method, it freezes my firmware as I use your version I²C. So I have no practical way to detect an SSD1306 controller is present through your interface. I notice there is an active polling to check an ACK after sending a command. Wouldn't it be okay to poll a certain amount and abort with a boolean telling if it was ACKed? At least begin may return a boolean to say if a SSD1306 was able to answer while the rest of interface may stay unchanged.

Regards.

Flickering 2.0

Screen is flickering as if literally seeing it refresh. worsening on right side and lower side of screen .

COde:

#define I2C_ADDRESS 0x3C
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"

SSD1306AsciiWire oled;

void setup()
{
Wire.begin();
oled.begin(&Adafruit128x32, I2C_ADDRESS);
oled.set400kHz();
oled.setFont(Iain5x7);
}

void loop()
{
oled.clear();
oled.println("flickering");
}

Chip:
Arduino Nano V3.0, Elegoo Nano board CH340/ATmega328P

Screen:
MakerFocus 2pcs I2C OLED Display Module 0.91 Inch I2C SSD1306 OLED Display Module Blue I2C OLED Screen Driver DC 3.3V~5V for Arduino

Added Support for 96x16 SSD1306 Oled Display

I added support for the 96x16 SSD1306 Oled Display. Initialization follows specification from this displays data sheet.

Adafruit96x16
SSD1306init.zip

It's not actually an Adafruit display but it seem like it would be better to conform to how the rest of SSD1306 displays are initialized in this library.

//------------------------------------------------------------------------------
// This section is based on data sheet for the 96x16 SSD1306
// https://www.buydisplay.com/download/manual/ER-OLED0.69-1_Series_Datasheet.pdf
/** Initialization commands for a 96x16 SSD1306 oled display. /
static const uint8_t MEM_TYPE Adafruit96x16init[] = {
// Init sequence for Adafruit 128x32 OLED module
SSD1306_DISPLAYOFF,
SSD1306_SETDISPLAYCLOCKDIV, 0x80, // the suggested ratio 0x80
SSD1306_SETMULTIPLEX, 0x0F, // ratio 32
SSD1306_SETDISPLAYOFFSET, 0x0, // no offset
SSD1306_SETSTARTLINE | 0x40, // line #0
SSD1306_CHARGEPUMP, 0x14, // internal vcc
SSD1306_MEMORYMODE, 0x00, // page mode
SSD1306_SEGREMAP | 0xA1, // column 95 mapped to SEG0
SSD1306_COMSCANDEC, // column scan direction reversed
SSD1306_SETCOMPINS, 0x02, // sequential COM pins, disable remap
SSD1306_SETCONTRAST, 0xAF, // contrast level 175
SSD1306_SETPRECHARGE, 0xF1, // pre-charge period (1, 15)
SSD1306_SETVCOMDETECT, 0x20, // vcomh regulator level
SSD1306_DISPLAYALLON_RESUME,
SSD1306_NORMALDISPLAY,
SSD1306_DISPLAYON
};
/
* Initialize a 96x16 SSD1306 oled display. */
static const DevType MEM_TYPE Adafruit96x16 = {
Adafruit96x16init,
sizeof(Adafruit96x16init),
96,
16,
0
};

96x16 ssd1306

println() stops working and freezes program

Hi,

I've been testing a few different libraries to use an oled display.

With SSD1306AsciiAvrI2c, I'm having an issue where a call to println() just stops in the middle of the string (I can see the line not entirely showing on the display) and it seems to freeze the program entirely. This happens only after running the program for 2-3 minutes.

Edit: I was testing that on a Pro Micro. On a Leonardo, it can't even run the entire 3 texts loop, it usually freezes randomly in the middle of text 1, 2 or 3.

Interestingly, this doesn't happen when I use Wire. But using Wire eats up more memory so I'd like to stick with AvrI2c.

This is my code:

#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>

#define I2C_ADDRESS 0x3C

SSD1306AsciiAvrI2c oled;

char textDisplayed = 3;
const int displayDelay = 3000;
long lastDisplay = 0;

void setup() {
  Serial.begin(9600);
  oled.begin(&Adafruit128x64, I2C_ADDRESS);

  oled.setFont(System5x7);
}

void loop() {
  if (millis() - lastDisplay >= displayDelay || lastDisplay == 0) {

    if (textDisplayed == 3) {
      oled.clear();
      oled.println("Hello LouWii!");
      oled.println("It's me, Pro Micro!");
      oled.println("=]");
    
      Serial.println(F("1"));

      textDisplayed = 1;
      lastDisplay = millis();
    } else if (textDisplayed == 1) {
      oled.clear();

      oled.println("Scrolling? ");
      Serial.println(F("2"));

      textDisplayed = 2;
      lastDisplay = millis();
    } else if (textDisplayed == 2) {
      oled.clear();

      oled.println("");
      oled.println("");
      oled.println("   \\\\\\||||||////");
      oled.println("    \\\\  ~ ~  //");
      oled.println("     (  @ @  )");
      oled.println("___oOOo-(_)-oOOo___");

      Serial.println(F("3"));

      textDisplayed = 3;
      lastDisplay = millis();
    }

  }
}

Font Length wrong conversion?

From allFonts.h, " FONT_LENGTH is a 16 bit Big Endian length field."

But in SSD1306Ascii.cpp:

size_t SSD1306Ascii::write(uint8_t ch) { const uint8_t* base = m_font; if (!base) return 0; uint16_t size = readFontByte(base++) << 4; size |= readFontByte(base++);

I think 4 is not right. Should it be

uint16_t size = readFontByte(base++) << 8;

how to display bitmap

I tried to use the function **ssd1306WriteRam (uint8_t c)** to display some points on the screen, but I couldn't display them by coordinates, and I wanted to display some graphics or characters obtained by the modulo software but I couldn't implement them (I am a programming newcomer). 
I really like this library because it's really small, it's very helpful for my development, but I don't want to give it up and use other libraries that are more powerful but use more storage, so I hope you can help a little. thank you very much!

inverted text with dark background

Hello,
For some sensor values above or below the expected value, I use the oled display to show these out of bound values in dark background and light text.

is there any way to do this in SSD1306Ascii?

clear() takes 60ms.

oled.clear takes about 60ms to clear the display, using an I2C 128x64 from ebay. This causes horrible flickering problems. Is it possible to speed this up?

Scrolling

Hi there

Would it be possible for you to add a vertical scrolling function ?

Thanks in advance.
Tvix.

Compiler error with Arduino Due

In file included from /Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/SSD1306AsciiAvrI2c.h:26:0,
from /Users/rcaratti/Downloads/si5351_vfobfo/si5351_vfobfo.ino:17:
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'void AvrI2c::begin(bool)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:65:5: error: 'TWSR' was not declared in this scope
TWSR = 0;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'uint8_t AvrI2c::read(bool)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:77:19: error: 'TWINT' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:77:34: error: 'TWEN' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:77:60: error: 'TWEA' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWEN) | (last ? 0 : (1 << TWEA)));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:78:12: error: 'TWDR' was not declared in this scope
return TWDR;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'void AvrI2c::setClock(uint32_t)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:98:5: error: 'TWBR' was not declared in this scope
TWBR = ((F_CPU / frequency) - 16) / 2;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'bool AvrI2c::start(uint8_t)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:109:19: error: 'TWINT' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:109:34: error: 'TWSTA' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:109:49: error: 'TWEN' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWSTA) | (1 << TWEN));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:114:5: error: 'TWDR' was not declared in this scope
TWDR = addressRW;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'void AvrI2c::stop()':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:126:5: error: 'TWCR' was not declared in this scope
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:126:18: error: 'TWINT' was not declared in this scope
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:126:33: error: 'TWEN' was not declared in this scope
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:126:47: error: 'TWSTO' was not declared in this scope
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'bool AvrI2c::write(uint8_t)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:139:5: error: 'TWDR' was not declared in this scope
TWDR = data;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:140:19: error: 'TWINT' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWEN));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:140:34: error: 'TWEN' was not declared in this scope
execCmd((1 << TWINT) | (1 << TWEN));
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h: In member function 'void AvrI2c::execCmd(uint8_t)':
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:149:5: error: 'TWCR' was not declared in this scope
TWCR = cmdReg;
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:151:27: error: 'TWINT' was not declared in this scope
while (!(TWCR & (1 << TWINT))) {}
^
/Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii/src/utility/AvrI2c.h:153:15: error: 'TWSR' was not declared in this scope
status_ = TWSR & 0xF8;
^
Using library Encoder at version 1.4.1 in folder: /Users/rcaratti/Documents/Arduino/libraries/Encoder
Using library Etherkit_Si5351 at version 2.1.3 in folder: /Users/rcaratti/Documents/Arduino/libraries/Etherkit_Si5351
Using library Wire at version 1.0 in folder: /Users/rcaratti/Library/Arduino15/packages/arduino/hardware/sam/1.6.12/libraries/Wire
Using library SSD1306Ascii at version 1.2.3 in folder: /Users/rcaratti/Documents/Arduino/libraries/SSD1306Ascii
exit status 1
Error compiling for board Arduino Due (Native USB Port).

ESP32 WEMOS Lolin32 embedded OLED 128x64

Hi,
I cannot make it work it with ESP32 WEMOS Lolin32 embedded OLED 128x64 module.
My guess is the I2C pins are different on this board.

How can we enforce it to use specific pins for I2C?

Bottom half of display "noise"

Been trying to find a lightweight ascii lib for my Banggood 128x64 I2C oled (same as most of the ebay ones) but I have a problem that the bottom half of the display is just random dots. The top half is fine though and I can see the text being displayed fine.

Not sure if it's a quirk with this display or something missing from the initialisation? Works fine on the adafruit libraries, but the memory use is ridiculous on an Arduino nano hence looking for a smaller version...

Any clues as to what's wrong?

Edit:

It was a problem with the display and needed a power down. All working now!

Great library, but no <newline> using println

Hello Bill,

I have just discovered your library and I REALLY like it :-)

It's compact, yet rich in functions for "normal" text. Thanks for sharing!

But..... I have an "issue".

When I upload your example AvrI2c128x64 (Arduino 1.6.7) to an Arduino-Nano with a "noname" SSD1306 display (which looks identical to yours) the PRINTLN statements function like they were PRINT statements. So, following the output from a PRINTLN statement the following PRINT or PRINTLN statement is NOT printed on the next line, but immediately after the 1st PRINTLN.

When I ad \n to the String to be printed the following line DOES print the next line. When I WRITE("\n"); also the next output appear on the next line.I'm not sure if this makes any sense, here's an example.

  oled.println("Hello world!");
  oled.println("A long line may be truncated");

results in

  Hello World!A long line may be tru.....

But

  oled.println("Hello world!\n");
  oled.println("A long line may be truncated\n");

results in

  Hello World!
  A long line may be tru.....

In a JPG of the testoutput on your display is seems to work as expected.

Do you have a clue why I could have this issue?

Thanks.

Inverse lines and underlining

Doing underlining and inverting is quite easy:

  1. add 2 variables to the class:
    uint8_t m_underline; // Underline flag.
    uint8_t m_inverse; // Inverse flag.

  2. add 2 set methods:
    /**

    • @brief Set the flag for underlining.
      /
      void setU(uint8_t flag) {m_underline = flag;}
      /
      *
    • @brief Set the flag for inverse display
      */
      void setI(uint8_t flag) {m_inverse = flag;}
  3. change the init method (add 2 lines):
    m_underline=0;
    m_inverse=0;

  4. change the write method:
    ssd1306WriteRamBuf((b);
    to
    ssd1306WriteRamBuf((b|m_underline)^m_inverse);
    and
    ssd1306WriteRamBuf(0);
    to
    ssd1306WriteRamBuf(m_underline^m_inverse);

Usage:
underline:

      oled.clear();
      oled.setU(128);
      oled.print("MENU");
      oled.setU(0);

inverse (a little bit more tricky, because you have to underline the previous line completely and pad both prev. line and current line with blanks (to avoid missing inverted dots):

	  if(line==invertedLine)
	  {
			oled.setU(128);
			oled.setI(127);
			oled.print(' ');
			uint8_t ml=strlen(Strings[line);
			strcpy((char*)gbuf,Strings[line]);
			if(ml<16)
			{
				for (size_t s = ml ;s < 16; s++) {
					gbuf[s]=' ';
				}
				gbuf[16]=0;
			}
			oled.print((char *)gbuf);
          }
         if(line== invertedLine-1)
	 {
		oled.setU(128);
		uint8_t ml=strlen(Strings[line]);
		strcpy((char*)gbuf,Strings[line]);
		if(ml<16)
		{
			for (size_t s = ml ;s < 16; s++) {
				gbuf[s]=' ';
			}
			gbuf[16]=0;
		}
		oled.print((char *)gbuf);
	 }
 //        normal display:			
                       oled.setU(0);
			oled.setI(0);

I think, the code should be integrated.

fontWidth() does not include padding for fixed-sized fonts

It seems like there are 2 types of fixed-width fonts, differentiated by the first 2 bytes of the font table:

  • 0x0, 0x0 - 1 pixel padding (most of them)
  • 0x0, 0x1 - 0 pixel padding (e.g. font8x8.h, cp437font8x8.h)

For fonts with 1-pixel padding, the fontWidth() returns the font width without the padding.

I need to calculate the effective font width including the padding because I want to calculate the rectangular coordinates that go into clear(uint8_t c0, uint8_t c1, uint8_t r0, uint8_t r1) which erases a specific character of a fixed width font. If the fontWidth() included the padding (including the magFactor()), then erasing the N'th character (using a 0-based offset) would be:

clear(N * fontWidth(), (N+1) * fontWidth() - 1, 0, fontRows() - 1);

(The reason I want to erase a specific character is because some fonts are incomplete, and do not include the ASCII 0x20 "space" character).

Unfortunately, I cannot arbitrarily add a 1-pixel padding, because some fonts don't have padding. The current API does not allow me to determine whether a specific font has padding. In fact, the current API does not even have a getFont() method to retrieve the current font.

Proposed Solutions

Option 1

Add a fontWidthPadded() method which includes the padding for both padded and non-padded fonts. The implementation would be something like:

uint8_t fontWidthPadded() {
  if (m_font == nullptr) return 0;
  uint16_t size = readFontByte(m_font) << 8;                                    
  size |= readFontByte(m_font+1);                                                 
  uint8_t padding = (size == 1) ? 0 : 1; 
  return m_magFactor * (padding + readFontByte(m_font + FONT_FIXED_WIDTH));
}

(Here, I'm assuming that all proportional fonts have a 1-pixel padding. I haven't researched your code in sufficient detail to be sure.)

Option 2

Add a fontPadding() method which returns the font padding size. The implementation would be something like:

uint8_t fontPadding() {
  if (m_font == nullptr) return 0;
  uint16_t size = readFontByte(m_font) << 8;                                    
  size |= readFontByte(m_font+1);                                                 
  uint8_t padding = (size == 1) ? 0 : 1; 
  return padding * m_magFactor;
}

Option 3

Add a uint8_t* getFont() (corresponding to the setFont()) so that I can at least retrieve the current font. This will allow me to extract the first 2 bytes of the current font, which allows me to manually calculate whether or not I need to add the padding.

Thanks for your library, and your consideration of this small API change.

Add timeouts to i2c ?

Great library - thanks!

Has anyone noticed that this hangs if there's no display present ?

Screen rotation

Is it possible to rotate the screen. i.e. have it 180 degrees?

Fonts

Hi!

Nice work! Fast, small, working.

My program uses a central definition of used fonts and I was playing around with fonts, optimize for readability and other things. Some fonts only have digits, some have characters, not sure all have a full set of special chars.

So I came to the following questions:
-- is there any advised way to detect by program whether a font has a char?
-- are there more fonts avaiable or a way to create fonts?

Characters are displayed 1 pixel off screen to the left

This is the first library that looks promising. But on the left, 2 columns of pixels are missing and on the right of the display there is a 2 pixel white column.

Sketch: WireI2c128x64
Oled: i2C 128 x 64 white from eBay

Brightness issue

Hi,
I did a few tests before writing this and I'm almost convinced that this issue relates only to this library.

I have a chinese made 128x64 Oled display that I run with software SPI.
In addition I have plenty of I2C sensors on board.

When I run these together 7 out of 10 times I have an issue with the brightness of the OLED screen.

I tried running other libraries and their brightness seems to be ok. I set the contrast value in setup to oled.setContrast(255); however that still doesnt effect anything.

I also had issues with the display not showing but when I connected the Ground of display to a seperate GND of Arduino that issues seems to be gone.

Is this something related to the library that someone can help with?

Use with rtc ds3231

Hi. I using ur library, very good. But i have problem when use ds3231 rtc module. I use i2c oled and ds3231 use sda and scl like oled. Oled will not work if i using ds3231 at same time. Can you help me use both? Sr my english very bad. Thank you.

i2c scrolling on 32 line displays

I'm using your WIRE example of scrolling (i2c) - and it isn't - the numbers count, lines go down then the bottom line gets replaced for the rest of the counts - ie the screen doesn't scroll up.

The only change I made to the example was to change the 64 to 32.... as I have the smaller 32 pixel high displays.....

small reorganization of files

Thanks for this great library.

Could you consider reorganizing the code such that "src", "examples" and "library.properties" appear at the top level directory, rather than in the SSD1306Ascii/SSD1306Ascii subdirectory?

That allows to install it like this

cd ~/Arduino/library
git clone https://github.com/greiman/SSD1306Ascii.git

after which it is immediately detected as library and the examples can be selected from the example menu.

best regards,
Robert

Restructure folder layout for Add .zip library in arduino

Hey there, I love this little i2c OLED library along with Arduiniana's Streaming5. One thought to improve it for future uses is to move the actual project folder one level higher (make the SSD1306Ascii subfolder the top level folder) . As it stands I can download this repo as a zip, take out the "SSD1306Ascii" subfolder, then zip that back up and then install it as a zip plugin library in Arduino. As this project has no tagged releases otherwise, I think making this change would let people drop it into the Arduino IDE more easily.

SPI - Display, begin() issue

Using two cheap Chinese SPI display with 128x64 (yellow/blue) with an Arduino Micro.
I need to initialize the first oled twice before the displays works properly,
if not - oled_A is noisy on the screen and only oled_B works like expected.
Same when using one display.
Here is the code (using PlatformIO) :

`
#include "Arduino.h"
#include "SSD1306Ascii.h"
#include "SSD1306AsciiSpi.h"

// pin definitions
#define A_RST_PIN 12
#define A_DC_PIN 11
#define A_CS_PIN 10
#define B_RST_PIN 9
#define B_DC_PIN 8
#define B_CS_PIN 7

SSD1306AsciiSpi oled_A;
SSD1306AsciiSpi oled_B;

void setup() {
Serial.begin(9600);

oled_A.begin(&Adafruit128x64, A_CS_PIN, A_DC_PIN, A_RST_PIN); // this is needed to work
oled_A.begin(&Adafruit128x64, A_CS_PIN, A_DC_PIN, A_RST_PIN);
oled_B.begin(&Adafruit128x64, B_CS_PIN, B_DC_PIN, B_RST_PIN);
oled_A.setFont(System5x7);
oled_B.setFont(Callibri15);
oled_A.clear();
oled_B.clear();
oled_A.set2X();
oled_A.print("Hello world!");
oled_B.print("Hello world!");
}

void loop() {

}
`

Please optimise the SSD1306Ascii::write(const char* s)

Please replace your existing code for the write(char*) function by this!.
The use of strlen() for no reason in your original code just drives me bananas :-)

That's my suggested change:

size_t SSD1306Ascii::write(const char* s) {
   size_t i = 0;
   while ( s[i] ) write(s[i++]);
   return i;`
}

Keep the good work!!

[not a issue] request for changes directory structure

It is possible to change directory structure of this lib?
I usually use a raw version of my favorite libraries from github repository
but it requires suitable for arduino ide directory structure,

so, target library must be inside main dir (not inside subdir)

please look at my fork Your library, with revised structure:
https://github.com/reaper7/SSD1306Ascii

Can you apply such a structure?

If yes, then I can put pull request

rest method

This is a suggestion only.

Do you consider to move reset method out of SD1306Ascii.cpp.

This is hardware/mcu dependence. Once it is moved out, the whole cpp can be used by any other platform. I have ported it to STM8 already. The only change is the reset method (and a little to SPI class).

Without moving it out, you will need to include mcu header files inside. So I moved it out. Then the rest of the codes complied fine.

I moved it via a virtual to SPI class. So only SPI file has mcu dedicated headers while SD1306Ascii.cpp is so clean and works with any platform.

SSD1306Ascii::ssd1306WriteRam

Why is the need for method "SSD1306Ascii::ssd1306WriteRam"?

There is no any reference to it. After delete it, the library is still complied without any warning.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.