Skip to content

Instantly share code, notes, and snippets.

@Spirik
Last active July 10, 2023 22:46
Show Gist options
  • Save Spirik/5e3ce403a49f42c1c066989b0342b657 to your computer and use it in GitHub Desktop.
Save Spirik/5e3ce403a49f42c1c066989b0342b657 to your computer and use it in GitHub Desktop.
Basic example for use with Adafruit Feather M0 + Adafruit 128x64 OLED FeatherWing
/*
Variation of basic menu example using GEM library for use with Adafruit Feather M0 + Adafruit 128x64 OLED FeatherWing.
Simple one page menu with one editable menu item associated with int variable, one with boolean variable,
and a button, pressing of which will result in int variable value printed to Serial monitor if boolean variable is set to true.
Adafruit GFX library is used to draw menu.
KeyDetector library is used to detect push-buttons presses.
Additional info (including the breadboard view) available on GitHub:
https://github.com/Spirik/GEM
This example code is in the public domain.
*/
#include <GEM_adafruit_gfx.h>
#include <KeyDetector.h>
// SPI and I2C libraries required by FeatherWing
#include <SPI.h>
#include <Wire.h>
// Hardware-specific library for Adafruit FeatherWing.
// Include library that matches your setup (see https://learn.adafruit.com/adafruit-gfx-graphics-library for details)
#include <Adafruit_SH110X.h>
// FeatherWing buttons
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
// Pins the buttons are connected to
const byte downPin = BUTTON_C;
// const byte leftPin = 3;
// const byte rightPin = 4;
// const byte upPin = 5;
const byte cancelPin = BUTTON_B;
const byte okPin = BUTTON_A;
// Array of Key objects that will link GEM key identifiers with dedicated pins
Key keys[] = {{GEM_KEY_DOWN, downPin}, {GEM_KEY_CANCEL, cancelPin}, {GEM_KEY_OK, okPin}};
// Create KeyDetector object
KeyDetector myKeyDetector(keys, sizeof(keys)/sizeof(Key), 0, 16, true);
// To account for switch bounce effect of the buttons (if occur) you may want to specify debounceDelay
// as the third argument to KeyDetector constructor:
// KeyDetector myKeyDetector(keys, sizeof(keys)/sizeof(Key), 10, 16, true);
// Create an instance of the Adafruit GFX library.
// Use constructor that matches your setup (see https://learn.adafruit.com/adafruit-gfx-graphics-library for details).
// Adafruit 128x64 OLED FeatherWing is used in the example.
// This instance is used to call all the subsequent Adafruit GFX functions (internally from GEM library,
// or manually in your sketch if it is required)
Adafruit_SH1107 display = Adafruit_SH1107(64, 128, &Wire);
// Create variables that will be editable through the menu and assign them initial values
int number = -512;
boolean enablePrint = false;
// Create two menu item objects of class GEMItem, linked to number and enablePrint variables
GEMItem menuItemInt("Number:", number);
GEMItem menuItemBool("Enable print:", enablePrint);
// Create menu button that will trigger printData() function. It will print value of our number variable
// to Serial monitor if enablePrint is true. We will write (define) this function later. However, we should
// forward-declare it in order to pass to GEMItem constructor
void printData(); // Forward declaration
GEMItem menuItemButton("Print", printData);
// Create menu page object of class GEMPage. Menu page holds menu items (GEMItem) and represents menu level.
// Menu can have multiple menu pages (linked to each other) with multiple menu items each
GEMPage menuPageMain("Main Menu");
// Create menu object of class GEM_adafruit_gfx. Supply its constructor with reference to display object we created earlier
GEM_adafruit_gfx menu(display, GEM_POINTER_ROW, GEM_ITEMS_COUNT_AUTO);
void setup() {
// Push-buttons pin modes
pinMode(downPin, INPUT_PULLUP);
// pinMode(leftPin, INPUT);
// pinMode(rightPin, INPUT);
// pinMode(upPin, INPUT);
pinMode(cancelPin, INPUT_PULLUP);
pinMode(okPin, INPUT_PULLUP);
// Serial communications setup
Serial.begin(115200);
delay(250); // Wait for the OLED to power up
display.begin(0x3C, true); // Address 0x3C default
// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
// display.display();
// delay(1000);
// Clear the buffer.
display.clearDisplay();
display.display();
display.setRotation(1);
// Explicitly set correct colors for monochrome OLED screen
menu.setForegroundColor(SH110X_WHITE);
menu.setBackgroundColor(SH110X_BLACK);
// Disable GEM splash (it won't be visible on the screen of buffer-equiped displays such as this one any way)
menu.setSplashDelay(0);
// Menu init, setup and draw
menu.init();
setupMenu();
menu.drawMenu();
display.display();
}
void setupMenu() {
// Add menu items to menu page
menuPageMain.addMenuItem(menuItemInt);
menuPageMain.addMenuItem(menuItemBool);
menuPageMain.addMenuItem(menuItemButton);
// Add menu page to menu and set it as current
menu.setMenuPageCurrent(menuPageMain);
}
void loop() {
// If menu is ready to accept button press...
if (menu.readyForKey()) {
// ...detect key press using KeyDetector library
myKeyDetector.detect();
// Pass pressed button to menu
// (pressed button ID is stored in trigger property of KeyDetector object)
menu.registerKeyPress(myKeyDetector.trigger);
// Necessary to actually draw current state of the menu on screen
display.display();
}
}
void printData() {
// If enablePrint flag is set to true (checkbox on screen is checked)...
if (enablePrint) {
// ...print the number to Serial
Serial.print("Number is: ");
Serial.println(number);
} else {
Serial.println("Printing is disabled, sorry:(");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment