Are there any small libraries for this screen other than the u8g2 libraries?
Preferably as small as possible.
Are there any small libraries for this screen other than the u8g2 libraries?
Preferably as small as possible.
Okay. I've decided to come back to this and I'm trying to write a small library based on a SSD1306 basic library.
I've been studying the datasheets of both and looking around for information on the SSD1327 and I have a library that at least displays something, it's garbage but it's a start.
I'm thinking the issues are with setting the page address and the columns which of course then messes up everything else.
Would anyone like to give me a hand so that it will be possible to have a 128x128 OLED display working on Maybe a Uno or Mega?
I've had to edit out the font due to post size. I'll add it in another reply.
#define OLED_address 0x3C //0x3C or 0x3D
// Used to send commands to the display.
static void sendcommand(unsigned char com)
{
Wire.beginTransmission(OLED_address); //begin transmitting
Wire.write(0x80); //command mode
Wire.write(com);
Wire.endTransmission(); // stop transmitting
}
// Actually this sends a byte, not a char to draw in the display.
// Display's chars uses 8 byte font the small ones and 96 bytes
// for the big number font.
static void SendByte(unsigned char data)
{
Wire.beginTransmission(OLED_address); // begin transmitting
Wire.write(0x40);//data mode
Wire.write(data);
Wire.endTransmission(); // stop transmitting
}
// Prints a display char (not just a byte)
// being multiples of 8. This means we have 16 COLS (0-15)
// and 8 ROWS (0-7).
static void sendChar(unsigned char data)
{
Wire.beginTransmission(OLED_address); // begin transmitting
Wire.write(0x40);//data mode
for(int i=0;i<8;i++)
Wire.write(pgm_read_byte(myFont[data-0x20]+i));
Wire.endTransmission(); // stop transmitting
}
// Set the cursor position in a 16 COL * 2 ROW map.
static void setXY(unsigned char col,unsigned char row)
{
sendcommand(0xa0+row); //set page address
sendcommand(0x00+(8*col&0x15)); //set low col address
sendcommand(0x10+((8*col>>4)&0x15)); //set high col address
}
// Prints a string regardless the cursor position.
static void sendStr(unsigned char *string)
{
unsigned char i=0;
while(*string)
{
for(i=0;i<8;i++)
{
SendByte(pgm_read_byte(myFont[*string-0x20]+i));
}
*string++;
}
}
// Prints a string in coordinates X Y, being multiples of 8.
// This means we have 16 COLS (0-15) and 8 ROWS (0-7).
static void sendStrXY( char *string, int X, int Y)
{
setXY(X,Y);
unsigned char i=0;
while(*string)
{
for(i=0;i<8;i++)
{
SendByte(pgm_read_byte(myFont[*string-0x20]+i));
}
*string++;
}
}
// Resets display depending on the actual mode.
static void reset_display(void)
{
displayOff();
clear_display();
displayOn();
}
// Turns display on.
void displayOn(void)
{
sendcommand(0xaf); //display on
}
// Turns display off.
void displayOff(void)
{
sendcommand(0xae); //display off
}
// Clears the display by sendind 0 to all the screen map.
static void clear_display(void)
{
unsigned char i,k;
for(k=0;k<4;k++) //4
{
setXY(0,k);
{
for(i=0;i<128;i++) //was 128
{
sendChar(0); //clear all COL
//delay(10);
}
}
}
}
// Inits oled
static void init_OLED(void)
{
sendcommand(0xae);//--turn off oled panel
sendcommand(0x15); //set column addresses
sendcommand(0x00); //start column 0
sendcommand(0x7f); //end column 127
sendcommand(0x75); //set row addresses
sendcommand(0x00); //start row 0
sendcommand(0x7f); //end row 127
sendcommand(0x81); //set contrast control
sendcommand(0x80); //50% (128/255)
sendcommand(0xa0); //remap configuration
sendcommand(0x51); //51 (To my understanding, this is orientation
sendcommand(0xa1); //start line
sendcommand(0x00);
sendcommand(0xa2); //display offset
sendcommand(0x10);
sendcommand(0xa4); //normal display
//sendcommand(0xa5); //all pixels on
sendcommand(0xa8); //set multiplex ratio
sendcommand(0x7f);
sendcommand(0xb1); //set phase leghth
sendcommand(0x51);
sendcommand(0xb3); //set dclk
sendcommand(0x01); //80Hz:0xc1 90Hz:0xe1 100Hz:0x00 110Hz:0x30 120Hz:0x50 130Hz:0x70 01
sendcommand(0xab); //Enable vReg
sendcommand(0x01);
sendcommand(0xb6); //set phase leghth
sendcommand(0x01);
sendcommand(0xbe); //Set vcomh voltage
sendcommand(0x07);
sendcommand(0xbc); //set pre-charge voltage
sendcommand(0x08);
sendcommand(0xd5); //second precharge period
sendcommand(0x62);
sendcommand(0xfd); //Unlock commands
sendcommand(0x12);
sendcommand(0xaf);
clear_display();
}
This is the font code
// Small 8x8 font
const unsigned char myFont[][8] PROGMEM = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00, 0x00}, {0x00, 0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00, 0x00}, {0x00, 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x00},
{0x00, 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00}, {0x00, 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x41, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x08, 0x2A, 0x1C, 0x2A, 0x08, 0x00, 0x00}, {0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, 0x00, 0x00},
{0x00, 0xA0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00}, {0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00}, {0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x00}, {0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x62, 0x51, 0x49, 0x49, 0x46, 0x00, 0x00}, {0x00, 0x22, 0x41, 0x49, 0x49, 0x36, 0x00, 0x00}, {0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00, 0x00},
{0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00}, {0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, 0x00, 0x00}, {0x00, 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, 0x00},
{0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00}, {0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, 0x00, 0x00}, {0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xAC, 0x6C, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00}, {0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00},
{0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00}, {0x00, 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x00}, {0x00, 0x32, 0x49, 0x79, 0x41, 0x3E, 0x00, 0x00},
{0x00, 0x7E, 0x09, 0x09, 0x09, 0x7E, 0x00, 0x00}, {0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00}, {0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00},
{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, 0x00, 0x00}, {0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00}, {0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00},
{0x00, 0x3E, 0x41, 0x41, 0x51, 0x72, 0x00, 0x00}, {0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00}, {0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, 0x00, 0x00}, {0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00}, {0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, 0x00}, {0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x00}, {0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x00},
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00}, {0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00, 0x00}, {0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x00},
{0x00, 0x26, 0x49, 0x49, 0x49, 0x32, 0x00, 0x00}, {0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, 0x00}, {0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x00},
{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x00}, {0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00, 0x00}, {0x00, 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x00},
{0x00, 0x03, 0x04, 0x78, 0x04, 0x03, 0x00, 0x00}, {0x00, 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x00}, {0x00, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00}, {0x00, 0x41, 0x41, 0x7F, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00},
{0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00}, {0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x00},
{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, 0x00, 0x00}, {0x00, 0x38, 0x44, 0x44, 0x28, 0x00, 0x00, 0x00}, {0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, 0x00, 0x00},
{0x00, 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00}, {0x00, 0x08, 0x7E, 0x09, 0x02, 0x00, 0x00, 0x00}, {0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, 0x00, 0x00},
{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00}, {0x00, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x80, 0x84, 0x7D, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00}, {0x00, 0x41, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, 0x00, 0x00},
{0x00, 0x7C, 0x08, 0x04, 0x7C, 0x00, 0x00, 0x00}, {0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00}, {0x00, 0xFC, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x24, 0x24, 0xFC, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7C, 0x08, 0x04, 0x00, 0x00, 0x00}, {0x00, 0x48, 0x54, 0x54, 0x24, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7F, 0x44, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x3C, 0x40, 0x40, 0x7C, 0x00, 0x00, 0x00}, {0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00, 0x00},
{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00, 0x00}, {0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00}, {0x00, 0x1C, 0xA0, 0xA0, 0x7C, 0x00, 0x00, 0x00},
{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00}, {0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x02, 0x01, 0x01, 0x02, 0x01, 0x00, 0x00}, {0x00, 0x02, 0x05, 0x05, 0x02, 0x00, 0x00, 0x00}
};
The SSD1327 is 128x128 with 16 shades of grey.
This means that you would need 128x128x4 bits of SRAM for a buffer. i.e. 8kB of SRAM.
This is more SRAM than most Arduinos can afford to waste.
Yes, you can ignore the grayscale and treat it as a monochrome display e.g. SSD1306 style.
Follow the Adafruit_SSD1306 style and you can use a 128x128x1 buffer i.e. 2kB
U8g2lib treats it as a monochrome display. However U8g2lib has a sophisticated buffer scheme that can work with a "small" SRAM buffer.
Unfortunately the SSD1327 can only read its internal GRAM if you use the 8-bit parallel interface.
Neither SPI nor I2C interface permit GRAM read.
If you could read GRAM it is possible to draw bit-addressable graphics. i.e. no need for any buffer at all.
The SSD1327 has internal GRAM memory organised as 128x128x4 bits
You can only address it as 64x128x8. i.e. two pixels in one byte.
It seems crazy to me. It would cost Solomon Systech nothing to provide individual pixel addressing.
No need to alter the interface hardware. Just provide a 128 pixel wide X register.
Hey-ho. It would be so nice if there already was such a secret register.
What target do you want to use?
David.
I just want it as a simple monochrome display with 16 columns and maybe 4 rows.
It's mostly to be used for just displaying text with the odd special character if I can bring myself to designing them.
If you don't care about pixel-addressable graphics, you just write the text without worrying about anything else.
I have an SSD1327 and it displays grayscale photos quite nicely.
It seems wasteful to just use mono on a grayscale display.
If you don't care, you will find that a full colour ST7735 or ILI9163 will be much easier for displaying any text or graphics.
Much cheaper too. And the TFT uses less current than the OLED when active.
If you can switch the TFT backlight on or off, the TFT will give you better average current consumption.
David.
Sadly they are both SPI and although I've got the option of a PCD8544 in the project I want to fit this library into, I2C is more reliable and uses less pins as I am using SPI already for SD card access.
At the moment using the 1306 on a Nano with my project I use up most of the Nanos memory
Sketch uses 28416 bytes (92%) of program storage space. Maximum is 30720 bytes.
Global variables use 1530 bytes (74%) of dynamic memory, leaving 518 bytes for local variables. Maximum is 2048 bytes.
I give up. You started this topic. The title says I2C.
If you replace the Nano bootloader you would have more Flash.
Quite honestly, U8g2lib only uses minimal memory. Choose your fonts carefullly.
David.
david_prentice:
I give up. You started this topic. The title says I2C.
And the two screens you suggested, ST7735 or ILI9163, are SPI.
If you replace the Nano bootloader you would have more Flash.
Quite honestly, U8g2lib only uses minimal memory. Choose your fonts carefullly.
David.
Even if I replaced the bootloader U8g2lib uses too much memory even with the smallest of fonts which is why I'm trying to write a small SSD1327 similar to the SSD1306 library.
Yes, ST7735 etc are SPI. It can share the hardware SPI bus with other devices. But you still need a separate DC and CS pin. (I prefer RESET to be controllable too)
Which U8g2lib fonts are you using?
What do you actually print?
Number fonts are very small
UPPERCASE fonts are fairly small
Regular 95 char ascii is same as as any other ascii font
Yes, Extended and Unicode fonts can be enormous.
David.
Again. u8g2 is too big for what I'm trying to do and what I'm trying to fit it into. Even with the smallest fonts.
It has to be a very small library to fit into a large over all project.
All I'm printing on screen is filenames and "playing", "stopped" etc and other messages but I want a nice clear large display and be able to fit all the programming into a Nano.
The SSD1327 1.5" is an ideal size and is I2C which is preferable as having two SPI devices connected has caused issues.
Buleste:
Are there any small libraries for this screen other than the u8g2 libraries?Preferably as small as possible.
I just ordered one from China last week. When it arrives, I'll create a compact library for drawing text and graphics. I just updated my SSD1306 library to fit better on AVR by shrinking the font data to 1344 bytes (3 sizes - 6x8, 8x8, 16x16) and the code is just a little bigger than that. I can see doing something similar with the SSD1327 and allowing you to specify the foreground and background text "color" as well as drawing pixels/lines as if the display is 64x128. I will drive it from the ATtiny85 as well to show off it's compactness ![]()
bitbank:
I just ordered one from China last week. When it arrives, I'll create a compact library for drawing text and graphics. I just updated my SSD1306 library to fit better on AVR by shrinking the font data to 1344 bytes (3 sizes - 6x8, 8x8, 16x16) and the code is just a little bigger than that. I can see doing something similar with the SSD1327 and allowing you to specify the foreground and background text "color" as well as drawing pixels/lines as if the display is 64x128. I will drive it from the ATtiny85 as well to show off it's compactness
That sounds great. I'll have to have a look at your libraries.
It has to be a very small library to fit into a large over all project.
Did you test the U8x8 interface, which comes with u8g2?
It should require much lesser RAM and FlashROM
Oliver
olikraus:
Did you test the U8x8 interface, which comes with u8g2?
It should require much lesser RAM and FlashROMOliver
Doesn't have I2C support for the 128x128
//U8X8_SSD1327_SEEED_96X96_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
//U8X8_SSD1327_SEEED_96X96_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // Seeedstudio Grove OLED 96x96
//U8X8_SSD1327_EA_W128128_4W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8X8_SSD1327_EA_W128128_4W_HW_SPI u8x8(/* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8X8_SSD1327_MIDAS_128X128_4W_SW_SPI u8x8(/* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
//U8X8_SSD1327_MIDAS_128X128_4W_HW_SPI u8x8(/* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);
Buleste:
Doesn't have I2C support for the 128x128
Not all combinations of display and interface are listed in the examples!
// Please UNCOMMENT one of the contructor lines below
// U8x8 Contructor List
// The complete list is available here: https://github.com/olikraus/u8g2/wiki/u8x8setupcpp
On this page you will find:
U8X8_SSD1327_EA_W128128_HW_I2C([reset [, clock, data]])
U8X8_SSD1327_MIDAS_128X128_HW_I2C([reset [, clock, data]])
and more....
Oliver
Ah. Okay. I didn't realise that.
Thank you.
I'll have to give it a try.
Okay.
Tried
U8X8_SSD1327_EA_W128128_HW_I2C([reset [, clock, data]])
With a few examples on a Pro Mega and had the following error message
Arduino: 1.8.9 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
16x16Font:197:32: error: expected unqualified-id before '[' token
U8X8_SSD1327_EA_W128128_HW_I2C([reset [, clock, data]])
^
16x16Font:197:32: error: expected ')' before '[' token
C:\Users\Duncan Edwards\AppData\Local\Temp\arduino_modified_sketch_102905\16x16Font.ino: In function 'void setup()':
16x16Font:214:3: error: 'u8x8' was not declared in this scope
u8x8.begin();
^
C:\Users\Duncan Edwards\AppData\Local\Temp\arduino_modified_sketch_102905\16x16Font.ino: In function 'void loop()':
16x16Font:220:3: error: 'u8x8' was not declared in this scope
u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);
^
exit status 1
expected unqualified-id before '[' token
[ and ] just denote the optional arguments. Just use
U8X8_SSD1327_EA_W128128_HW_I2C u8x8();
Oliver
Buleste:
Are there any small libraries for this screen other than the u8g2 libraries?Preferably as small as possible.
I just received this display today and have some basic functionality working. I'll share the library to github this week when it's in better shape. The final code+data size (with 3 font sizes) will be less than 3K and for AVR (RAM challenged) Arduinos, it won't require any back buffer.