DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

OLED interface problems

Sun May 19, 2019 3:06 am

I'm having a problem with my oled display code.
Hardware: RPI B+ / RPI 0W
OLED: Waveshare SSD1327 128x128 SPI mode

My goal is to make a nice system monitor display for a headless server. However the included software I got working is slow to draw a screen and CPU load well 74% to update a clock... So impressive even fixing the busy wait leaves me at 26% CPU load.

I also have an Adafruit SSD1306 32x128 i2c I'm using. This one I'm using https://github.com/bitbank2/oled_96 runs perfectly very lightweight.

My monitor daemon uses on average ~2% load at peek even with writing to the i2c display.

I'm looking for a C compatible library that is light and fast preferably doesn't rely on any other libraries such as wiringpi or bcm2835. Or if there is a good resource on how to initialize these displays and communicate with them, I might be able to role my own.

Any help is appreciated,
Thanks
Last edited by DarkElvenAngel on Fri Jun 14, 2019 5:28 am, edited 1 time in total.

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED is slow and CPU intensive

Wed May 22, 2019 5:46 pm

After some searching online I can see that a full screen redraw isn't fast as each pixel requires 4 bits each.

My current thinking is the library supplied to use the display is not well written and is causing the CPU load to be much higher than it needs to be. I'm attempting to write a new C library to drive the display.

I plan to use a simple buffer with no support for grayscale. And use a simple 5x7 expanded to 6x8 font set from an LCD Datasheet.

I'm left with these questions
1. What library to use for SPI and Gpio?
2. How do I copy the font data correctly to the frame buffer?
3. Is there a better way?

I'm ruling WiringPi out as a candidate for interfacing because it doesn't like static linking and I would prefer to have no dependencies on external libraries.
P_20190519_201421_1.jpg
P_20190519_201421_1.jpg (255.94 KiB) Viewed 2319 times
Currently I've manage to produce this result with my other OLED and would like to replicate this functionality to my bigger display.

*Edit*
I did a test of just writing to display with the supplied library with wiringpi as the backend and during writing ~5-6% of the cpu is used. The small display using I2C only uses .5-1% to update the display. Even factor in the size difference of 4 Times the usage doesn't match. Is this different due to protocol or function?

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 23060
Joined: Sat Jul 30, 2011 7:41 pm

Re: OLED is slow and CPU intensive

Wed May 22, 2019 8:34 pm

Well, 128x128is only 16k at 8bpp, and the SPI can run up to 125MHz, but I'm not that familiar with SPI so not sure of the CPU overheads at those speed.

It does sound odd, so I'd suspect bad software somewhere.

https://www.raspberrypi.org/documentati ... /README.md
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed. Here's an example...
"My grief counseller just died, luckily, he was so good, I didn't care."

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED is slow and CPU intensive

Thu May 23, 2019 8:25 pm

jamesh wrote:
Wed May 22, 2019 8:34 pm
Well, 128x128is only 16k at 8bpp, and the SPI can run up to 125MHz, but I'm not that familiar with SPI so not sure of the CPU overheads at those speed.

It does sound odd, so I'd suspect bad software somewhere.

https://www.raspberrypi.org/documentati ... /README.md
That was some great info I dug into the software and it was indeed set to a very slow transfer rate of 122kHz I changed the driver to 31.2 MHz (this is the maximum of the driver)

I'm still thinking I will make my own driver as this one still has some issues

User avatar
[email protected]rogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: OLED is slow and CPU intensive

Mon May 27, 2019 1:17 pm

DarkElvenAngel wrote:
Wed May 22, 2019 5:46 pm
After some searching online I can see that a full screen redraw isn't fast as each pixel requires 4 bits each.

My current thinking is the library supplied to use the display is not well written and is causing the CPU load to be much higher than it needs to be. I'm attempting to write a new C library to drive the display.

I plan to use a simple buffer with no support for grayscale. And use a simple 5x7 expanded to 6x8 font set from an LCD Datasheet.

I'm left with these questions
1. What library to use for SPI and Gpio?
2. How do I copy the font data correctly to the frame buffer?
3. Is there a better way?

