Teensy 3.0 and u8glib

Status
Not open for further replies.
At the moment, I have hardware on my desk for 10 different graphical LCD libraries!

Code:
Library             Access method
-------             -------------
Adafruit_ST7735     native SPI
Adafruit_ILI9340    avr SPI
Adafruit_SSD1306    bitbash SPI
Adafruit_RA8875     avr SPI
UTFT                native parallel
arLCD               serial
u8glib              TBD (currently broken)
FTOLED              avr SPI
OpenGLCD            native parallel
Gameduino2          avr SPI

Eventually I want to port more of the SPI ones to the extremely native SPI....

I'm going to work with u8glib over the next few days. Hopefully that'll provide some relief.
 
Yes thats the one I am using as well.

Heres the link to adafruits driver. https://github.com/adafruit/Adafruit-SSD1351-library

The test seems ok, but its drawing different pics. You don't really think about flicker until you are trying to do something like make a clock, or update a temp reading.

For the adafruit driver (and their GFX lib), I am using the HW setting, and have the SPI wired to the HW pins.
Teensy3.1 pins 10,11,12,13.

Thanks.
 
Certainly the right pins for hardware SPI on the teensy 3.1. I presume you set the SPI clock divisor to 2? (Not sure what the max refresh rate is but 12 MHz seems reasonable)
 
Oliver (the u8glib guy) is active in the arduino forum and apparently doesn't have a teensy 3.0. I'm planning to change that by sending him one of the "contributor boards" I received from Paul. There is an "ARM" port of u8glib which is fairly generic, but it doesn't work asynchronously (yet) and is written in C.
 
Hi, thanks.

I did play with the divisor a bit. I ran several different versions. 96/8, 48/4, 24/2...all to mostly no visible difference in refresh rate.

I'll be watching this thread.
 
That's what I would expect. If the SCK frequency is always the same (which it is for 96/8, 48/4 and 24/2) the amount of data per second that arrives at the display doesn't change.

