I love these little 128x64 OLED displays, and have used them in many projects. However, I'm encountering a very odd issue. I have a menu driven system, and use a rotary encoder to select items on the menu. Pictures say it all, so here is a picture of the type of menu driven interface I am using:
When I turn the encoder knob, the highlight will scroll through Selection #1 through #4. The problem is, my Teensy 2.0 is crashing after I spin the knob a few times. The highlight will scroll through all of the selections a few times, and then it will hang.
Through a careful set of Serial.println lines, I have determined that it is crashing at the I2C write within the Adafruit_SSD1306 library, called when I call display.display(). I have plenty of memory (1156 bytes of dynamic memory), and see no indication that I am running out of memory.
There is something interesting I've noticed though. If you look at my code, you'll see that my println lines to the OLED have spaces that go all the way to the right side of the screen. This is so the highlight extends all the way across.
If I remove one of the spaces, the crashes are less frequent, two spaces and even less frequent... Removing four spaces from the end seems to eliminate the crashes, though maybe if I play with it long enough I can get it to happen. That's a workaround, but doesn't seem to solve the real problem, and I can't have my code crashing even once in a while.
Any tips on what might be going on would be really appreciated. Or even how to debug the problem.
Here is source code to reproduce the issue. I've cut it down to the bare minimum to reproduce the problem:
When I turn the encoder knob, the highlight will scroll through Selection #1 through #4. The problem is, my Teensy 2.0 is crashing after I spin the knob a few times. The highlight will scroll through all of the selections a few times, and then it will hang.
Through a careful set of Serial.println lines, I have determined that it is crashing at the I2C write within the Adafruit_SSD1306 library, called when I call display.display(). I have plenty of memory (1156 bytes of dynamic memory), and see no indication that I am running out of memory.
There is something interesting I've noticed though. If you look at my code, you'll see that my println lines to the OLED have spaces that go all the way to the right side of the screen. This is so the highlight extends all the way across.
Code:
display.println(F("Selection #1 "));
If I remove one of the spaces, the crashes are less frequent, two spaces and even less frequent... Removing four spaces from the end seems to eliminate the crashes, though maybe if I play with it long enough I can get it to happen. That's a workaround, but doesn't seem to solve the real problem, and I can't have my code crashing even once in a while.
Any tips on what might be going on would be really appreciated. Or even how to debug the problem.
Here is source code to reproduce the issue. I've cut it down to the bare minimum to reproduce the problem:
Code:
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define ENC_A 14
#define ENC_B 15
#define OLED_RESET 17
Adafruit_SSD1306 display(OLED_RESET);
int encoderPos, encoderPosPrev;
void setup()
{
pinMode(ENC_A, INPUT_PULLUP);
pinMode(ENC_B, INPUT_PULLUP);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED I2C Address, may need to change for different device,
// Check with I2C_Scanner
updateSelection();
}
void loop()
{
updateEncoderPos();
}
void updateEncoderPos() {
static int encoderA, encoderB, encoderA_prev;
encoderA = digitalRead(ENC_A);
encoderB = digitalRead(ENC_B);
if((!encoderA) && (encoderA_prev)){ // A has gone from high to low
encoderPosPrev = encoderPos;
encoderB ? encoderPos++ : encoderPos--;
updateSelection();
}
encoderA_prev = encoderA;
}
void updateSelection() { // Called whenever encoder is turned
display.clearDisplay();
display.setCursor(0,0);
display.setTextColor(WHITE,BLACK);
display.print(F("SELECTIONS"));
display.setCursor(0,16);
setHighlight(0,4);
display.println(F("Selection #1 "));
setHighlight(1,4);
display.println(F("Selection #2 "));
setHighlight(2,4);
display.println(F("Selection #3 "));
setHighlight(3,4);
display.println(F("Selection #4 "));
display.display();
}
void setHighlight(int menuItem, int numMenuItems) {
if (mod(encoderPos, numMenuItems) == menuItem) {
display.setTextColor(BLACK,WHITE);
}
else {
display.setTextColor(WHITE,BLACK);
}
}
int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
}