Adafruit character display basics are working with LcdMenu library

This commit is contained in:
len0rd 2025-02-09 14:57:02 -05:00
parent d9f03d0a2d
commit 9f1ce934e4
5 changed files with 142 additions and 36 deletions

View file

@ -2,47 +2,60 @@
AdafruitVfdDisplay::AdafruitVfdDisplay(UART& lcdUart) : m_lcdUart{lcdUart} {}
void AdafruitVfdDisplay::createChar(uint8_t id, uint8_t* c) {
// todo: prolly doesnt work
uint8_t createChar[] = {0xfe, 0x4e, id};
m_lcdUart.write_raw(createChar, sizeof(createChar));
m_lcdUart.write_raw(c, 8);
}
void AdafruitVfdDisplay::drawBlinker() {
uint8_t blockCursorOn[] = {0xfe, 0x53};
m_lcdUart.write_raw(blockCursorOn, sizeof(blockCursorOn));
}
void AdafruitVfdDisplay::clearBlinker() {
uint8_t blockCursorOff[] = {0xfe, 0x54};
m_lcdUart.write_raw(blockCursorOff, sizeof(blockCursorOff));
}
void AdafruitVfdDisplay::begin() {
delay(500);
clear();
show();
uint8_t noAutoScroll[] = {0xFE, 0x52};
m_lcdUart.write_raw(noAutoScroll, sizeof(noAutoScroll));
}
void AdafruitVfdDisplay::clear() {
uint8_t clearCmd[] = {0xfe, 0x58};
uint8_t clearCmd[] = {0xfe, 0x58, 0xfe, 0x48};
m_lcdUart.write_raw(clearCmd, sizeof(clearCmd));
}
void AdafruitVfdDisplay::show() {
uint8_t dispOn[] = {0xfe, 42};
m_lcdUart.write_raw(dispOn, sizeof(dispOn));
uint8_t brightnessUp[] = {0xfe, 0x99, 100};
m_lcdUart.write_raw(brightnessUp, sizeof(brightnessUp));
}
void AdafruitVfdDisplay::hide() {
uint8_t dispOff[] = {0xfe, 0x46};
m_lcdUart.write_raw(dispOff, sizeof(dispOff));
}
void AdafruitVfdDisplay::draw(uint8_t byte) {
m_lcdUart.write(byte);
}
void AdafruitVfdDisplay::draw(const char* text) {
m_lcdUart.write(text);
}
void AdafruitVfdDisplay::setCursor(uint8_t col, uint8_t row) {
uint8_t setCursorCmd[] = {0xfe, 0x47, col+1, row+1};
m_lcdUart.write_raw(setCursorCmd, sizeof(setCursorCmd));
}
void AdafruitVfdDisplay::setBacklight(bool enabled) {

View file

@ -21,15 +21,24 @@ class AdafruitVfdDisplay : public CharacterDisplayInterface {
void clearBlinker() override;
void begin() override;
void clear() override;
/// @brief turn display on, showing previously displayed text
void show() override;
/// @brief turn display off so text is no longer visible (but still present).
void hide() override;
void draw(uint8_t byte) override;
void draw(const char* text) override;
/// @brief Move display cursor to specified position
/// TODO: 0 based or 1-based col/row position???
/// @param col
/// @param row
void setCursor(uint8_t col, uint8_t row) override;
void setBacklight(bool enabled) override;
private:
UART m_lcdUart;
UART &m_lcdUart;
};
#endif /* __ADAFRUITVFDDISPINTERFACE_H__ */

74
lib/ui/TrainUi.hpp Normal file
View file

@ -0,0 +1,74 @@
/** \File TrainUi.hpp
* \copyright (c) 2025 len0rd
* \date 2025-02-09
*
* Menu and LCD UI/rotary encoder for train controller
*/
#ifndef __TRAINUI_H__
#define __TRAINUI_H__
#include <Arduino.h>
#include <SimpleRotary.h>
#include "AdafruitVfdDisplay.hpp"
#include "LcdMenu.h"
#include "Serial.h"
#include "input/SimpleRotaryAdapter.h"
#include "renderer/CharacterDisplayRenderer.h"
MENU_SCREEN(mainScreen,
mainItems,
ITEM_BASIC("Item Eins"),
ITEM_BASIC("Item Zwei"),
ITEM_BASIC("Item Drei"));
#define ROT_ENC_A_PIN PIN_D6
#define ROT_ENC_B_PIN PIN_D7
#define ROT_ENC_BUTTON_PIN PIN_D8
#define DISP_NUM_ROWS 2
#define DISP_NUM_COLS 16
class TrainUi {
public:
TrainUi()
: m_lcdUart{_UART2_},
m_disp(m_lcdUart),
m_renderer(&m_disp, DISP_NUM_COLS, DISP_NUM_ROWS),
m_menu(m_renderer),
m_rotEnc(ROT_ENC_A_PIN, ROT_ENC_B_PIN, ROT_ENC_BUTTON_PIN),
m_rotaryInput(&m_menu, &m_rotEnc) {}
inline void setup() {
m_lcdUart.begin(57600);
while (!m_lcdUart)
;
// m_disp.show();
// m_disp.clear();
// m_disp.drawBlinker();
m_renderer.begin();
m_menu.setScreen(mainScreen);
}
inline void loop() {
// m_disp.clear();
// // uint8_t clearCmd[] = {0xfe, 0x58, 0xfe, 0x48};
// // m_lcdUart.write_raw(clearCmd, sizeof(clearCmd));
// char toPrint[16] = {};
// snprintf(toPrint, 16, "enc: %d %d", m_rotEnc.rotate(), m_rotEnc.push());
// m_disp.draw(toPrint);
// m_lcdUart.print("howdy do");
m_rotaryInput.observe();
}
private:
UART& m_lcdUart;
AdafruitVfdDisplay m_disp;
CharacterDisplayRenderer m_renderer;
LcdMenu m_menu;
SimpleRotary m_rotEnc;
SimpleRotaryAdapter m_rotaryInput;
};
#endif /* __TRAINUI_H__ */

View file

@ -16,3 +16,4 @@ monitor_speed = 115200
lib_deps =
mathertel/OneButton@^2.6.1
forntoh/LcdMenu@^5.6.0
mprograms/SimpleRotary@^1.1.3

View file

@ -4,6 +4,7 @@
#include "NvmEeprom.hpp"
#include "SingleAxis.hpp"
#include "OneButton.h"
#include "TrainUi.hpp"
// joystick calibration
#define TIME_CAL_1 2000
@ -14,18 +15,22 @@ AlignedJoy joystick_1(PIN_A0, PIN_A1); /// X on A0, Y on A1
ArduinoLEDMatrix ledMatrix;
LinearSingleAxis lever0(PIN_A2);
enum Button : size_t {
RED_BUTTON = 0,
// WHITE_BUTTON,
TrainUi s_ui;
NUM_BUTTONS,
};
UART *uOut = nullptr;
// enum Button : size_t {
// RED_BUTTON = 0,
// // WHITE_BUTTON,
// NUM_BUTTONS,
// };
OneButton s_buttons[Button::NUM_BUTTONS] = {
[Button::RED_BUTTON] = OneButton(PIN_D2, true, false),
// [Button::WHITE_BUTTON] = OneButton(PIN_D3),
};
// OneButton s_buttons[Button::NUM_BUTTONS] = {
// [Button::RED_BUTTON] = OneButton(PIN_D2, true, false),
// // [Button::WHITE_BUTTON] = OneButton(PIN_D3),
// };
static_assert(sizeof(void*) == sizeof(size_t));
@ -154,6 +159,8 @@ void setup() {
Serial.println("Wait for serial connection...");
delay(5000);
s_ui.setup();
// run joystick calibration if needed
// bool calibrationInvalid = !nvm.valid();
// do {
@ -190,28 +197,30 @@ void setup() {
// configure buttons
for (size_t ii = 0; ii < NUM_BUTTONS; ii++) {
s_buttons[ii].attachClick(buttonClickHandler, (void*)ii);
}
// for (size_t ii = 0; ii < NUM_BUTTONS; ii++) {
// s_buttons[ii].attachClick(buttonClickHandler, (void*)ii);
// }
}
int loopCount = 0;
void loop() {
loopCount++;
if (loopCount >= 50) {
loopCount = 0;
// print joystick axes value
Serial.print("joystick_1 X -> ");
Serial.print(joystick_1.read(X));
Serial.print(" | Y -> ");
Serial.println(joystick_1.read(Y));
Serial.print("lever0: ");
Serial.println(lever0.readRaw());
}
for (size_t ii = 0; ii < NUM_BUTTONS; ii++) {
s_buttons[ii].tick();
}
s_ui.loop();
delay(10);
// loopCount++;
// if (loopCount >= 50) {
// loopCount = 0;
// // print joystick axes value
// Serial.print("joystick_1 X -> ");
// Serial.print(joystick_1.read(X));
// Serial.print(" | Y -> ");
// Serial.println(joystick_1.read(Y));
// Serial.print("lever0: ");
// Serial.println(lever0.readRaw());
// }
// for (size_t ii = 0; ii < NUM_BUTTONS; ii++) {
// s_buttons[ii].tick();
// }
// delay(10);
}