Closed Trotter73 closed 1 year ago
Im having this same issue on sh1106 where it used to work perfectly.
@Trotter73 Hi Mr. Trotter - Reflashed rasbian to see if that fixed it. I'm looking around, and thinking about what my screen mighta been through and i think this is a symptom of a broken screen.
This looks to be a memory mapping issue. The GDRAM inside the device is layer out in pages that interleaved, and if the init sequence is not correct then this could result in the image @Trotter73 shows.
Looking back through the git history, the code for SSD1306 hasn’t changed in a few years. But what has changed is the performance of the raspberry pi. It could be that the init sequence is being supplied too quickly for the display to consume it, and so it doesn’t get initialized properly. We may need to add a delay at some relevant points. This is complete conjecture by the way..
Anyway, I will try and find my 128x32 oled and give it a try, but in the meantime, could you try adding --spi-bus-speed=500000
when you run the demo (this is the lowest bus speed it supports) to see if indeed it might be a timing issue?
Hi,
Thanks for taking the time to reply, appreciated !
As suggested I appended --spi-bus-speed=500000
but it gave the same result, out of curiosity I also under-clocked my Zero to Pi B speeds to see if that made a difference, but again no change, the display was not as expected.
arm_freq=700 core_freq=250 sdram_freq=400
For reference the same SD card put in a Zero with a SH1106 controller and 128x64 display works as expected.
If you are in the UK I could pop this display in the post if you think that would help ?
M.
I think I might have a 128x32 device somewhere, but if not I might take you up on that (I am in the UK) let me know what your email is (ping me at rm_hull@yahoo.co.uk) and I’ll give you the mailing address
Hi,
Just sent you an email.
Thanks for looking at it ya'll. This project has brought me a lot of joy. I'll follow-up with ya'll on sh1106 once i finish my own testing.
So, I dug out my 128x32 SSD1306 (which incidentally is I2C rather than SPI) and ran the following:
$ python3 examples/demo.py -d ssd1306 --i2c-port=1 --width=128 --height=32
and it lit up as follows:
I dont think I2C vs SPI is making any difference here, but it does suggest that your SSD1305 either:
Looking at the differences between the different screen resolutions, the multiplexing, display clock divider and COM pins settings are the only differences (see https://github.com/rm-hull/luma.oled/blob/master/luma/oled/device/__init__.py#L158-L164), it seems like if we "tweak" those values we may arrive at the correct settings for your device.
Looking at the code sample they provide (https://www.waveshare.com/w/upload/c/c5/2.23inch-OLED-HAT-Code.7z) in the SSD1305.py file the following values are used, the ones that I think are relevant i've marked as PERTINENT:
def _initialize(self):
# 128x32 pixel specific initialization.
self.command(0xAE)#--turn off oled panel
self.command(0x04)#--turn off oled panel
self.command(0x10)#--turn off oled panel
self.command(0x40)#---set low column address
self.command(0x81)#---set high column address
self.command(0x80)#--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
self.command(0xA1)#--set contrast control register
self.command(0xA6)# Set SEG Output Current Brightness
# PERTINENT
self.command(0xA8)#--Set SEG/Column Mapping 0xa0×óÓÒ·´ÖÃ 0xa1Õý³£
self.command(0x1F)#Set COM/Row Scan Direction 0xc0ÉÏÏ·´Öà 0xc8Õý³£
self.command(0xC8)#--set normal display
self.command(0xD3)#--set multiplex ratio(1 to 64)
self.command(0x00)#--1/64 duty
self.command(0xD5)#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0xF0)#-not offset
# PERTINENT
self.command(0xd8)#--set display clock divide ratio/oscillator frequency
self.command(0x05)#--set divide ratio, Set Clock as 100 Frames/Sec
self.command(0xD9)#--set pre-charge period
self.command(0xC2)#Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
# PERTINENT
self.command(0xDA)#--set com pins hardware configuration
self.command(0x12)
self.command(0xDB)#--set vcomh
self.command(0x08)#Set VCOM Deselect Level
self.command(0xAF)#-Set Page Addressing Mode (0x00/0x01/0x02)
The only one of these that I think is likely to affect your display is the COM pins setting - looking at the data sheet (https://www.waveshare.com/w/upload/b/b5/SSD1305-Revision_1.8.pdf) on pg 51 section heading "10.1.26 Set COM Pins Hardware Configuration (DAh)" this enumerates the acceptable values...
If you modified the demo.py file https://github.com/rm-hull/luma.examples/blob/master/examples/demo.py#L53-L56 to look like this:
def main():
device = get_device()
device.command(0xDA, 0x12) # <--- insert this line
print("Testing basic canvas graphics...")
If that doesn't work, try progressively addingdevice.command(0xD8, 0x05)
and device.command(0xA8, 0x1F)
.
Pictures would help to diagnose further. Else the last resort is you can loan me your device. Ultimately we would probably need to create a new class for ssd1305 with its own distinct init sequence
Hi,
You were correct 0xDA, 0x12
made huge improvements on the look of the display, we are almost there.
In addition to these 0xDB & 0x08
were needed to make the contrast section of the demo work.
The rest of the options didn't appear to make any difference, however this was only a really quick check.
However, there is still the issue of the stray pixels on the right hand side of the display, examples attached...
Me.
@Trotter73 try adding 0xD5, 0xF0
to your custom init command, eg:
def main():
device = get_device()
device.command(0xDA, 0x12, 0xD5, 0xF0) # <--- insert this line
print("Testing basic canvas graphics...")
@rm-hull No change, still the shift to the left and odd pixels on the right, as per the picture above...
Not sure if it matters but the description of these differs to the documentation for the ssd1305..
self.command(0xD3)#--set multiplex ratio(1 to 64)
self.command(0x00)#--1/64 duty
self.command(0xD5)#-set display offset Shift Mapping RAM Counter (0x00~0x3F)
self.command(0xF0)#-not offset
Maybe take all the values in the waveshareinitialize()
method and transcribe them into a list and supply them to display.command(...)
If that works, we can just create an ssd1305 class that has a common base with ssd1306 but just has a different init sequence.
Ok cool, I think I know what I'm doing there, was going to give that a go anyway. Will try to have a look at that tomorrow.
In the Waveshare main.py there are some other values, constants I think, does anything need to be done with them?
@rm-hull OK so I thought I knew what you were suggesting but I was wrong lol. If you could give a little example or pointer I'll collate the list and try....
hi @Trotter73, sorry I missed your response (for some reason some but not all github notifications keep getting snagged in my spam folder)
I meant: could you add the following:
display.command(
0xAE, 0x04, 0x10, 0x40, 0x81, 0x80, 0xA1, 0xA6,
0xA8, 0x1F, 0xC8, 0xD3, 0x00, 0xD5, 0xF0, 0xd8,
0x05, 0xD9, 0xC2, 0xDA, 0x12, 0xDB, 0x08, 0xAF)
(This is the complete init sequence from the SSD1305.py file)
Hi,
@rm-hull
No worries, funnily enough I have the same here, all git email seems to be dumped to spam...
OK, so adding the above gives the the following, basically the random pixels om the right are now two bars...
I was also looking at the constants and comparing those and found some differences
% = Present in SSD1305.py but not const.py
? = I think there is a different value
`# Constants %SSD1305_I2C_ADDRESS = 0x3C # 011110+SA0+RW - 0x3C or 0x3D %SSD1305_SETCONTRAST = 0x81 %SSD1305_DISPLAYALLON_RESUME = 0xA4 %SSD1305_DISPLAYALLON = 0xA5 %SSD1305_NORMALDISPLAY = 0xA6 %SSD1305_INVERTDISPLAY = 0xA7 %SSD1305_DISPLAYOFF = 0xAE %SSD1305_DISPLAYON = 0xAF
%SSD1305_SETMULTIPLEX = 0xA8
?SSD1305_SEGREMAP = 0xA0
%SSD1305_ACTIVATE_SCROLL = 0x2F %SSD1305_DEACTIVATE_SCROLL = 0x2E %SSD1305_SET_VERTICAL_SCROLL_AREA = 0xA3 %SSD1305_RIGHT_HORIZONTAL_SCROLL = 0x26 %SSD1305_LEFT_HORIZONTAL_SCROLL = 0x27 %SSD1305_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29 %SSD1305_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A`
So I changed /usr/local/lib/python3.7/dist-packages/luma/oled/const.py to make SETSEGMENTREMAP = 0xA0 instead of 0xA1 and the random pixels appear to have gone, however if I change it back to 0xA1 they don't reappear ?! The screen is still offset though..
Is there a method of passing constants to demo.py, similar to that of the commands ? Edit:- Adding the extra ones into the const.py file does not appear to work, although I didn't really expect it to
I'm going to be really rude and bump this, any ideas on how we can get this over the line, we seems to be all but there ...
sorry, quite right (and not rude) to bump. Could you try adding:
def main():
device = get_device()
device.command(...)
device._colstart += 1 # <--- insert these lines
device._colend += 1
print("Testing basic canvas graphics...")
and let me know if that makes any difference?
Hi,
Thanks for the understanding !
So I had to start with a fresh install, this is what I have in demo.py
def main(): device = get_device() device.command( 0xAE, 0x04, 0x10, 0x40, 0x81, 0x80, 0xA1, 0xA6, 0xA8, 0x1F, 0xC8, 0xD3, 0x00, 0xD5, 0xF0, 0xd8, 0x05, 0xD9, 0xC2, 0xDA, 0x12, 0xDB, 0x08, 0xAF) device._colstart += 1 device._colend += 1
The additional couple of lines didn't make any difference, the output is as per the last pic in this thread, still shifted to the left a bit..
Regards,
However..... Just had a play and the following values appear to fix the issue... I tried values either side but 4 was the sweet spot...
device._colstart += 4
device._colend += 4
So to wrap up adding the following to demo.py gives the correct output
device.command(
0xAE, 0x04, 0x10, 0x40, 0x81, 0x80, 0xA1, 0xA6,
0xA8, 0x1F, 0xC8, 0xD3, 0x00, 0xD5, 0xF0, 0xd8,
0x05, 0xD9, 0xC2, 0xDA, 0x12, 0xDB, 0x08, 0xAF)
device._colstart += 4
device._colend += 4
@Trotter73 ok, thanks for that - good news .. it should be enough for me to be able to create a specific SSD1305 device with this init wrapped inside it, but in the meantime until this is published, you are ok to proceed with the above as an interrim hack?
@rm-hull Thanks for all your help in getting this working, it really is appreciated, I'm more than happy with the interim solution, I've already tried it with some other code I had written for a SH1106 and it works a treat. Just shout if you want anything testing, you have my email, if you don't get a reply here ping me there.
Thanks again.
This issue is a few months old, I know, but as another Pi user and owner of the same Waveshare 2.23" 128x32 OLED, the eventual appearance of specific SSD1305 device from luma.oled would be great! I am learning a lot creating my own code for it, but using luma would be so much better. I prefer SPI, and the only properly documented library at the moment would requite getting the soldering iron out to force it into I2C mode (then there is an Adafruit CircuitPython SSD1305 library that would allow drawing on the display with PIL but it does not support SPI). All other SSD1305 code is very Arduino-specific.
I'm using the "Adafruit 2.23" Monochrome OLED Bonnet for Raspberry Pi" which is another, very similar, SSD1305 display (https://www.adafruit.com/product/4567). Looking at the datasheet differences and the command list mentioned above, I reduced the changes needed for this display to:
device = ssd1306(width=128, height=32, ...)
device.command(0xDA, 0x12) # Use alternate COM pin configuration
device._colstart += 4
device._colend += 4
@Trotter73 ok, thanks for that - good news .. it should be enough for me to be able to create a specific SSD1305 device with this init wrapped inside it, but in the meantime until this is published, you are ok to proceed with the above as an interrim hack?
Hi, not sure if this is still actively in development? Would there be a lot of work to add the SSD1305 device? Or if someone could give some pointers on how/where to start I could have a go at creating a device and generating a pull request ....
I'd suggest to duplicate class ssd1306
and modify appropriately to get class ssd1305
in __init__.py
.
I'd guess modifications should go before/into/after self.command
(lines around 260 of __init__.py
)
Maybe this is "brute force" (as it does not subclass from class ssd1306
), but probably works...
Unfortunately I don't (yet) have the SSD1305 (but want to get this 2+" OLED for my planned project) - so cannot try atm.
...in oled/device/__init__.py
- and also add "ssd1305"
to __all__
(line 48)
Thanks @Trotter73 and @rm-hull for saving me a lot of time! Very useful.
Hi,
Firstly I appreciate that I am unsupported here but thought I would raise an issue in case there is a wider problem..
I recently purchased a Waveshare 2.23” OLED HAT for a Pi Zero project I was working on, the display is 128x32 and uses the SSD1305 controller, link to the device… https://www.waveshare.com/wiki/2.23inch_OLED_HAT
Initially I used the drivers supplied by Waveshare to check the display and prove my code, no issues with them, and I got code that worked, the support though is not fantastic…
On reading about the SSD1305 controller I found that it was supposed to be code compatible with the SSD1306 and SSD1309, with some exceptions around the charge pump, so I thought I would give Luma-OLED a try..
After installing, I can run the example code and get an output on the display, however there appears to be an issue with the height or scaling, there are some random pixels to the right of the screen and it looks as if every other horizontal line is being skipped, I have attached a picture. Searching through the issues here this looks like it was previously a problem with 128x32 devices and it looks as if it was fixed at some point in 2017, I wasn’t sure if this is a particular issue with the SSD1305 or whether the issue with 128x32 devices has reappeared.
If it is a controller incompatibility issue, I would be more than happy to work with you guys on adding this one, I am no coder but could look at areas if pointed in the right direction.
The project is running on a Raspberry Pi Zero W, Buster with kernel “Linux raspberrypi 5.4.51+ #1333”
Many Thanks, M.
python3 demo.py -d ssd1306 -i spi --width 128 --height 32 Version: luma.oled 3.7.0 (luma.core 1.17.3) Display: ssd1306 Interface: spi Dimensions: 128 x 32