If the code hasn't been touched in this long, its probably release-worthy.
This commit is contained in:
232
src/platform/arduino/U8Display.cpp
Normal file
232
src/platform/arduino/U8Display.cpp
Normal file
@@ -0,0 +1,232 @@
|
||||
#include <Figments.h>
|
||||
#include <U8g2lib.h>
|
||||
#include "../../Static.h"
|
||||
#include <ArduinoLog.h>
|
||||
#include "../../LogService.h"
|
||||
|
||||
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, 16, 15, 4);
|
||||
|
||||
class U8Display : public Task {
|
||||
public:
|
||||
U8Display() : Task("U8Display") {}
|
||||
|
||||
enum ScreenState {
|
||||
BootSplash,
|
||||
Running,
|
||||
Message,
|
||||
Idle = Running
|
||||
};
|
||||
|
||||
void onStart() {
|
||||
xTaskCreatePinnedToCore(
|
||||
&U8Display::redrawTask,
|
||||
name,
|
||||
2000,
|
||||
this,
|
||||
1,
|
||||
&m_renderTask, 0
|
||||
);
|
||||
}
|
||||
|
||||
void handleEvent(const InputEvent& evt) {
|
||||
m_lastEvent = evt;
|
||||
if (m_state == Idle) {
|
||||
switch(evt.intent) {
|
||||
case InputEvent::NetworkStatus:
|
||||
m_nextState = Message;
|
||||
m_message = evt.asBool() ? "Online!" : "Offline :[";
|
||||
break;
|
||||
case InputEvent::SetPattern:
|
||||
m_nextState = Message;
|
||||
m_message = "Pattern: " + String(evt.asString());
|
||||
break;
|
||||
case InputEvent::SetPower:
|
||||
m_nextState = Message;
|
||||
m_message = evt.asBool() ? "Power On" : "Power Off";
|
||||
break;
|
||||
case InputEvent::SaveConfigurationRequest:
|
||||
m_nextState = Message;
|
||||
m_message = "Settings Saved!";
|
||||
break;
|
||||
case InputEvent::FirmwareUpdate:
|
||||
m_nextState = Message;
|
||||
m_message = "Firmware update";
|
||||
break;
|
||||
case InputEvent::PreviousPattern:
|
||||
m_nextState = Message;
|
||||
m_message = "Previous Pattern";
|
||||
break;
|
||||
case InputEvent::NextPattern:
|
||||
m_nextState = Message;
|
||||
m_message = "Next Pattern";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawSplash() {
|
||||
//u8g2.setFont(u8g2_font_VCR_OSD_mr);
|
||||
u8g2.setFont(u8g2_font_HelvetiPixelOutline_tr);
|
||||
u8g2.setDrawColor(1);
|
||||
uint8_t splashWidth = u8g2.getStrWidth("Renderbug!");
|
||||
u8g2.drawStr(64 - splashWidth / 2, 32 - 15, "Renderbug!");
|
||||
u8g2.setFont(u8g2_font_7x13B_mr);
|
||||
u8g2.setCursor(15, 64 - 7);
|
||||
u8g2.print("Version ");
|
||||
u8g2.print(RENDERBUG_VERSION);
|
||||
|
||||
for(int i = 0; i < 3; i++) {
|
||||
uint8_t sparkleX = (64 - splashWidth/2) + scale8(7-i, beatsin8(40)) * (splashWidth/7) + 5;
|
||||
uint8_t sparkleY = scale8(3+i, beatsin8(40)) * 3 + 7;
|
||||
u8g2.setDrawColor(2);
|
||||
if (beatsin8(60*4) + i * 3 >= 170) {
|
||||
u8g2.drawLine(sparkleX - 3, sparkleY - 3, sparkleX + 3, sparkleY + 3);
|
||||
u8g2.drawLine(sparkleX + 3, sparkleY - 3, sparkleX - 3, sparkleY + 3);
|
||||
} else if (beatsin8(60*4) + i * 2 >= 82) {
|
||||
u8g2.drawLine(sparkleX - 4, sparkleY - 4, sparkleX + 2, sparkleY + 2);
|
||||
u8g2.drawLine(sparkleX - 2, sparkleY - 2, sparkleX + 4, sparkleY + 4);
|
||||
u8g2.drawLine(sparkleX + 4, sparkleY - 4, sparkleX - 2, sparkleY + 2);
|
||||
u8g2.drawLine(sparkleX + 2, sparkleY - 2, sparkleX - 4, sparkleY + 4);
|
||||
} else {
|
||||
u8g2.drawLine(sparkleX - 2, sparkleY, sparkleX + 2, sparkleY);
|
||||
u8g2.drawLine(sparkleX, sparkleY - 2, sparkleX, sparkleY + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawMessage() {
|
||||
//u8g2.setFont(u8g2_font_VCR_OSD_mr);
|
||||
u8g2.setFont(u8g2_font_HelvetiPixelOutline_tr);
|
||||
uint8_t splashWidth = u8g2.getStrWidth(m_message.c_str());
|
||||
if (splashWidth >= 128) {
|
||||
u8g2.setFont(u8g2_font_7x13B_mr);
|
||||
splashWidth = u8g2.getStrWidth(m_message.c_str());
|
||||
}
|
||||
u8g2.drawStr(64 - splashWidth / 2, 32 - 15, m_message.c_str());
|
||||
}
|
||||
|
||||
void drawTime() {
|
||||
u8g2.setFont(u8g2_font_7x13O_tn);
|
||||
u8g2.setCursor(0, 64);
|
||||
struct tm timeinfo;
|
||||
Platform::getLocalTime(&timeinfo);
|
||||
uint8_t hour = timeinfo.tm_hour;
|
||||
uint8_t minute = timeinfo.tm_min;
|
||||
u8g2.print(hour);
|
||||
u8g2.print(":");
|
||||
u8g2.print(minute);
|
||||
}
|
||||
|
||||
void drawState(ScreenState state) {
|
||||
switch(state) {
|
||||
case BootSplash:
|
||||
drawSplash();
|
||||
break;
|
||||
case Message:
|
||||
drawMessage();
|
||||
break;
|
||||
case Running:
|
||||
uint8_t y = 11;
|
||||
u8g2.setFont(u8g2_font_7x13B_mr);
|
||||
u8g2.setCursor(0, y);
|
||||
u8g2.print("FPS: ");
|
||||
u8g2.setFont(u8g2_font_7x13O_tn);
|
||||
u8g2.print(FastLED.getFPS());
|
||||
y += 12;
|
||||
u8g2.setCursor(0, y);
|
||||
u8g2.setFont(u8g2_font_7x13B_mr);
|
||||
u8g2.print("Last event: ");
|
||||
y += 7;
|
||||
u8g2.setCursor(10, y);
|
||||
u8g2.setFont(u8g2_font_4x6_tr);
|
||||
const char* intentName = LogService::intentName(m_lastEvent.intent);
|
||||
if (intentName) {
|
||||
u8g2.print(intentName);
|
||||
} else {
|
||||
u8g2.print("<");
|
||||
u8g2.print(m_lastEvent.intent);
|
||||
u8g2.print(">");
|
||||
}
|
||||
y += 12;
|
||||
u8g2.setCursor(15, y);
|
||||
u8g2.setFont(u8g2_font_7x13O_tf);
|
||||
u8g2.print(LogService::eventValue(m_lastEvent));
|
||||
drawTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
EVERY_N_MILLISECONDS(8) {
|
||||
xTaskNotifyGive(m_renderTask);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ScreenState m_state = BootSplash;
|
||||
ScreenState m_nextState = BootSplash;
|
||||
uint8_t m_transitionFrame = 0;
|
||||
uint8_t m_screenStartTime = 0;
|
||||
InputEvent m_lastEvent;
|
||||
String m_message;
|
||||
|
||||
TaskHandle_t m_renderTask;
|
||||
void redraw() {
|
||||
if (m_state != m_nextState) {
|
||||
EVERY_N_MILLISECONDS(8) {
|
||||
constexpr uint8_t speed = 11;
|
||||
if (m_transitionFrame <= 255 - speed) {
|
||||
m_transitionFrame += speed;
|
||||
} else {
|
||||
m_transitionFrame = 255;
|
||||
}
|
||||
uint8_t offset = ease8InOutApprox(m_transitionFrame);
|
||||
u8g2.clearBuffer();
|
||||
if (m_transitionFrame <= 128) {
|
||||
uint8_t width = scale8(128, offset * 2);
|
||||
u8g2.setDrawColor(1);
|
||||
drawState(m_state);
|
||||
u8g2.drawBox(0, 0, width, 64);
|
||||
u8g2.setDrawColor(2);
|
||||
u8g2.drawBox(width, 0, 8, 64);
|
||||
} else {
|
||||
uint8_t width = scale8(128, offset/2)*2;
|
||||
u8g2.setDrawColor(1);
|
||||
drawState(m_nextState);
|
||||
u8g2.setDrawColor(2);
|
||||
u8g2.drawBox(std::max(0, width - 8), 0, 8, 64);
|
||||
u8g2.setDrawColor(1);
|
||||
u8g2.drawBox(width, 0, 128, 64);
|
||||
}
|
||||
u8g2.sendBuffer();
|
||||
|
||||
if (m_transitionFrame == 255) {
|
||||
m_state = m_nextState;
|
||||
m_screenStartTime = millis();
|
||||
m_transitionFrame = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
u8g2.clearBuffer();
|
||||
drawState(m_state);
|
||||
u8g2.sendBuffer();
|
||||
uint16_t screenTime = millis() - m_screenStartTime;
|
||||
if (screenTime >= 7000 && m_state != Idle) {
|
||||
m_nextState = Idle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void redrawTask(void* data) {
|
||||
u8g2.begin();
|
||||
U8Display* self = static_cast<U8Display*>(data);
|
||||
self->m_screenStartTime = millis();
|
||||
while (true) {
|
||||
self->redraw();
|
||||
ulTaskNotifyTake(0, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
STATIC_ALLOC(U8Display);
|
||||
STATIC_TASK(U8Display);
|
Reference in New Issue
Block a user