port to platformio

This commit is contained in:
2021-03-29 01:10:55 -07:00
parent 9a3bf84214
commit a6534bcb20
131 changed files with 1537 additions and 1148 deletions

37
src/inputs/Buttons.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "./Buttons.h"
void
Buttons::onStart()
{
for(int i = 0; i < 3; i++) {
//Log.info("Bound pin %d to button %d", 2 + i, i);
m_buttons[i].attach(2 + i, INPUT_PULLDOWN);
m_buttons[i].interval(15);
}
}
InputEvent
Buttons::read()
{
for(int i = 0; i < 3; i++) {
m_buttons[i].update();
if (m_buttons[i].rose()) {
//Log.info("Read press on %d", i);
int buttonID = m_buttonMap[i];
for(int j = 0; j < 3; j++ ) {
if (j != i && m_buttons[j].held()) {
buttonID |= m_buttonMap[j];
//Log.info("Chord with %d", j);
m_wasChord[j] = true;
}
}
if (m_wasChord[i]) {
//Log.info("Not emitting release from previous chord");
m_wasChord[i] = false;
} else {
return InputEvent{InputEvent::UserInput, buttonID};
}
}
}
return InputEvent{};
}

94
src/inputs/Buttons.h Normal file
View File

@@ -0,0 +1,94 @@
#pragma once
#include <Input.h>
class Bounce {
public:
void attach(int pin, int buttonPinMode) {
m_pin = pin;
pinMode(m_pin, buttonPinMode);
//Log.info("Attaching a button to %d", pin);
}
void update() {
int readResult = digitalRead(m_pin);
if (m_state == Ready) {
if (readResult == HIGH) {
m_state = Started;
m_downStart = millis();
//Log.info("Button %d is started!", m_pin);
}
} else if (m_state == Started && millis() - m_downStart >= m_interval) {
if (readResult == HIGH) {
m_state = Confirmed;
//Log.info("Button %d is CONFIRMED!", m_pin);
} else {
m_state = Ready;
//Log.info("Button %d bounced back to ready!", m_pin);
}
} else if (m_state == Confirmed || m_state == Held) {
if (readResult == LOW) {
//Log.info("Button %d is released", m_pin);
m_state = Released;
} else if (m_state == Confirmed) {
m_state = Held;
//Log.info("Button %d is being held down!", m_pin);
}
} else if (m_state == Released) {
//Log.info("Button %d is ready!", m_pin);
m_state = Ready;
}
}
void interval(uint8_t v) {
m_interval = v;
}
bool fell() const {
return m_state == Confirmed;
}
bool rose() const {
return m_state == Released;
}
bool held() const {
return m_state == Held;
}
private:
enum State {
Ready,
Started,
Confirmed,
Held,
Released
};
State m_state = Ready;
unsigned int m_pin = 0;
unsigned int m_downStart = 0;
unsigned int m_interval = 10;
};
class Buttons: public InputSource {
public:
Buttons() : InputSource("Buttons") {}
void onStart() override;
InputEvent read() override;
enum Chord {
None = 0,
Circle = 1,
Triangle = 2,
Cross = 4,
CircleTriangle = Circle | Triangle,
CircleCross = Circle | Cross,
TriangleCross = Triangle | Cross,
CircleTriangleCross = Circle | Triangle | Cross
};
private:
Bounce m_buttons[3];
Chord m_buttonMap[3] = {Circle, Triangle, Cross};
bool m_wasChord[3] = {false, false, false};
};

View File

32
src/inputs/ColorCycle.h Normal file
View File

@@ -0,0 +1,32 @@
#include <Figments.h>
#include <ArduinoLog.h>
template<int Period>
class ColorSequenceInput: public InputSource {
public:
ColorSequenceInput(const std::vector<CRGB> &colors, const char* name, Task::State initialState)
: InputSource(name, initialState), m_colors(colors) {}
InputEvent read() override {
EVERY_N_SECONDS(Period) {
m_idx %= m_colors.size();
m_reset = true;
m_idx++;
}
if (m_reset) {
m_reset = false;
Log.notice("Cycling %s color to %d [%d, %d, %d]", name, m_idx, m_colors[m_idx].r, m_colors[m_idx].g, m_colors[m_idx].b);
return InputEvent{InputEvent::SetColor, m_colors[m_idx]};
}
return InputEvent{};
}
void onStart() override {
m_reset = true;
}
private:
std::vector<CRGB> m_colors;
unsigned int m_idx = 0;
bool m_reset = true;
};

79
src/inputs/DMX.cpp Normal file
View File

