renderbug-cpp/src/main.cpp

146 lines
4.3 KiB
C++
Raw Normal View History

2021-03-29 08:10:55 +00:00
#include "Arduino.h"
#include <FastLED.h>
#include <Figments.h>
#include <ArduinoLog.h>
#include "Platform.h"
2021-03-29 08:10:55 +00:00
#include "Static.h"
#include "Config.h"
#include "LogService.h"
2021-03-29 08:10:55 +00:00
#include <time.h>
2021-03-29 08:10:55 +00:00
#include "inputs/ColorCycle.h"
#include "inputs/Buttons.h"
#include "SafeMode.h"
2021-03-29 08:10:55 +00:00
// Setup FastLED and the display
CRGB leds[HardwareConfig::MAX_LED_NUM];
Display dpy(leds, HardwareConfig::MAX_LED_NUM, Static<ConfigService>::instance()->coordMap());
// FIXME: rewrite as static task
/*FigmentFunc configDisplay([](Display* dpy) {
2021-03-29 08:10:55 +00:00
uint8_t brightness = brighten8_video(beatsin8(60));
auto coords = Static<ConfigService>::instance()->coordMap();
for(int i = 0; i < HardwareConfig::MAX_LED_NUM; i++) {
if (i < coords->startPixel || i > coords->startPixel + coords->pixelCount) {
dpy->pixelAt(i) += CRGB(brightness, 0, 0);
} else {
dpy->pixelAt(i) += CRGB(255 - brightness, 255 - brightness, 255 - brightness);
}
}
});*/
2021-03-29 08:10:55 +00:00
InputMapper keyMap([](const InputEvent& evt) {
if (evt.intent == InputEvent::UserInput) {
Buttons::Chord chord = (Buttons::Chord)evt.asInt();
switch(chord) {
case Buttons::Circle:
return InputEvent::PowerToggle;
break;
case Buttons::Triangle:
return InputEvent::NextPattern;
break;
case Buttons::Cross:
return InputEvent::UserInput;
break;
default:
break;
2021-03-29 08:10:55 +00:00
}
}
return InputEvent::None;
}, "Keymap");
REGISTER_TASK(keyMap);
2021-03-29 08:10:55 +00:00
// Cycle some random colors
2021-04-10 18:10:25 +00:00
ColorSequenceInput<9> idleCycle{{
2021-03-29 08:10:55 +00:00
CRGB(0, 123, 167), // Cerulean
CRGB(80, 200, 120), // Emerald
CRGB(207, 113, 175), // Sky Magenta
CRGB(128, 0, 128), // Purple
CRGB(255, 255, 255), // White
CRGB(0, 255, 255), // Cyan
}, "IdleColors"};
REGISTER_TASK(idleCycle);
2021-04-10 18:10:25 +00:00
ColorSequenceInput<7> rainbowCycle{{
CRGB(255, 0, 0), // Red
CRGB(255, 127, 0), // Yellow
CRGB(0, 255, 0), // Green
CRGB(0, 0, 255), // Blue
CRGB(128, 0, 128), // Purple
}, "Rainbow"};
2021-03-29 08:10:55 +00:00
REGISTER_TASK(rainbowCycle);
MainLoop* runner = &SafeMode::safeModeApp;
2021-03-29 08:10:55 +00:00
void setup() {
// Turn on,
Platform::preSetup();
2021-03-29 08:10:55 +00:00
Log.notice(u8"🐛 Booting Renderbug!");
2023-02-19 17:46:43 +00:00
Log.notice(u8"🐞 I am built for %d LEDs on pin %d", HardwareConfig::MAX_LED_NUM, RENDERBUG_LED_PIN);
Log.notice(u8"📡 Platform %s version %s", Platform::name(), Platform::version());
2023-02-19 17:46:43 +00:00
if (Platform::bootopts.crashCount > 0) {
Log.warning(u8"Previous crash detected!!!! We're on attempt %d", Platform::bootopts.crashCount);
2023-03-03 17:33:07 +00:00
char lastTaskBuf[16];
2023-02-19 17:46:43 +00:00
strncpy(lastTaskBuf, MainLoop::lastTaskName(), sizeof(lastTaskBuf));
lastTaskBuf[15] = 0;
Log.error(u8"Crash occurred in task %s", lastTaskBuf);
}
Log.trace("Startup reason: %d", Platform::bootopts.resetReason);
2023-02-18 15:30:00 +00:00
Log.notice(u8"Setting timezone to +2 (CEST)");
Platform::setTimezone(+2);
2023-02-19 17:46:43 +00:00
Log.trace(u8"Setting up platform...");
2021-03-29 08:10:55 +00:00
Platform::setup();
Platform::bootSplash();
2021-03-29 08:10:55 +00:00
2023-12-11 06:51:10 +00:00
Log.notice(u8"💡 Starting FastLED on %d LEDs...", HardwareConfig::MAX_LED_NUM);
Platform::addLEDs(leds, HardwareConfig::MAX_LED_NUM);
2021-03-29 08:10:55 +00:00
// Tune in,
2021-04-10 18:10:25 +00:00
if (Platform::bootopts.isSafeMode) {
2023-12-11 06:51:10 +00:00
Log.warning(u8"⚠️ Starting Figment in safe mode!!!");
runner = &SafeMode::safeModeApp;
2021-04-10 18:10:25 +00:00
FastLED.showColor(CRGB(5, 0, 0));
FastLED.show();
2021-03-29 08:10:55 +00:00
} else {
Log.notice(u8"🌌 Starting Figment...");
if (Platform::bootopts.isSetup) {
2023-02-19 17:46:43 +00:00
Log.warning(u8"🔧 Booting up into setup profile!!!");
Static<ConfigService>::instance()->overrideProfile("setup");
}
// Render all layers to the displays
Renderer* renderer = new Renderer({&dpy}, std::vector<Figment*>{Platform::beginFigments(), Platform::endFigments()});
std::vector<Task*> defaultTasks{Platform::beginTasks(), Platform::endTasks()};
defaultTasks.push_back(renderer);
runner = new MainLoop{std::vector<Task*>{defaultTasks.begin(), defaultTasks.end()}};
2021-03-29 08:10:55 +00:00
}
Serial.flush();
runner->start();
2021-03-29 08:10:55 +00:00
2023-12-11 06:51:10 +00:00
Log.notice(u8"💽 %l bytes of free RAM", Platform::freeRam());
2021-03-29 08:10:55 +00:00
Log.notice(u8"🚀 Setup complete! Ready to rock and roll.");
Serial.flush();
}
// Drop out.
void loop() {
EVERY_N_SECONDS(5) {
2023-02-18 15:16:35 +00:00
Log.notice("FPS: %d\tRAM: %d", FastLED.getFPS(), Platform::freeRam());
}
runner->loop();
2021-03-29 08:10:55 +00:00
}