Hi @chizbiz ,
I took your Wokwi simulation and modified it so that it works:
Sketch:
/*
Forum: https://forum.arduino.cc/t/do-while-loop-of-u8g-page-drawing-mode-stops-everything-else-in-void-loop/1240533
Wokwi: https://wokwi.com/projects/393526781879393281
2024/03/27
ec2021
*/
#include "U8glib.h"
#define ENCODER_CLK 3
#define ENCODER_DT 2
#define ENCODER_SW 4
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
//images
// 'icon_dashboard', 16x16px
const unsigned char epd_bitmap_icon_dashboard [] PROGMEM = {
0x07, 0xe0, 0x18, 0x18, 0x21, 0x24, 0x50, 0x02, 0x48, 0x0a, 0x84, 0x01, 0x83, 0x81, 0xa2, 0x45,
0x82, 0x41, 0x81, 0x81, 0xa0, 0x05, 0x40, 0x02, 0x4b, 0xd2, 0x23, 0xc4, 0x18, 0x18, 0x07, 0xe0
};
// 'icon_battery', 16x16px
const unsigned char epd_bitmap_icon_battery [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x40, 0x04, 0x5b, 0x66, 0x5b, 0x66,
0x5b, 0x66, 0x40, 0x04, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'icon_parksensor', 16x16px
const unsigned char epd_bitmap_icon_parksensor [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x22, 0x00, 0x25, 0x00, 0xf9, 0x00, 0x00, 0x81,
0x0c, 0x85, 0x12, 0x95, 0xd2, 0x95, 0x0c, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'scrollbar_background', 8x64px
const unsigned char epd_bitmap_scrollbar_background [] PROGMEM = {
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02,
0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
};
// 'item_sel_outline', 128x21px
const unsigned char epd_bitmap_item_sel_outline [] PROGMEM = {
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
};
const int NUM_ITEMS = 3;
char menu_item[NUM_ITEMS][20] {
{"Battery"},
{"Set Timer"},
{"4WD Status"}
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 144)
const int epd_bitmap_allArray_LEN = 3;
const unsigned char* epd_bitmap_allArray[3] = {
epd_bitmap_icon_battery,
epd_bitmap_icon_dashboard,
epd_bitmap_icon_parksensor
};
// Global variable that holds the values
// 0 = not rotated
// 1 = clockwise
// -1 = counterclockwise
// declared volatile to avoid compiler optimization
volatile int rotation = 0;
#define LED_PIN 13
bool led_state = LOW;
void setup() {
//serial monitor
Serial.begin(115200);
// Set the encoder pins as required
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
// Attach the function readEncoder to an interrupt on ENCODER_CLK pin on a falling edge
attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoder, FALLING);
//test led
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, led_state);
//oled screen
u8g.setFont(u8g_font_tpssb);
u8g.setColorIndex(1);
}
void loop() {
u8g.firstPage();
do {
u8g.drawBitmapP( 4, 2, 16 / 8, 16, epd_bitmap_allArray[0]);
u8g.setFont(u8g_font_7x14);
u8g.drawStr(26, 15, menu_item[0]);
u8g.drawBitmapP( 4, 24, 16 / 8, 16, epd_bitmap_allArray[1]);
u8g.setFont(u8g_font_7x14B);
u8g.drawStr(26, 37, menu_item[1]);
u8g.drawBitmapP( 4, 46, 16 / 8, 16, epd_bitmap_allArray[2]);
u8g.setFont(u8g_font_7x14);
u8g.drawStr(26, 59, menu_item[2]);
u8g.drawBitmapP( 0, 22, 128 / 8, 21, epd_bitmap_item_sel_outline);
u8g.drawBitmapP( 120, 0, 8 / 8, 64, epd_bitmap_scrollbar_background);
// Call the encoder handler inside the ug8 while loop()
handleEncoder();
} while ( u8g.nextPage() );
}
// Interrupt routine to change the global variable rotation in case of a falling edge detected
// on ENCODER_CLK pin
void readEncoder() {
int dtValue = digitalRead(ENCODER_DT);
if (dtValue == HIGH) {
rotation = 1; // Clockwise
}
if (dtValue == LOW) {
rotation = -1; // Counterclockwise
}
}
// Function to copy the value of rotation to another variable while
// interrupts are "switched off" and then returns this value to the Encoder handler routine
// After this rotation is reset to 0 so that it is set again by the next interrupt
int getRotation(){
noInterrupts();
int rot = rotation;
rotation = 0;
interrupts();
return rot;
}
// Handles the value returned from getRotation() and also checks the
// Encoder switch state
// If ENCODER_SW was LOW it ignores this state for 500 ms to avoid
// bouncing and multiple detections
void handleEncoder() {
static unsigned long lastPress = 0;
switch (getRotation()) {
case -1 : Serial.println("Rotated counterclockwise ⏪");
break;
case 1 : Serial.println("Rotated clockwise ⏩");
break;
}
if (digitalRead(ENCODER_SW) == LOW && millis()-lastPress > 500) {
lastPress = millis();
led_state = !led_state;
digitalWrite(LED_PIN, led_state);
Serial.println("Button Pressed");
}
}
You can test it here:
Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!
Changes:
For further information see the comments in the sketch ...
Good luckj
ec2021