Closed Philip-Mohr closed 6 years ago
"ssd1306_drawRect(1,1,126,62);" does this:
other librarys use the bottom 8 pixels without a problem.
@Philip-Mohr, thank you for posting this issue.
UNO is based on Atmega328p, the same as mine Nano. And I do not observe any issues with draw_bitmap example:
The picture I posted shows image, and then text, which is displayed on the top of image. The top 8 pixels and bottom 8 pixels are good.
As you can see my display looks slightly different than yours. If you use Wire library in your program, could you please reduce the speed to standard 100kHz instead of 400kHz and see what happens.
For now, it looks for me like i2c communication issue, I didn't find any problem in logic of ssd1306_drawBitmap().
Do you have any datasheet for you display?
It's this board: http://s.aliexpress.com/u6zmE3m6 With u8g2 it works good, but I want an attiny compatible library. Not at home at the moment, tomorrow I will test 100khz
Hi @Philip-Mohr ,
I noticed one thing in your screenshots. The resulting image (owl) is shifted by 8 pixels up. That's why you don't have 8 top rows, and there is empty 8 bottom rows in your case. I checked 0.96" ssd1306 and 1.3" ssd1306 oleds, I have. And they both work ok for me.
Could you please, share your sketch source code? Which configuration of u8g2 library did you use for your lcd? I check the top most initialization sequence for ssd1306 128x64, and my library does the same initialization steps for the display. Could it be possible, that your display is not ssd1306? For example, sh1106 has almost the same commands.
Could you please edit file src/lcd/ssd1306_128x64.c and insert the line
0xB0,
right before SSD1306_MEMORYMODE, HORIZONTAL_ADDRESSING_MODE,
line, and let me know if it helps.
Hey dude,
with u8g2 i need to use U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
When i use the SH1106 code from u8g2 it works, but a bit buggy, so it seems to be a SSD1306. Adafruit lib and u8g2 both work without a problem.
I tried 0xB0
, but it doesn´t help. (What does 0xB0
?).
Also i tried to reduce the i2c speed, but i´m not sure if i´ve done it right.
After Wire.begin();
i added Wire.setClock();
and tried 400khz, 100khz, 31khz and some other random numbers.
And i don´t know if sharing the code is necessary. It´s just your draw_bitmap code.
ESP8266 has the same bug btw with my panel and your lib.
I removed my arduino 1.8.3 ide and all libs etc, so i could do a clean install of the arduino 1.8.5 with only your lib. Same problem. I would think that the board is defective, but the other 2 libs work without a problem. I have an old project laying around with an oled display and arduino pro mini. When i find it, i will try it there.
Tried the oled with the digispark and digisparkOLED library. also there no problems. I don´t get why your lib works on your oled without a problem and on mine not. But i wanna use your lib, because it´s the best in my opinion.
Thank you for the response. I'm still looking at the issue, trying to figure out what happened. I will check against digisparkOLED library.
Hi @Philip-Mohr
Please, try display configuration I listed below instead of the one in src/lcd/ssd1306_128x64.c file and let me know if it works.
static const uint8_t PROGMEM s_oled128x64_initData[] =
{
SSD1306_DISPLAYOFF, // display off
SSD1306_MEMORYMODE, HORIZONTAL_ADDRESSING_MODE, // Page Addressing mode
0xB0,
SSD1306_COMSCANDIR,
SSD1306_SETLOWCOLUMN,
SSD1306_SETHIGHCOLUMN,
SSD1306_SETSTARTLINE,
/* normal page addressing mode */
SSD1306_SETCONTRAST, 0x3F, // contast value
SSD1306_SEGREMAP | 0x01,
SSD1306_NORMALDISPLAY,
SSD1306_SETMULTIPLEX, 63,
SSD1306_DISPLAYALLON_RESUME,
SSD1306_SETDISPLAYOFFSET, 0x00, // --no offset
SSD1306_SETDISPLAYCLOCKDIV, 0xF0,
SSD1306_SETPRECHARGE, 0x22, // --switch vcc
SSD1306_SETCOMPINS, 0x12, // --set divide ratio
SSD1306_SETVCOMDETECT, 0x20, // --vcom detect
SSD1306_CHARGEPUMP, 0x14,
SSD1306_DISPLAYON
};
Tried it, same problem :/
Ok, lets try the simple things:
What does ssd1306_putPixels(0,0,0x99);
show on the display? No any other draw commands, just this one. You should see 4 pixels at (0,0), (0,3), (0,4) and (0,7)
Try this version of drawBitmap:
void ssd1306_drawBitmap(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const uint8_t *buf)
{
uint8_t i, j;
ssd1306_setRamBlock(x, y, w);
ssd1306_dataStart();
for(j=0; j<(h >> 3); j++)
{
// if ( g_lcd_type == LCD_TYPE_PCD8544 )
{
ssd1306_endTransmission();
ssd1306_setPos(x, y+j);
ssd1306_dataStart();
}
for(i=w;i>0;i--)
{
ssd1306_sendByte(s_invertByte^pgm_read_byte(buf++));
}
}
ssd1306_endTransmission();
}
Dude! It worked! 😄 i removed all if ( g_lcd_type == LCD_TYPE_PCD8544 )
(not the else if
's) and now it seems to work. Thank you very much!!!!
btw when I compile for digispark, i´m getting this error:
`C:\Program Files (x86)\Arduino\libraries\ssd1306\src\ssd1306.cpp: In function 'SPRITE ssd1306_createSprite(uint8_t, uint8_t, uint8_t, const uint8_t*)':
C:\Program Files (x86)\Arduino\libraries\ssd1306\src\ssd1306.cpp:419:28: error: 'nullptr' was not declared in this scope
return {x,y,w,x,y,data,nullptr};`
Hi @Philip-Mohr ,
I'm glad to hear that the changes helped you. However, I'm still trying to figure out, why ssd1306_setRamBlock() didn't work well for you. Actually it sends 4 ssd1306 commands: Column address, Set page, Set high column and Set low column. The commenting out g_lcd_type == LCD_TYPE_PCD8544
causes library to send those command in two different i2c sessions. During the first session only one command is sent: Column address. Other three commands are sent in second session.
As for the issue with digispark, which compiler and IDE do you use? nullptr
appeared in C++11 first. For now you can try to simply replace nullptr
with 0
.
@Philip-Mohr, could you please download latest sources from https://github.com/lexus2k/ssd1306 and check if the changes fix both issues:
I found the root cause with compilation for digispark board. Actually, the library ssd1306 requires c++11/c99. This is defined by compiler flags. By default for all supported Arduino boards they are set to -std=gnu++11
and -std=gnu11
. However, digispark settings are different. You can fix that by making changes to platform.txt file installed with digispark board:
I found mine in this location:
"C:\Users\User\AppData\Local\Application Data\Arduino15\packages\digistump\hardware\avr\1.6.7\"
Edit platform.txt for your Digispark board and add required standards to compilation flags. Here is example how I modified the flags for Digispark board:
compiler.c.flags=-c -g -Os -w -std=gnu11 -ffunction-sections -fdata-sections -MMD compiler.cpp.flags=-c -g -Os -w -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -MMD
Now I can compile the code for Digispark with the latest ssd1306 sources.
Hey Dude!
In the new version i still need to delete if ( g_lcd_type == LCD_TYPE_PCD8544 )
, otherwise the same problem as before occures.
Also bad news for digispark. After the change in the platform.txt it compiled. But i´m getting no i2c commands. I´m using p0 and p2. I hookep up my logic analyzer and saw nothing. For looking that i made no mistake with the wiring I uploaded the digispark I2Cscanner example and in the logic analyzer software I saw how it scanned the ports with p0/p2.
Do you have a digispark or have you just compiled it without testing?
Can i donate a few bucks for maybe a digispark and a beer? 😃 💻 🍺
Hi @Philip-Mohr , Regarding your lcd ssd1306 issue. I'm reading datasheet ssd1306 and still have no clear answer, why my implementation of sending control commands doesn't work in your case. According to the datasheet, it should work. But since you gave me a clue, I need to do more analysis.
Regarding Digispark, how many i2c devices are you going to use in your project? By default, since Digispark is based on Attiny85, the library switches internal software i2c implementation, which allows only direct connection with single i2c device: ssd1306 display, - and usage of any pins. By default i2c pins used by the library for Attiny controllers are pin 3 and pin 4. This is pointed in the examples and you can find that in the documentation (ssd1306_i2c_conf.h). That is the reason, why you do not see anything on p0/p2 pins. You wrote that you're trying to use pins p0, p2, which, I believe, are PB0 and PB2. Try to update ssd1306_i2c_conf.h with the pin numbers, you use for the project. I checked Digispark I2Cscanner, and found that they implemented specific Wire library for Attiny controllers (in original Arduino Wire is not available for those). So, there are 2 ways for you available right now:
I don't have Digispark module to check, I have only single Attiny85 chip and ISP programmer.
With new version of ssd1306 library, there will be ability to configure pins from the project source (if interesting, you can check 1.3.0_i2c_spi branch in development). Also, with new version it will be possible to choose to use either software or hardware i2c implementation in the project.
Thank you for your wishes. I'm pleased. I can order ssd1306 module, you have, and digispark board, but it will take from 2 weeks to 1.5 months to get them. Maybe, we will be able to solve the issue a little bit faster.
I tried the preferred method and it worked 😄 thank you!
But the 8 bottom pixel problems still happens. When removing the 3 if ( g_lcd_type == LCD_TYPE_PCD8544 )
lines the problem goes away. But just for the draw_bitmap
sketch. With buffers_demo
and draw_text
i still have the same problem.
Actually I'm thinking now that you have not ssd1306 lcd, but sh1106 instead (or some lcd not fully compliant with ssd1306 spec). They have similar datasheets and very often manufactures describe sh1106 as ssd1306, but sh1106 doesn't support Horizontal/Vertical addressing modes, and supports only Page Addressing mode. That explains, why my library doesn't work for you correctly (as you noticed the problem with the text printing). The main mode of my library is horizontal addressing mode, while u8g2 uses page addressing mode. That's why it works. But don't worry, I will add SH1106 support (at least I have the datasheet for it). I just only need your help in testing.
Please, check commit https://github.com/lexus2k/ssd1306/commit/8c12ac93c65da84fd1461526d3c9a55629661019
and initialize your display with sh1106_128x64_i2c_init()
Hi @Philip-Mohr , Do the changes help you to solve the issue? You can try also 1.3.0_i2c_spi branch. It also has support for SH1106 oled display.
Sry for answering so late (had much stuff to do (learn stm32... i hate these fu**ers )).
I downloaded the 1.3.0_i2c_spi branch and uploaded it with sh1106_128x64_i2c_init()
. Works nice now. But now it also works with ssd1306_128x64_i2c_init()
. Have i done something wrong? ^^
Btw, thank you really much for your help 😃
I'm surprised. Looking at the manufactures, I found that there are several ssd1306 controller versions (at least, I saw ssd1306, ssd1306b). If both variants work for you, use ssd1306_128x64_i2c_init() since it is faster. The new library 1.3.0 is greatly reworked, and it is not still published. I'm going to do that soon.
Cool Cool! Thank you 👍
library version
1.2.5
LCD display type
SSD1306
Steps to reproduce the issue
flash "draw_bitmap" (tried on Arduino Uno and Attiny45)
Expected behavior
Draw the owl
Actual behavior
Draws the owl but the top 8 pixels are cut on the top and the bottom 8 pixels are not refreshed.
I uploaded "draw_text" (with "_ssd1306_charF6x8(0, 7, "Line 7. Italic text", STYLEITALIC);") before and then uploaded "draw_bitmap" to show, that the 8 pixels on the bottom don´t refresh.