Hi all,
I'm working with an ESP32 dev kit V1; I'm trying to implement a simple menu in my code, and I'm doing few test on the i2c OLED (SSD1306) and a rotary encoder. Everything seem to work correctly until I use the serial.print, but when I try to add the oled display, something strange happen: at the beginning the display print the initial menu correctly, but when I click the rotary button, the display stop working. I post the code hoping that the problem will be more clear:
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h"
SSD1306Wire display(0x3c, SDA, SCL);
#define SW 4
#define DT 2
#define CLK 15
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
volatile bool stampa=true;
volatile long timing = 0;
uint8_t layer = 0;
uint8_t functionMenuSel;
uint8_t subMenuSel;
uint8_t valueSel;
volatile int8_t sumVal;
typedef struct subMenu{
String title;
double val;
};
typedef struct functionMenu{
String title;
subMenu variables[3];
String back = "back";
};
functionMenu Slider;
functionMenu TimeLapse;
functionMenu StopMotion;
functionMenu Impostazioni;
functionMenu Back;
functionMenu *menuList[5] = { &Slider, &TimeLapse, &StopMotion, &Impostazioni, &Back};
void setup() {
Slider.title = "Slider";
Slider.variables[0].title = "velocità";
Slider.variables[0].val = 100;
Slider.variables[1].title = "acellerazione";
Slider.variables[1].val = 2.5;
TimeLapse.title = "TimeLapse";
TimeLapse.variables[0].title = "passo";
TimeLapse.variables[0].val = 23;
TimeLapse.variables[1].title = "pausa";
TimeLapse.variables[1].val = 4.2;
StopMotion.title = "StopMotion";
Impostazioni.title = "Impostazioni";
// put your setup code here, to run once:
pinMode (DT, INPUT_PULLUP);
pinMode (CLK, INPUT_PULLUP);
pinMode (SW, INPUT);
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
// display.setFont(Roboto_Light_12);
attachInterrupt(DT, updateEncoder, CHANGE);
attachInterrupt(CLK, updateEncoder, CHANGE);
attachInterrupt(SW, menuSel, RISING);
Serial.begin (115200);
display.init();
// display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
// display.setFont(Roboto_Light_12);
}
void loop() {
if (stampa){
OLED_print();
Serial.println();
if (layer == 0) Serial.print("*");
Serial.println (menuList[functionMenuSel]->title);
if (layer == 1) Serial.print("*");
Serial.println ((String)" "+menuList[functionMenuSel]->variables[subMenuSel].title);
if (layer == 2) Serial.print("*");
Serial.println ((String)" "+menuList[functionMenuSel]->variables[subMenuSel].val);
delay(80);
stampa = false;
}
}
void OLED_print(){
display.clear();
if (layer == 0){
display.setTextAlignment(TEXT_ALIGN_LEFT);
for (int i; i<4; i++){
display.drawString(12, (i*12), menuList[i]->title ); // (x pos, y pos, string) --> text align set the distribution of the text starting from the x pos
}
display.drawString(0, (functionMenuSel*12), ">" );
}
if (layer == 1){
display.setTextAlignment(TEXT_ALIGN_LEFT);
for (int i; i<2; i++){
display.drawString(12, (i*12), menuList[functionMenuSel]->variables[i].title ); // (x pos, y pos, string) --> text align set the distribution of the text starting from the x pos
}
display.drawString(0, (subMenuSel*12), ">");
}
display.display();
}
void updateValue () {
switch (layer) {
case 0:
functionMenuSel += sumVal;
if (functionMenuSel > 3) functionMenuSel = 0;
break;
case 1:
subMenuSel += sumVal;
if (subMenuSel > 2) subMenuSel = 0;
break;
case 2:
menuList[functionMenuSel]->variables[subMenuSel].val += sumVal;
break;
}
stampa=true;
timing=millis();
}
void menuSel () {
if (millis() - timing>200){
if (layer < 2) layer++;
else layer--;
if (layer==2 && (functionMenuSel == 4 || subMenuSel == 2)) layer = 0;
stampa=true;
timing = millis();
}
}
void updateEncoder() {
int MSB = digitalRead(DT); //MSB = most significant bit
int LSB = digitalRead(CLK); //LSB = least significant bit
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
//if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
//if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
if (sum == 0b1000){
if (millis() - timing>80) {
encoderValue ++;
sumVal = 1;
updateValue();
timing = millis();
}
//else encoderValue +=10;
}
if (sum == 0b0010) {
if (millis() - timing>80) {
encoderValue --;
sumVal = -1;
updateValue();
timing = millis();
}
//else encoderValue -=10;
}
lastEncoded = encoded; //store this value for next time
}
In the "OLED_print" function, I've tried to remove the "if" statements, so that the same menu page should be print regardless of the "layer" value, just to verify, but again when i push the rotary button, the oled stops working.
Probably I'm doing some basic errors, but I've been on it for too long, and I can't see it.
Thanks in advance for your help!
Fulvio