@@ -0,0 +1,79 @@
#if 0
#include "Particle.h"
#include "../Input.h"
#include "../colors.h"
#include "../Static.h"
volatile uint8_t DmxRxField[8];
volatile uint16_t DmxAddress;
enum { IDLE, BREAK, STARTB, STARTADR };
volatile uint8_t gDmxState;
class DMXInput: public InputSource {
public:
void init() {
UCSR1B = (1<<RXEN1) | (1<<RXCE1);
Serial1.begin(250000, SERIAL_8N2);
}
static void handleInterrupt() {
static uint16_t DmxCount;
uint8_t USARTstate = UCSR1A;
uint8_t DmxByte = UDR1;
uint8_t DmxState = gDmxState;
if (USARTstate &(1<<FE1)) {
DmxCount = DmxAddress;
gDmxState = BREAK;
} else if (DmxState == BREAK) {
if (DmxByte == 0) {
gDmxState = STARTB;
} else {
gDmxState = IDLE;
}
} else if (DmxState == STARTB) {
if (--DmxCount == 0) {
DmxCount = 1;
DmxRxField[0] = DmxByte;
gDmxState = STARTADR;
}
} else if (DmxState == STARTADR) {
DmxRxField[DmxCount++] = DmxByte;
if (DmxCount >= sizeof(DmxRxField)) {
gDmxState = IDLE;
}
}
}
virtual void update() override {
bool hasUpdate = false;
if (gDmxState == IDLE) {
for(int i = 0; i < 8; i++) {
if (m_lastReadFields[i] != DmxRxField[i]) {
hasUpdate = true;
m_lastReadFields[i] = DmxRxField[i];
}
}
}
if (hasUpdate) {
m_lastReadEvent = InputEvent(InputEvent::SetColor, {m_lastReadFields[0], m_lastReadFields[1], m_lastReadFields[2]});
}
m_lastEvent = m_lastReadEvent;
m_lastReadEvent = InputEvent();
}
virtual InputEvent read() const override {
return m_lastEvent;
}
private:
InputEvent m_lastEvent;
InputEvent m_lastReadEvent;
uint8_t m_lastReadFields[8];
};
ISR(USART1_RX_vect) {
DMXInput::handleInterrupt();
}
#endif

0
src/inputs/MPU6050.cpp Normal file
View File

97
src/inputs/MPU6050.h Normal file
View File

@@ -0,0 +1,97 @@
#include <Wire.h>
class MPU5060: public InputSource {
const int ACCEL_XOUT_HIGH = 0x3B;
const int ACCEL_XOUT_LOW = 0x3C;
const int ACCEL_YOUT_HIGH = 0x3D;
const int ACCEL_YOUT_LOW = 0x3E;
const int ACCEL_ZOUT_HIGH = 0x3F;
const int ACCEL_ZOUT_LOW = 0x40;
const int I2C_ADDRESS = 0x68;
const int PWR_MGMT_1 = 0x6B;
const int CONFIG_REG = 0x1A;
const int ACCEL_CONFIG_REG = 0x1C;
public:
MPU5060() : InputSource("MPU5060", HardwareConfig::HAS_MPU_6050 ? Task::Running : Task::Stopped) {}
void onStart() override {
Wire.begin();
// Turn on the sensor
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(PWR_MGMT_1);
Wire.write(0);
Wire.endTransmission(true);
// Configure the filter
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(CONFIG_REG);
Wire.write(3);
Wire.endTransmission(true);
// Configure the accel range
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(ACCEL_CONFIG_REG);
// 4G
Wire.write(2 << 3);
Wire.endTransmission(true);
}
void onStop() override {
Wire.beginTransmission(I2C_ADDRESS);
// Turn off the sensor
Wire.write(PWR_MGMT_1);
Wire.write(1);
Wire.endTransmission(true);
//Wire.end();
}
InputEvent read() override {
EVERY_N_MILLISECONDS(5) {
Wire.beginTransmission(I2C_ADDRESS);
Wire.write(ACCEL_XOUT_HIGH);
Wire.endTransmission(false);
Wire.requestFrom(I2C_ADDRESS, 6);
const int16_t accelX = Wire.read() << 8 | Wire.read();
const int16_t accelY = Wire.read() << 8 | Wire.read();
const int16_t accelZ = Wire.read() << 8 | Wire.read();
const uint16_t accelSum = abs(accelX) + abs(accelY) + abs(accelZ);
const uint16_t delta = abs(m_value.value() - accelSum);
m_value.add(accelSum);
if (delta > 32) {
return InputEvent{InputEvent::Acceleration, delta};
}
}
return InputEvent{};
}
template<typename T, uint8_t Size = 8>
struct Averager {
std::array<T, Size> buf;
unsigned int idx = 0;
unsigned int count = 0;
void add(const T &value) {
buf[idx] = value;
idx = (idx + 1) % Size;
if (count < Size) {
count += 1;
}
}
T value() const {
if (count == 0) {
return T{};
}
long long int sum = 0;
for(unsigned int i = 0; i < count; i++) {
sum += buf[i];
}
return sum / count;
}
};
Averager<int16_t, 32> m_value;
};

12
src/inputs/Serial.h Normal file
View File

@@ -0,0 +1,12 @@
#include "Particle.h"
#include "../Figments/Figments.h"
class SerialInput: public InputSource {
public:
void onAttach() override {
//Serial.begin();
}
InputEvent read() {
}
}