SPI Display Corruption on During Interrupt on digital pin using SSD1331 display

So I have tried an SSD1331 OLED display with both a nano every/standard and I am getting display corruption only when using interrupts that trigger. I am very familiar with this display driver and have used it for countless things outside of using interrupts. With interrupts, It's like the display loses some kind of clock sync and starts writing gibberish, or random pixels or worse. This isn't a "how to fix my code" question. I am looking for general direction to try first to figure this out on my own, but here are my thoughts..
Here is what I have tried based on popular platforms like stackexchange, arduino, and other research:
These are 1ms - 2ms pulses from a signal generator.
PulseIn - Works for a while, but slows code down considerably, and eventually corrupts display.
Servo.h - also works for a while, doesn't slow code as much, but corrupts display pretty quickly.
Creating my own polling function - checking digital pin input every loop for a high or low signal, recording state and duration, and estimating the pwm width from that. This slows the program to a level I don't like, but doesn't corrupt the display (leading me to believe it's an interrupts-associated issue)
External Interrupts and Pin Change interrupts both tried.
Tried using attachinterrupt(digitalPinToInterrupt) and all associated code, still corrupts display when interrupt is enabled.
Tried using SPI.UsingInterrupt(); Doesn't seem to have an effect on spi display corruption, it's still corrupting when the interrupts is active.
(By active, I mean when the interrupt senses an event. I can let it sit for 20 min without doing the event and the display never corrupts, but the moment I do something to trigger an interrupt state, in any of the above code scenarios, the display will corrupt a bit (Random pixels, lines, etc) once the interrupts triggers)

What I would like direction on, is, does anyone know if, since interrupts stop the main code, is there a way to process signals from interrupts without interfering with SPI displays? (Keep in mind the above methods I have tried)
If yes, then I have more research to do. If no, then I can quit wasting my time trying to work around something that's not going to be possible.

If someone else has had success with the methods above using an SSD1331 driver on an Oled that displays complex graphics, then it must be my code causing issues.

None of the aforementioned methods work when timing SPI display events, I have to use internal registers - this is not desirable, but if that's the case, I can try to go down that rathole.

I'm missing something else.. could use a pointer in the right direction about using interrupts or measuring an external digital signal in a way that doesn't interfere with the display.

I would think an oscilloscope program would be a great example of interrupts vs real time display..

B:

It's probably "not all interrupts" because:
1: Timer0 is interrupting about 980 times a second.
2: pulseIn() doesn't use interrupts.

Does it happen mostly when you have your own ISR? Does your ISR do anything it shouldn't? Does any of your code write into an array?

Set Preferences... -> Compiler warnings: [All]
Then look carefully at any compiler warnings.
Triple-check any place where you cast or convert variable types. Look for places where integer math might overflow. Add serial output to let you know what path your code is taking and if your variables have the expected values.

This ---> Set Preferences... -> Compiler warnings: [All]
Was a great idea. Thanks!

I found a few of these:

libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp: In member function 'bool Adafruit_I2CDevice::_read(uint8_t*, size_t, bool)':
\libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp:176:79: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
   size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
                                                                               ^
In file included from \libraries\Adafruit_BusIO/Adafruit_I2CDevice.h:1:0,
                 from \libraries\Adafruit_BusIO\Adafruit_I2CDevice.cpp:1:
\ArduinoData\packages\arduino\hardware\megaavr\1.8.7\libraries\Wire\src/Wire.h:64:12: note: candidate 1: size_t TwoWire::requestFrom(int, int, int)
     size_t requestFrom(int, int, int);
            ^~~~~~~~~~~
\ArduinoData\packages\arduino\hardware\megaavr\1.8.7\libraries\Wire\src/Wire.h:62:12: note: candidate 2: virtual size_t TwoWire::requestFrom(uint8_t, size_t, bool)
     size_t requestFrom(uint8_t, size_t, bool);

In my pre-interrupt code..

Compiler Warnings to all, fixed all issues, now no errors or warnings.
Spi display still corrupts when using interrupt.
hmm.. I2C display, no problem. SPI display. Problem...

Are you using any alternate pins for either SPI or UART? If not, maybe try using the alternate SPI pins.

All those pins, SPI and I2C are multiplexed. You can have conflicts there.

Standard pins for that communication.

This may be a problem with writing the display too often. I just streamlined the writes in a different project and noticeably improved the speed. I am not sure why SPI would matter in this case though because it's much faster than the display would need in order to update anyway, so I believe it's a buffer or timing issue.. But the SCLK pin could be getting interrupted?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.