diff --git a/lib/matrix_orbital/AdafruitVfdDisplay.cpp b/lib/matrix_orbital/AdafruitVfdDisplay.cpp new file mode 100644 index 0000000..396a518 --- /dev/null +++ b/lib/matrix_orbital/AdafruitVfdDisplay.cpp @@ -0,0 +1,51 @@ +#include "AdafruitVfdDisplay.hpp" + +AdafruitVfdDisplay::AdafruitVfdDisplay(UART& lcdUart) : m_lcdUart{lcdUart} {} + + +void AdafruitVfdDisplay::createChar(uint8_t id, uint8_t* c) { + +} + +void AdafruitVfdDisplay::drawBlinker() { + +} + +void AdafruitVfdDisplay::clearBlinker() { + +} + +void AdafruitVfdDisplay::begin() { + delay(500); + clear(); +} + +void AdafruitVfdDisplay::clear() { + uint8_t clearCmd[] = {0xfe, 0x58}; + m_lcdUart.write_raw(clearCmd, sizeof(clearCmd)); +} + +void AdafruitVfdDisplay::show() { + +} + +void AdafruitVfdDisplay::hide() { + +} + +void AdafruitVfdDisplay::draw(uint8_t byte) { + +} + +void AdafruitVfdDisplay::draw(const char* text) { + +} + +void AdafruitVfdDisplay::setCursor(uint8_t col, uint8_t row) { + +} + +void AdafruitVfdDisplay::setBacklight(bool enabled) { + uint8_t backlightCmd[] = {0xfe, 0x99, enabled ? 150 : 50}; + m_lcdUart.write_raw(backlightCmd, sizeof(backlightCmd)); +} diff --git a/lib/matrix_orbital/AdafruitVfdDisplay.hpp b/lib/matrix_orbital/AdafruitVfdDisplay.hpp new file mode 100644 index 0000000..2509145 --- /dev/null +++ b/lib/matrix_orbital/AdafruitVfdDisplay.hpp @@ -0,0 +1,35 @@ +/** + * + * Implementation of LcdMenu::CharacterDisplayInterface + * For the Adafruit Character LCD Serial backpack. Which per their docs + * has a similar interface to the "Matrix Orbital Specification" + * @see https://learn.adafruit.com/usb-plus-serial-backpack/command-reference + */ +#ifndef __ADAFRUITVFDDISPINTERFACE_H__ +#define __ADAFRUITVFDDISPINTERFACE_H__ + +#include + +class AdafruitVfdDisplay : public CharacterDisplayInterface { + public: + AdafruitVfdDisplay(UART& lcdUart); + + // interface implementations + + void createChar(uint8_t id, uint8_t* c) override; + void drawBlinker() override; + void clearBlinker() override; + void begin() override; + void clear() override; + void show() override; + void hide() override; + void draw(uint8_t byte) override; + void draw(const char* text) override; + void setCursor(uint8_t col, uint8_t row) override; + void setBacklight(bool enabled) override; + + private: + UART m_lcdUart; +}; + +#endif /* __ADAFRUITVFDDISPINTERFACE_H__ */ diff --git a/platformio.ini b/platformio.ini index 7fd5129..5dcfbf9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,3 +12,7 @@ platform = renesas-ra board = uno_r4_wifi framework = arduino +monitor_speed = 115200 +lib_deps = + mathertel/OneButton@^2.6.1 + forntoh/LcdMenu@^5.6.0 diff --git a/src/main.cpp b/src/main.cpp index 30c7b7c..6a6bfa0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,15 +3,41 @@ #include "Arduino_LED_Matrix.h" #include "NvmEeprom.hpp" #include "SingleAxis.hpp" +#include "OneButton.h" // joystick calibration #define TIME_CAL_1 2000 #define TIME_CAL_2 3000 // static objects -AlignedJoy joystick_1(0, 1); /// X on A0, Y on A1 +AlignedJoy joystick_1(PIN_A0, PIN_A1); /// X on A0, Y on A1 ArduinoLEDMatrix ledMatrix; -LinearSingleAxis lever0(2); +LinearSingleAxis lever0(PIN_A2); + +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), +}; + + +static_assert(sizeof(void*) == sizeof(size_t)); +void buttonClickHandler(void* ctx) { + // void* theButton = ctx; + + Serial.println("Clicky clack"); + + // char buf[64] = {}; + // snprintf(buf, 64, "Button %u pressed!", theButton); + // Serial.println(buf); +} /// Run calibration on the provided joystick. Save the results to the provided calibration bool runJoystickCalibrationRoutine(AlignedJoy& joy, JoystickCalibration& cal) { @@ -80,7 +106,7 @@ bool runJoystickCalibrationRoutine(AlignedJoy& joy, JoystickCalibration& cal) { Serial.print(joy.getCalibratedPoint(X, MID)); Serial.print(" | max -> "); Serial.println(joy.getCalibratedPoint(X, MAX)); - Serial.print("Y min -> "); + Serial.print(" Y min -> "); Serial.print(joy.getCalibratedPoint(Y, MIN)); Serial.print(" | center -> "); Serial.print(joy.getCalibratedPoint(Y, MID)); @@ -116,7 +142,7 @@ bool runLeverCalibration(LinearSingleAxis& lever, LinearAnalogCalibration& cal) void setup() { // SERIAL INITIALIZE Serial.begin(115200); - ledMatrix.loadSequence(LEDMATRIX_ANIMATION_STARTUP); + ledMatrix.loadSequence(LEDMATRIX_ANIMATION_HEARTBEAT_LINE); ledMatrix.begin(); while (!Serial) { } @@ -125,47 +151,67 @@ void setup() { // retrieve current calibration values NonVolatileMemory nvm = {}; readNvm(nvm); + Serial.println("Wait for serial connection..."); + delay(5000); // run joystick calibration if needed - bool calibrationInvalid = !nvm.valid(); - do { - calibrationInvalid |= - !nvm.calData.joystickCal.x.valid() || !nvm.calData.joystickCal.y.valid(); - if (calibrationInvalid) { - Serial.println("Joystick1 calibration required\n========================"); - calibrationInvalid |= - !runJoystickCalibrationRoutine(joystick_1, nvm.calData.joystickCal); - } - } while (calibrationInvalid); - // ensure calibration has been applied - // TODO: API doesnt allow setting configured midpoint... - joystick_1.setCalibratedPoint(axis_t::X, point_t::MIN, nvm.calData.joystickCal.x.min); - joystick_1.setCalibratedPoint(axis_t::X, point_t::MID, nvm.calData.joystickCal.x.mid); - joystick_1.setCalibratedPoint(axis_t::X, point_t::MAX, nvm.calData.joystickCal.x.max); - joystick_1.setCalibratedPoint(axis_t::Y, point_t::MIN, nvm.calData.joystickCal.y.min); - joystick_1.setCalibratedPoint(axis_t::Y, point_t::MID, nvm.calData.joystickCal.y.mid); - joystick_1.setCalibratedPoint(axis_t::Y, point_t::MAX, nvm.calData.joystickCal.y.max); + // bool calibrationInvalid = !nvm.valid(); + // do { + // calibrationInvalid |= + // !nvm.calData.joystickCal.x.valid() || !nvm.calData.joystickCal.y.valid(); + // if (calibrationInvalid) { + // Serial.println("Joystick1 calibration required\n========================"); + // calibrationInvalid = + // !runJoystickCalibrationRoutine(joystick_1, nvm.calData.joystickCal); + // } + // } while (calibrationInvalid); + // // ensure calibration has been applied + // // TODO: API doesnt allow setting configured midpoint... + // joystick_1.setCalibratedPoint(axis_t::X, point_t::MIN, nvm.calData.joystickCal.x.min); + // joystick_1.setCalibratedPoint(axis_t::X, point_t::MID, nvm.calData.joystickCal.x.mid); + // joystick_1.setCalibratedPoint(axis_t::X, point_t::MAX, nvm.calData.joystickCal.x.max); + // joystick_1.setCalibratedPoint(axis_t::Y, point_t::MIN, nvm.calData.joystickCal.y.min); + // joystick_1.setCalibratedPoint(axis_t::Y, point_t::MID, nvm.calData.joystickCal.y.mid); + // joystick_1.setCalibratedPoint(axis_t::Y, point_t::MAX, nvm.calData.joystickCal.y.max); - // run analog lever calibration if needed - calibrationInvalid = !nvm.valid(); - do { - calibrationInvalid |= !nvm.calData.lever0.valid(); - if (calibrationInvalid) { - Serial.println("Lever0 calibration required\n==========================="); - calibrationInvalid |= runLeverCalibration(lever0, nvm.calData.lever0); - } - } while (calibrationInvalid); - lever0.applyCalibration(nvm.calData.lever0); + // // run analog lever calibration if needed + // calibrationInvalid = !nvm.valid(); + // do { + // calibrationInvalid |= !nvm.calData.lever0.valid(); + // if (calibrationInvalid) { + // Serial.println("Lever0 calibration required\n==========================="); + // calibrationInvalid = !runLeverCalibration(lever0, nvm.calData.lever0); + // } + // } while (calibrationInvalid); + // lever0.applyCalibration(nvm.calData.lever0); + + // // write NVM in the event any values were updated + // writeNvm(nvm); + + + // configure buttons + for (size_t ii = 0; ii < NUM_BUTTONS; ii++) { + s_buttons[ii].attachClick(buttonClickHandler, (void*)ii); + } - // write NVM in the event any values were updated - writeNvm(nvm); } +int loopCount = 0; + void loop() { - // print joystick axes value - Serial.print("joystick_1 X -> "); - Serial.print(joystick_1.read(X)); - Serial.print(" | Y -> "); - Serial.println(joystick_1.read(Y)); - delay(500); + 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); }