Hello,
I am trying to create an interactive menu with a ST7735(Adafruit 1.8 inch version) display.
The display is mounted on a PCB(game console style, with buttons), and the MCU is a Raspberry Pi Pico W.
Sprig:
PCB Game console powered by Pico W,
Display: ST7735R 1.8 Inch Adafruit Display
#define TFT_CS 21
#define TFT_RST 26 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 22
Buttons:
|W:GPIO5|A:GPIO6|S:GPIO7|D:GPIO8|
|I:GPIO12|J:GPIO13|K:GPIO14|L:GPIO15|
(Those are the only hardware features I intend to use for now, so I will only list them)
I created this topic to get advice on software improvements.
(And perhaps some UI advice)
Project details:
I am attempting to create a program for the Sprig(Pico W MCU), that has multiple menus,
So a bit like:
Option 1 >
Option 2
Option 3
Which, when the D button is pressed, it advances to a second menu.
When the final submenu is reached, something is executed.
Back buttons, titles, and page numbers may be needed.
Problems/Advice requested(Higher on list is higher in curiosity levels):
Currently, the whole code isn't written very well, so first I would like to know how to clean it up,
Possible things I have thought about:
Classes for options(I'm unsure if this is possible, but something that points to a function to execute?), and pins.
Miscalculated where the ">" triangle is supposed to be, minor counting mistakes.
Improving readability.
Menu class might be a good idea, if I can figure that out.
Code:
/*
Experiments with Sprig and Arduino.
*/
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
//#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#define TFT_CS 21
#define TFT_RST 26 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 22
#define WIDTH 160
#define HEIGHT 128
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
const int wButtonPin = 5;
const int aButtonPin = 6;
const int sButtonPin = 7;
const int dButtonPin = 8;
const int iButtonPin = 12;
const int jButtonPin = 13;
const int kButtonPin = 14;
const int lButtonPin = 15;
void setup() {
Serial.begin(115200);
Serial.print(F("Hello! ST77xx TFT Test"));
pinMode(wButtonPin, INPUT_PULLUP);
pinMode(aButtonPin, INPUT_PULLUP);
pinMode(sButtonPin, INPUT_PULLUP);
pinMode(dButtonPin, INPUT_PULLUP);
pinMode(iButtonPin, INPUT_PULLUP);
pinMode(jButtonPin, INPUT_PULLUP);
pinMode(kButtonPin, INPUT_PULLUP);
pinMode(lButtonPin, INPUT_PULLUP);
/*
for (int i = 5; i < 9; i++) {
pinMode(i, INPUT_PULLUP);
}
for (int i = 12; i < 16; i++) {
pinMode(i, INPUT_PULLUP);
}
*/
pinMode(17, OUTPUT);
digitalWrite(17, HIGH);
// Use this initializer if using a 1.8" TFT screen:
tft.initR(INITR_BLACKTAB); // Init ST7735S chip, black tab
tft.setRotation(3);
//rocket fast sprig, anyone?
// SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here
// Note that speed allowable depends on chip and quality of wiring, if you go too fast, you
// may end up with a black screen some times, or all the time.
//tft.setSPISpeed(40000000);
Serial.println(F("Initialized.."));
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(0, 0);
tft.setTextColor(ST77XX_GREEN);
tft.println("TITLE - Page 1 of 1");
tft.drawLine(0, 10, WIDTH, 10, ST77XX_WHITE);
tft.setCursor(0, 12);
//so the line is at 10, and we start text at 12.
tft.println("Option 1");
tft.println("Option 2");
tft.println("Option 3");
tft.println("Option 4");
//tft.drawLine(0, 12, WIDTH, 12, ST77XX_WHITE);
//tft.drawLine(0, 21, WIDTH, 20, ST77XX_WHITE);
}
bool lastWButtonState = false;
bool wButtonState = false;
bool lastSButtonState = false;
bool sButtonState = false;
int option = 1;
void loop() {
Serial.println("I'm still alive,");
static unsigned long timer = 0;
unsigned long interval = 50;
int optionLocation = (7 * (option - 1)) + 13;
Serial.println("looping, I guess");
if (millis() - timer >= interval) {
Serial.println("interval");
timer = millis();
// read the pushbutton input pin:
wButtonState = digitalRead(wButtonPin);
sButtonState = digitalRead(sButtonPin);
if (sButtonState != lastSButtonState) {
if ((sButtonState == false) && (option < 4)) {
tft.fillTriangle(WIDTH - 3, optionLocation, WIDTH - 7, optionLocation - 2, WIDTH - 7, optionLocation + 2, ST77XX_BLACK);
Serial.println("sbutton ");
option++;
optionLocation = (7 * (option - 1)) + 13;
tft.fillTriangle(WIDTH - 3, optionLocation, WIDTH - 7, optionLocation - 2, WIDTH - 7, (optionLocation) + 2, ST77XX_YELLOW);
}
}
// compare the wButtonState to its previous state
if (wButtonState != lastWButtonState) {
if ((wButtonState == false) && (option > 1)) {
tft.fillTriangle(WIDTH - 3, optionLocation, WIDTH - 7, optionLocation - 2, WIDTH - 7, optionLocation + 2, ST77XX_BLACK);
Serial.println("wbutton");
option--;
optionLocation = (7 * (option - 1)) + 13;
tft.fillTriangle(WIDTH - 3, optionLocation, WIDTH - 7, optionLocation - 2, WIDTH - 7, optionLocation + 2, ST77XX_YELLOW);
}
}
}
lastWButtonState = wButtonState;
lastSButtonState = sButtonState;
}
(I'm sorry, the code is not documented at all)
(Button reading code from @\groundFungus, thank you!)
(Have not had time for better crediting)
I'm having quite a lot of fun creating this program, so I might ask that instead of completing everything, instead give me small steps to continue progress.
(Sorry for inconvenience that way)
More hardware details
Schematic(Hack Club Sprig):
https://github.com/hackclub/sprig/blob/main/hardware/mainboard_PCB/schematic.png?raw=true
Layout files(KiCAD):
(I do not believe that those files are needed, as I cannot modify the hardware)
sprig/hardware/mainboard_PCB/kicad at main · hackclub/sprig · GitHub
Other information:
MacOS Sonoma
Arduino IDE 2.x.x
Core: GitHub - earlephilhower/arduino-pico: Raspberry Pi Pico Arduino core, for all RP2040 boards
Thank you,
I'm sorry if this message was a bit too long.
I'm somewhat happy that I managed to use some non-blocking code without failing,