I'm ruling WiringPi out as a candidate for interfacing because it doesn't like static linking and I would prefer to have no dependencies on external libraries.

P_20190519_201421_1.jpgCurrently I've manage to produce this result with my other OLED and would like to replicate this functionality to my bigger display.

*Edit*
I did a test of just writing to display with the supplied library with wiringpi as the backend and during writing ~5-6% of the cpu is used. The small display using I2C only uses .5-1% to update the display. Even factor in the size difference of 4 Times the usage doesn't match. Is this different due to protocol or function?
If you read the wiringPi sources, you'll find that the wiringPiSPI code is just some dumbed-down 2 or 3-line wrappers round the bog-standard Linux kernel SPI driver, so actually using wiringPi as a template to write your own 2 or 3-line function to do what you need to do ought to be a 5-minute task...

You will also find some example programs that drive a parallel interface display that maintains a software frame buffer and generic graphics primitives and font for it ... (lcd128x64.c, etc)


-Gordon
--
Gordons projects: https://projects.drogon.net/

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED is slow and CPU intensive

Mon May 27, 2019 2:49 pm

[email protected] wrote: If you read the wiringPi sources, you'll find that the wiringPiSPI code is just some dumbed-down 2 or 3-line wrappers round the bog-standard Linux kernel SPI driver, so actually using wiringPi as a template to write your own 2 or 3-line function to do what you need to do ought to be a 5-minute task...

You will also find some example programs that drive a parallel interface display that maintains a software frame buffer and generic graphics primitives and font for it ... (lcd128x64.c, etc)


-Gordon
Thanks Gordon,

I have not looked at your SPI source code yet as I tried the BCM 2835 library first. The OEM drives supports both. I was able to get the BCM2835 driver to speed up where as the wiringpi driver wasn't changing speeds for some reason.

The OLED also requires GPIO control of it's Data/Command and Reset lines, I have seen ways to control these from the linux kernel and haven't tested any of it yet.

I have just finished my first font and framebuffer tests and can send one line of text to the OLED. As my current framebuffer is only 512bytes or 21 characters at 6x8 font-size.

I'm going to take a look at these other examples you mention Gordon as I'm not certain my font to framebuffer routines are efficient.

Right now I might stick with the BCM2835 library as I can compile my source on one machine and run it on the others with out the library installed. However does wiringpi and by extension the linux drivers require root permissions to run as this is a slight stumbling block.

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED is slow and CPU intensive

Tue Jun 11, 2019 12:27 am

I'm looking to change when the BCM2835 Library accesses the /dev/mem or /dev/gpiomem. I don't want my program running as root

The question is this currently /dev/mem has read only permission by group kmem is there harm in changing this the read write? Further what is the best way to force the library to use this device.

I haven't dug too much into the code but I believe that it uses a check against the effective user to make this choice, if so I would simply add an override.

The other thing to find is the udev rule that sets this permission and add writing from boot.

Or is there a way to use SPI with the spi group and not have to re configure each target system ideally I want to use a static library?

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

OLED interface problems

Fri Jun 14, 2019 5:26 am

@[email protected]

The SPI code you use, does it require root access to work?

My driver works and writes to the OLED as intended with one issue it will only work if I run the demo program first, this problem popped up after reboot. Is there a way to spy on the bus and log what is sent including two gpio pins?

I don't have fancy test equipment like a logic analyzer. I thought I saw a program for the RPI that could do this.

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 4991
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: OLED interface problems

Sat Jun 15, 2019 5:41 pm

DarkElvenAngel wrote:
Fri Jun 14, 2019 5:26 am
...
Is there a way to spy on the bus and log what is sent including two gpio pins?
I don't have fancy test equipment like a logic analyzer. I thought I saw a program for the RPI that could do this.
Were you thinking of piscope** perhaps? (I no longer have access to oscilloscopes etc. and have found it very useful)
Trev.
** http://abyz.me.uk/rpi/pigpio/piscope.html
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED interface problems