The display needs 3 8-bit SPI transfers per byte with the settings made by u8glib (there's a different configuration possible, however). The maximum possible frame rate you can then get with 12 MHz SCK is 12 MHz/(8*3*128*128) = 30.5, which is close to what I get with DMA (about 22 fps, including overhead for paging and actually drawing stuff). u8glib (and most probably all other more or less generic graphics libraries) don't use DMA but instead write out byte for byte, adding overhead to each SPI transfer. This can be improved by utilizing the SPI's TX FIFO, but the library doesn't do that. Now add overhead for drawing and paging, and you're at 10 fps.
 
Yes, 10fps seems about right.

My question is this, why develop and make a display with such a low frame rate?
Or are we missing something? Is this the display or the SPI interface adafruit added?

I will get the datasheet and see.

Looks like more research is needed.

Thanks.
 
It's the library. The minimum clock cycle time for the SSD1351 is 50 ns, so f_SCK < 20 MHz, corresponding to roughly 50 fps in 262k color mode. If you configure it for 65k color mode, you can get 76 fps. It's all up to the library. With DMA, f_SCK = 16 MHz and 65k colors, I'd say 25 fps are no problem even if you do some heavy drawing.
 
Hi Christoph,

I've noticed on this forum you seem to be the only guy who is actively trying to port a graphics lib for ssd1351 based on u8lib. I am very interested in the same thing, however my knowledge with ARM Cortex programming is pretty dismal. In fact I don't even have the OLED nor the Teensy3 yet! I was debating wether to buy a 4D-Systems uOLED board (http://www.4dsystems.com.au/product/1/2/4D_Intelligent_Display_Modules/uOLED_128_G2/) which has the graphics commands hard-wired in the chip with some extra features like video playback and animation but it is quite pricy ($55), or get an OEM sdd1351 OLED display for about $10 and a teensy 3.1, which is much cheeper and way more powerfull, among other benefits.

I am leaning more towards teensy 3.1 and ssd1351 myself but porting the u8lib for it and utilizing optimized SPI transfer with FIFO and DMA is a little bit over my head! So i wondetr if you have any sugestions or any code snipets that you might like to share.

Cheers

Sharko.
 
Hi Sharko,

the 4D-Systems board seems to be quite powerful and would be something totally different compared to directly attaching an SSD1351 display to a Teensy. I would post code if I had something readable and versatile, trust me. My experience is that posting code snippets for one particular setup usually doesn't really help people. Not documenting it enough just leads to frustration when someone tries to use it in their environment.

So, the bottom line is: this is going to take a while.
 
Yes it works. It works a lot better. I can create a clock, and it isn't flickering with every update.
FTOLED has a function they call 'reset()' in thier textboxes, that eliminates 'most' flicker. Full screen redraws are still slow, but it is better. I still see a redraw line on the biggest text I want to display. But I think its usable.

I downloaded the lib from thier webpage and it built ok for teensy3.1.

Thanks all.

ETA: proper textbox positioning (removing overlaps) removed all flicker.
 
Last edited:
Glad that worked.

I have 10 graphic LCD library test boards on my desk, but with the audio library release, looks like I won't do much with then for at least a few weeks.

Almost all have already been tested and ported, but not documented. I did the FTOLED fix a few weeks ago, as you can see in that thread and also on the Freetronics forum.

So far, only 2 libraries have native Teensy3 optimizations: ST7735 (rewored from Peter Loveday's earlier work) and UTFT (contributed by Dawnmist).

Several others, including FTOLED, are using the hardware SPI through the AVR compatibility layer. They achieve pretty good speed that way, but similar to Arduino Uno, because the compatibility code tries to configure the same speeds that an official Arduino Uno would use. Eventually I'm going to revisit FTOLED, ILI9340, RA8875, SSD1306 and others using SPI and port the native SPI code from ST7735. Using the native SPI is much faster, partly because it supports high SPI clock speeds, partly because it has a FIFO that helps reduce dead time between transfers.

One issue with the native SPI is a limitation of which pins you can use for CS and D/C. I recommend using pin 10 for CS and 9 for D/C. The available pins for those signals are 2, 6, 9, 10, 15, 20, 21, 22 and 23. However, four pairs must not be used together: 2 & 10, 6 & 9, 20 & 23, and 21 & 22. If you connect your CS and D/C signal to those 10 pins, and avoid those specific pairs, you'll be ready to use the native version when it's ported.
 
Thanks guys! Great information!

FTOLED seems very promising. I was originally going to pair a teensy 3 and a ssd1351 OLED to mainly do graphics intensive work at high(ish) colour and high frame rate. I'm sure teensy 3 can do that easily with a native library. It's great to know that you guys are working on it and I'm sure going to welcome it!

For now i think i'm going to use 4D-Systems display modules because of the robust hardware/library. Basically I need to have 16 displays, each with 4 touch sensors for a MIDI controller project. I thought instead of using 16 teensy3's and 16 ssd1351 displays I'd rather use a teensy 3 to control 16 4D-system modules via UART.

Teensy3 should also be able to send, receive, and parse MIDI information to and from a PC via USB. All the graphics and video processing and storage will be done on each individual display module and serial communication is only for synchronization and for high level instruction and data.

Of course this is subject of a different discussion, but i have to figure out how to multiplex 16 serial ports to use with teensy hardware UART's. I could sacrifice transmission rate and use a teensy 2++ and soft-serial library but that's a lot of overhead just for bit banging. There are also these nifty little 8-core Parallax propeller chips that can multiplex and parse up to 8 serial ports at high speed per chip.

For now I have to educate myself more. Project is a little daunting! I know some java and C but my knowledge of MCU's and electronics is very elementary. I sure look forward to a native ssd1351 library for teensy 3.

Thanks for the education! Cheers,

Sharko
 
Sharko,

what would you need in an ssd1351 library for the teensy 3? What do you want to draw:
  • Single Pixels (what color representation?)
  • Lines
  • Frames
  • Circles
  • Fonts (type, sizes?)
  • Which of these? Anything else?
How do you want to handle drawing areas for different display connected to the same teensy?
  • One big canvas for multiple displays, each using a "view" of that canvas
  • Individual canvases for each display
What other features do you need:
  • Clipping
  • Coordinate transformations
  • Support for different coordinate types (i.e. support for fixed point or floating points types)?
  • Which of these? Anything else?
I take it that you would like to update the displays in the background and have some free CPU time to do other calculations. As I'm currently writing a canvas library for my own SSD1351 project, I can try to implement some additional features for you. I can not test with multiple displays as I only have one. Same for Teensy 3.1 - I only have a teensy 3.0, so no second SPI.

Regards

Christoph
 
Hi Christoph and sorry for the delay!

- Single pixel draw would be great! 16 bit 64k colour is more than enough for me. I think that would be a 5-6-5 RGB representation. If i understand correctly from the data sheet, ssd1351 writes to it's RAM in 8 bit chunks, therefore a single 16 bit pixel is transfer uses 6 SPI clock cycles less than a 18 bit pixel. That may contribute to higher frame rate? I'm not sure. A little beyond me! I guess 18 bit 256k would be a fantastic bonus if it is efficient at higher frame rates. 16 bit is fine for my projects' requirements, which are basically asking for vivid coloured lines and curves moving across a black background with some text. I can think of real time wave-form and ADSR representations for synths and such.

- Lines, frames, circles and the usual graphic primitives are very useful. Would be great to have filled rectangles and circles too.

- Fonts dont have to be true-type. up to about 40 pixels hight is good enough. Hoping for an easy(ish) way for me to import custom fonts of any readily available formats out there.

- As for multiple displays I was planning to run one teensy3 with one display, and then multiply them by 16. Then i was going to find a way for these 16 teensy's to communicate with each other and with MIDI. It would be great to handle more than 1 display per each teensy but i haven't really thought about that. I guess we can have a large canvas with different views for each display.

- Clipping, transformations, and anything that can help me eventually incorporate animations and bitmap drawing are hugely welcomed! In fact I would love to have a function similar to 4-D Systems display's draw-video-frame method which basically is a great tool to incorporate animated GUI elements such as guages and VU meters. I suppose for bit map and video we need the sd card which uses the same hardware spi on teensy 3 but it could go on second hardware spi on teensy 3.1 (?)

-Yes, background processing is a requirement as I'm hoping to also process four touch inputs and parse MIDI too.

Thanks so much for asking for my input! Please let me know if there is anything I can do to help.

Cheers.

Sharko
 
Last edited:
Hi Sharko,

- the ssd1351 has 2 color modes - 16 bit (RGB565, 2 bytes) and 18 bit (RGB666, 3 bytes). RGB565 needs one byte less per SPI transfer, which clearly helps with getting higher fps. It's up to you to decide if you really need the extra color depth.

- Lines, ellipses, circles and frames are no problem, I need those too. I'm not sure how hard it would be to implement filling for ellipses and circles, but I'll give it a go.

- Fonts would need to be converted to a custom, library-specific binary format. I'm currently using u8glib's format, which works well, but it has its quirks. See if u8glib has the fonts you need, otherwise it's possible to convert true type fonts to bdf and then write a converter tool that creates the custom binary format. 40 pixels seems a bit large for a 128x128 display, but I don't know what you want to do.

- Bitmap Fonts are hard to scale and rotate. I highly recommend not wanting to do that.

- Clipping can be an expensive operation. At the moment I'm doing it pixel-wise, which means that even for a line every pixel that would be drawn without clipping is calculated, but only drawn if the clipping object allows it. It's not the line that is clipped, but the pixels. Coordinate transformations are a simple thing (i.e. draw line a -> b becomes draw line a' ->b'), object transformations are not (i.e. scaling and rotating a bitmap).

Here are some numbers for my current project using the ssd1351 with my own code: My information is monochrome (I just need black/red), so I use a packed monochrome page buffer. The display driver takes a chunk and expands it to 16-bit RGB before sending it to the display. Filling the whole display with the character ' ' (0x20, beginning of the font) takes 39 ms (roughly 25 fps), filling it with 'g' takes 72 ms (too slow), and filling it with the character at 0xFF takes 120 ms (bad!). At 12 MHz f_SCK, 22 ms plus overhead are needed for the SPI transfer, which means that about 17 ms are eaten by the expansion from monochrome to RGB, and most of the CPU time is wasted by looking up glyphs. I'll have to add some kind of glyph lookup tables for fonts that are heavily used, which would result in constant glyph lookup time (not linear as it is now).
 
Hi Paul - I see that you are working through u8glib issues - when you do will it support using a HW serial port? I am currently using the ST7565 library but I am thinking to migrate to u8glib for three reasons (1) multiple fonts (2) richer API and (3) speed.
 
Thanks Christof,

16 bit RGB565 is all i need. 25 fps would be fantastic! cant wait to see that. everything else is luxury for me and i suppose 40 pixel fonts are a little excessive. Please keep us in the loop of your progress as i'm sure it would be useful to a lot of people.
 
I'm currently writing a converter that compresses bitmap fonts to a proprietary format similar to that used by u8glib.

Next step is to simplify the classes I use for DMA, as the current implementation depend on modifications to the linker script.
 
Friendly advice: Stay away from the uOLED-128-G2 . Me and my pupil are trying to get it working for about 2 months now. While it works out of the box with an arduino mini pro, it is absolutely unusable with the teensy 3.1. My guess up to now is, that the Goldelox Library simply fails on the teensy. As soon as you call any function related to that library (even a clear), your program freezes on the teensy.

While the display is good and compatible with arduino, it is a nightmare with teensy.
 
Actually I just noticed this thread. I don't have the uOLED-128-G2, but I do have a uOLED-128-G1. Not sure how much different they are, but I do have a Teensy 3.1 connected up to it in my DIY remote (Talked about in this thread)

I rolled my own sort-of library to run this earlier on different Arduinos, and did not have any issues when I tried it on Teensy. I am not sure if it would help you or not, but the code is part of my Teensy remote code in the github project: https://github.com/KurtE/DIY-Remote_Control

Note: There was another more advanced library (by I think Avenue33?) that worked on this OLED, both on Arduino and Chipkit, that I was at the time going to convert to, but never did. Also some of the links I found for this library no longer appear to exist.
 
Status
Not open for further replies.
Back
Top