serial_debugger/serial_debugger.ino

173 lines
4.7 KiB
C++

// Varous system includes
#include <Arduino.h>
// Various library includes
#include <Adafruit_NeoPixel.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <BBQ10Keyboard.h>
#include <CircularBuffer.h>
// Debugging via serial monitor (don't turn this on unless you're hacking on the firmware code)
#define DEBUG true
// Battery level measurement
#define VBATPIN A6
float measuredVBat;
float batteryPercent;
// TFT Setup
#define TFT_CS 9
#define TFT_DC 10
Adafruit_ILI9341 tft(TFT_CS, TFT_DC);
#include <Fonts/FreeMono9pt7b.h>
#define CHARS_HORIZONTAL 28
#define CHARS_ROWS 13
CircularBuffer<char,364> textBuffer;
// Keyboard
BBQ10Keyboard keyboard;
#define KBD_BTN_1 0x06
#define KBD_BTN_2 0x11
#define KBD_BTN_3 0x07
#define KBD_BTN_4 0x12
#define KBD_SW_UP 0x01
#define KBD_SW_DN 0x02
#define KBD_SW_LF 0x03
#define KBD_SW_RT 0x04
#define KBD_SW_OK 0x05
// NeoPixels
#define PIXELS_NUM_BOARD 1
#define PIXELS_NUM_WING 1
#define PIXELS_WING_PIN 11
Adafruit_NeoPixel pixels_board(PIXELS_NUM_BOARD, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels_wing(PIXELS_NUM_WING, PIXELS_WING_PIN, NEO_GRB + NEO_KHZ800);
// Various loop handlers
void handlerKeyboard();
void handlerBatteryLevel();
// UI screens
void screenClear();
// Color conversion (RGB888 -> RGB565 used by Adafruit GFX)
uint16_t RGB565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3);
}
// Various things that need to be setup via the Arduino standard methods
void setup() {
// Setup red LED to indicate device is on (in case we disable NeoPixel battery level later)
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
// Setup NeoPixels
pixels_board.begin();
pixels_wing.begin();
pixels_board.clear();
pixels_wing.clear();
pixels_board.setBrightness(10);
pixels_wing.setBrightness(5);
// Start with blank wing indicator
pixels_wing.show();
// Green : pixels.Color(0, 255, 0)
// Yellow : pixels.Color(255, 255, 0)
// Orange : pixels.Color(255, 128, 0)
// Red : pixels.Color(255, 0, 0)
pixels_board.setPixelColor(0, pixels_board.Color(0, 0, 255));
pixels_board.show();
// Setup TFT
tft.begin();
tft.setRotation(1);
screenClear();
tft.println("");
tft.setFont(&FreeMono9pt7b);
// Setup BBQ10Keyboard
Wire.begin();
keyboard.begin();
keyboard.setBacklight(0.5f);
}
// Main program via the Arduino standard methods
void loop() {
// Handle keyboard events
handlerKeyboard();
// Update battery level as appropriate
handlerBatteryLevel();
}
void handlerKeyboard() {
// Check if keys were pressed
if (keyboard.keyCount()) {
// Get keyboard event
const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent();
char output[28];
snprintf(output, 28, "key: '%c' (dec %d, hex %02x)", key.key, key.key, key.key);
for (int i=0; i<sizeof(output); i++) {
char toPush = output[i];
if (toPush != '\0') {
textBuffer.push(toPush);
}
else if (toPush == '\0') {
textBuffer.push('\n');
break;
}
}
screenClear();
for (int i=0; i<textBuffer.size(); i++) {
tft.print(textBuffer[i]);
}
// Pick color for signaling a key was pressed (short or long press)
uint32_t keyboard_pixel_color = pixels_wing.Color(0, 0, 255);
if (key.state == BBQ10Keyboard::StateLongPress) {
keyboard_pixel_color = pixels_wing.Color(0, 255, 255);
}
// Display indicator accordingly
if (key.state == BBQ10Keyboard::StatePress || key.state == BBQ10Keyboard::StateLongPress) {
pixels_wing.setPixelColor(0, keyboard_pixel_color);
pixels_wing.show();
}
else {
pixels_wing.clear();
pixels_wing.show();
}
}
}
// Measure battery level and change NeoPixel accordingly
void handlerBatteryLevel() {
measuredVBat = analogRead(VBATPIN);
measuredVBat *= 2; // we divided by 2, so multiply back
measuredVBat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredVBat /= 1024; // convert to voltage
batteryPercent = measuredVBat / 3.3;
if (batteryPercent >= 0.75) {
pixels_board.setPixelColor(0, pixels_board.Color(0, 255, 0));
}
else if (batteryPercent >= 0.50) {
pixels_board.setPixelColor(0, pixels_board.Color(255, 255, 0));
}
else if (batteryPercent >= 0.25) {
pixels_board.setPixelColor(0, pixels_board.Color(255, 128, 0));
}
else {
pixels_board.setPixelColor(0, pixels_board.Color(255, 0, 0));
}
pixels_board.show();
}
// Clear the screen
void screenClear() {
tft.setCursor(0, 0);
tft.fillScreen(RGB565(0, 0, 0));
}