Sun Jun 16, 2019 5:48 am

FTrevorGowen wrote:
Sat Jun 15, 2019 5:41 pm
DarkElvenAngel wrote:
Fri Jun 14, 2019 5:26 am
...
Is there a way to spy on the bus and log what is sent including two gpio pins?
I don't have fancy test equipment like a logic analyzer. I thought I saw a program for the RPI that could do this.
Were you thinking of piscope** perhaps? (I no longer have access to oscilloscopes etc. and have found it very useful)
Trev.
** http://abyz.me.uk/rpi/pigpio/piscope.html
That's the one thanks! Took a bit to get it working. I'm however not getting good data my SPI CE0 line is not holding for 8 bits, and the rest looks like a mess. I don't see the command/data line switch. I'm running known good sample code so I should see the reset flip and command mode setup the display.

I've installed piscope version 0.4 on my 3b+ and the daemon version 68 running on a B+ with the OLED.

My code is still using the bcm2835 library could that be the issue? Or is the SPI speed to high maybe?

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 4991
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: OLED interface problems

Sun Jun 16, 2019 11:20 am

DarkElvenAngel wrote:
Sun Jun 16, 2019 5:48 am
FTrevorGowen wrote:
Sat Jun 15, 2019 5:41 pm
DarkElvenAngel wrote:
Fri Jun 14, 2019 5:26 am
...
Is there a way to spy on the bus and log what is sent including two gpio pins?
I don't have fancy test equipment like a logic analyzer. I thought I saw a program for the RPI that could do this.
Were you thinking of piscope** perhaps? (I no longer have access to oscilloscopes etc. and have found it very useful)
Trev.
** http://abyz.me.uk/rpi/pigpio/piscope.html
That's the one thanks! Took a bit to get it working. I'm however not getting good data my SPI CE0 line is not holding for 8 bits, and the rest looks like a mess. I don't see the command/data line switch. I'm running known good sample code so I should see the reset flip and command mode setup the display.

I've installed piscope version 0.4 on my 3b+ and the daemon version 68 running on a B+ with the OLED.

My code is still using the bcm2835 library could that be the issue? Or is the SPI speed to high maybe?
What sample rate (time) did you set piscope to use? Remember you need to be sampling at least twice as fast as the bus clock (ie. > Nyquist limit)
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED interface problems

Sun Jun 16, 2019 3:45 pm

FTrevorGowen wrote:
Sun Jun 16, 2019 11:20 am
What sample rate (time) did you set piscope to use? Remember you need to be sampling at least twice as fast as the bus clock (ie. > Nyquist limit)
Trev.
Yeah I was running the daemon on the default settings.
Now using:

Code: Select all

sudo pigpiod -s 1 -b 200 -f
Okay I did a combination of using a slow SPI clock and running the daemon at its maximum speed now I am seeing something more useable. 8 clock pulses with the CE0 line low. Is there something that can parse this data and read say what data is sent on the bus? I saved my samples to text format and look at them looks like the format is simply sample time GPIO State

I was trying out the triggers but not sure what they do as I wanted to just read the data blocks.
Triggers are as follows:

Code: Select all

Sample from CE0 Falling
Sample to CE0 Rising
With 50,000 samples
I'm going to rewrite my code to have a was to set speed but I also thought it would be useful to have a gpio pin used outside the communication to act as a trigger for capturing the initialization or some other function as it runs.

I also pulled the latest piscope 0.6 from GitHub so everything is the latest version AFAIK

Thanks for the help.

DarkElvenAngel
Posts: 141
Joined: Tue Mar 20, 2018 9:53 pm

Re: OLED interface problems

Sun Jun 16, 2019 5:46 pm

So I gave WiringPi driver another shot since it works without root access however the speed is not there, the driver is coded to run at 9000000 or 9MHz however changes to that number have no effect on performance and the screen update is slow. I was going to use the standard SPI interface as Gordon suggested, however with this low transfer rate the CPU load is higher than it needs to be and transfers are too long.

Any thoughts as to why this is happening?

Return to “C/C++”