adafruit / Adafruit-SSD1331-OLED-Driver-Library-for-Arduino

For 0.96" OLEDs in the Adafruit shop
http://www.adafruit.com/products/684
Other
100 stars 67 forks source link

HWSPI works on ESP8266 but not ESP32. SWSPI works on ESP32 but is slow #27

Open marcmerlin opened 5 years ago

marcmerlin commented 5 years ago

I'm using the last version from git with arduino 1.8.9 on ESP32

#define sclk 18
#define mosi 23
#define rst  26
#define dc   27
#define cs   25

#define miso 19 // unused except for HWSPI init
#pragma message "Using SWSPI"
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);

//#pragma message "Using ESP32 SPI"
//#include "SPI.h"
//SPIClass tftSPI(VSPI);
//Adafruit_SSD1331 display = Adafruit_SSD1331(&tftSPI, cs, dc, rst);

(...)
    display.begin();
    display.setAddrWindow(0, 0, 96, 64);
    Serial.println("setAddrWindow");
    display.fillScreen(LED_WHITE_HIGH);
    display.show();
    Serial.println("first show done");  << when hang, this never gets displayed

The code works as is but is slow due to SWSPI. Adafruit_SSD1331(cs, dc, rst); hangs as soon as I run display.show() Adafruit_SSD1331(&SPI, cs, dc, rst) hangs too and the full definition of tftSPI using VSPI default pins, also hangs.

makermelissa commented 5 years ago

Thanks for reporting this. I’ll take a look. HWSPI should be working for both.

marcmerlin commented 5 years ago

So, to be fair, the HWSPI situation on ESP32 is not super clear, as there are 2 default SPIs, VSPI and HSPI. You'd think HSPI is the default, but at least with

I have a little cheat sheet that I paste in my code and that you are welcome to borrow from if you'd like to include it in your code samples too:

/*  https://pinout.xyz/pinout/spi
SD1331 Pin      Arduino ESP8266     ESP32   ESP32   
1 GND                                           VSPI    HSPI    
2 VCC                                                           
3 SCL/SCK/CLK/D0    13  GPIO14/D5   18  14  
4 SDA/SDI/MOSI/D1   11  GPIO13/D7   23  13  
5 RES/RST       9   GPIO15/D8   26  26  
6 DC/A0/RS (data)   8   GPIO05/D1   27  27  
7 CS            10  GPIO04/D2   25  25  

  MISO          12  GPIO12/D6   19  12  
*/

I know @ladyada told me in a prior PR I sent to add pinouts for other chips that she wasn't really interested in it, but at the same time, you do have it in some other library examples like this one https://github.com/adafruit/Adafruit-ST7735-Library/blob/075609ce4684301392ca932528c58b96f8c80247/examples/graphicstest/graphicstest.ino#L30 Thankfully that demo nicely gives the pin numbers for VSPI on ESP32, especially as honestly most people are likely to think that HSPI pins are the default, when indeed they are not.

While you don't have to include https://github.com/adafruit/Adafruit-SSD1331-OLED-Driver-Library-for-Arduino/pull/25/files as is, I think something similar to what you have for ST7735, would make things easier for people testing (including you when looking at a report like this one :) ).

As far as wiring goes, I have confirmed that VSPI pins with HWSPI works on my ESP32 with ILI9341, as well as ST7735, and the writing works with SSD1331 as long as I define the pins as SWSPI. I've re-confirmed that changing nothing but this:

//Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, mosi, sclk, rst);
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);

causes the SPI to hang. This was just to make sure again that it was hopefully not a problem on my side.

makermelissa commented 5 years ago

I think the pins used for the ST7735 Library were submitted as part of a PR that I merged in. The reason I let those be added in was because the PR organized all the examples to be consistent which made it easy to be able to add PyGamer and PyBadge pin sets since they use the ST7735R display. One reason including the ESP32 pins is useful in the ST7735 library and not so much here is because there is a featherwing that uses the ST7735R display (Mini TFT plus joystick) so it can be easily matched with the Huzzah32 Feather, but the SSD1331 is only available in a breakout.

That being said, it might be nice to add a comment into this library that basically says the ESP32 uses VSPI by default.

ladyada commented 5 years ago

yeah i dont like having non-fixed-hardware-devices in #ifdefs. it can cause a lot of confusion and support on our side :/

marcmerlin commented 5 years ago

@makermelissa https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/examples/graphicstest/graphicstest.ino is actually an example of what I'd like to see more :) I hear both of you and @ladyada on the fact that you'd rather not define pins randomly for breakout boards, but let's also be honestly that the SPI performance is terrible without HWSPI, and unless you really can't use HWSPI, you really should be using it. Even SSD1331 is too slow for me to use on ESP32 until I get HWSPI working. For the canonical example you give which each lib (and that is super useful), when you have multiple constructors with a HWSPI constructor that omits the pin numbers, I think that it would indeed not hurt to mention what those pins are for a few common chips do help people find them, especially for the ESP32 case where it's not obvious at all that you get VSPI by default (and still takes a bit of work to find the pins once you know it's VSPI). Honestly, https://github.com/adafruit/Adafruit-ST7735-Library/blob/075609ce4684301392ca932528c58b96f8c80247/examples/graphicstest/graphicstest.ino#L41 is a perfect example IMO.

Counter example is https://github.com/adafruit/Adafruit_ILI9341/blob/3a07e814872cd7fb6def4a66c6f8d1e2e0d75a20/examples/graphicstest/graphicstest.ino#L26 If I plug an ESP32 and use the HWSPI constructor, it's totally not obvious what pins I should wire for SPI (for ESP8266, I can do a google search for the SPI pins and there's only one set, so it's less confusing)

Now, to take @ladyada 's comment into account, maybe just mentioning the pins as part of a comment (i.e. not an ifdef), whether it's the small table I gave above, or some other way, would still be a very helpful pointer IMO.

Anyway, just my thoughts, you obviously have more insight about the pros and cons here.

marcmerlin commented 4 years ago

Any update on having HWSPI working on ESP32? I just ran into problems, traced it down for 45mn, only to realize that I was using SWSPI, and then later to find out that I had done this because HWSPI was broken and I had already filed this bug :)

marcmerlin commented 3 years ago

For anyone also seeing this problem, and not being ok with the SWSPI speed on ESP32 (I get only 7fps for full frame refresh), you can switch to https://github.com/moononournation/Arduino_GFX which supports HWSPI without crashing, and even HWSPI with DMA, which is even faster (I get around 160fps at 80Mhz)

terishrimp commented 3 months ago

This is still an issue in 2024 which is hilarious 😅. Following @marcmerlin's advice, all works well. If like me you'd also like to use the AnimatedGIF library, there's an example of that provided in the library here. Be sure to choose the correct display class if yours doesn't match the display in the example.

marcmerlin commented 3 months ago

@terishrimp I gave up on this lib and using Arduino_GFX exclusively. I then wrote my wrapper on top of it so you get all of GFX and FastLED and even LEDMatrix primitives on top of that better driver. Check out https://github.com/marcmerlin/FastLED_ArduinoGFX_TFT

The main reason for using my lib on top is that you can then replace the underlying hardware lib to one of 8 different things and your code will keep working see https://github.com/marcmerlin/Framebuffer_GFX and https://marc.merlins.org/perso/arduino/post_2020-03-16_Framebuffer_GFX_-Choosing-between-its-3-2D-APIs_-FastLED-XY_-NeoMatrix_-and-LEDMatrix_-and-detail-of-its-many-supported-hardware-backends.html