added led support

This commit is contained in:
Jelmer
2023-03-22 14:31:26 +01:00
parent add3d568a4
commit 5bc988c90e
13 changed files with 386 additions and 57 deletions

5
esp32_fw/include/leds.h Normal file
View File

@@ -0,0 +1,5 @@
#include <Arduino.h>
#include <FastLED.h>
void ledTask(void* parameter);
void shortBlink(CRGB cname);

View File

@@ -0,0 +1,5 @@
#include <Arduino.h>
void doLeds();
void rampTagPower(uint8_t pin, bool up);

View File

@@ -17,9 +17,9 @@
#define FLASHER_AP_MISO 6
#define FLASHER_AP_RESET 15
#define FLASHER_AP_POWER 0
#define FLASHER_AP_TXD 17
#define FLASHER_AP_TXD 16
#define FLASHER_AP_RXD 18
#define FLASHER_AP_TEST 16
#define FLASHER_AP_TEST 17
#define FLASHER_EXT_SS 40
#define FLASHER_EXT_CLK 41
@@ -27,9 +27,22 @@
#define FLASHER_EXT_MISO 42
#define FLASHER_EXT_RESET 1
#define FLASHER_EXT_POWER 8
#define FLASHER_EXT_TXD 47
#define FLASHER_EXT_TXD 38
#define FLASHER_EXT_RXD 39
#define FLASHER_EXT_TEST 38
#define FLASHER_EXT_TEST 47
#define FLASHER_ALT_SS 3
#define FLASHER_ALT_CLK 46
#define FLASHER_ALT_MOSI 10
#define FLASHER_ALT_MISO 9
#define FLASHER_ALT_RESET 11
#define FLASHER_ALT_TXD 12
#define FLASHER_ALT_RXD 14
#define FLASHER_ALT_TEST 13
#define FLASHER_LED 21
#define FLASHER_RGB_LED 48 // maybe 38?
/* Lolin32 lite connections to AP tag

View File

@@ -30,8 +30,9 @@ lib_deps =
https://github.com/Bodmer/TJpg_Decoder.git
https://github.com/garretlab/shoddyxml2
https://github.com/Bodmer/U8g2_for_TFT_eSPI
upload_port = COM7
monitor_port = COM7
fastled/FastLED
upload_port = COM17
monitor_port = COM17
build_unflags =
-D ARDUINO_USB_MODE=1
build_flags =

270
esp32_fw/src/leds.cpp Normal file
View File

@@ -0,0 +1,270 @@
#include <Arduino.h>
#include <FastLED.h>
#include "settings.h"
QueueHandle_t rgbLedQueue;
QueueHandle_t ledQueue;
struct ledInstructionRGB {
CRGB ledColor;
uint16_t fadeTime;
uint16_t length;
};
struct ledInstruction {
uint16_t value;
uint16_t fadeTime;
uint16_t length;
};
const uint8_t PROGMEM gamma8[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 109, 110, 112, 114,
115, 117, 119, 120, 122, 124, 126, 127, 129, 131, 133, 135, 137, 138, 140, 142,
144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 167, 169, 171, 173, 175,
177, 180, 182, 184, 186, 189, 191, 193, 196, 198, 200, 203, 205, 208, 210, 213,
215, 218, 220, 223, 225, 228, 231, 233, 236, 239, 241, 244, 247, 249, 252, 255};
const uint16_t gamma12[256] = {
0, 2, 4, 6, 8, 10, 12, 13, 15, 17,
19, 21, 23, 25, 27, 29, 31, 33, 35, 36,
38, 37, 39, 41, 43, 45, 47, 49, 52, 54,
56, 59, 61, 64, 66, 69, 72, 74, 77, 80,
83, 87, 90, 93, 96, 100, 103, 107, 111, 115,
118, 122, 126, 131, 135, 139, 143, 148, 153, 157,
162, 167, 172, 177, 182, 187, 193, 198, 204, 209,
215, 221, 227, 233, 239, 246, 252, 259, 265, 272,
279, 286, 293, 300, 307, 315, 322, 330, 338, 346,
354, 362, 370, 379, 387, 396, 405, 414, 423, 432,
442, 451, 461, 470, 480, 490, 500, 511, 521, 532,
542, 553, 564, 575, 587, 598, 610, 622, 633, 645,
658, 670, 683, 695, 708, 721, 734, 747, 761, 774,
788, 802, 816, 830, 845, 859, 874, 889, 904, 919,
935, 950, 966, 982, 998, 1015, 1031, 1048, 1065, 1082,
1099, 1116, 1134, 1151, 1169, 1187, 1206, 1224, 1243, 1262,
1281, 1300, 1319, 1339, 1359, 1379, 1399, 1419, 1440, 1461,
1482, 1503, 1524, 1546, 1568, 1590, 1612, 1634, 1657, 1680,
1703, 1726, 1749, 1773, 1797, 1821, 1845, 1870, 1895, 1920,
1945, 1970, 1996, 2022, 2048, 2074, 2100, 2127, 2154, 2181,
2209, 2236, 2264, 2292, 2321, 2349, 2378, 2407, 2436, 2466,
2495, 2525, 2556, 2586, 2617, 2648, 2679, 2710, 2742, 2774,
2806, 2838, 2871, 2904, 2937, 2970, 3004, 3038, 3072, 3107,
3141, 3176, 3211, 3247, 3283, 3319, 3355, 3391, 3428, 3465,
3502, 3540, 3578, 3616, 3654, 3693, 3732, 3771, 3810, 3850,
3890, 3930, 3971, 4013, 4054, 4095};
CRGB leds[1];
void addToRGBQueue(struct ledInstructionRGB* rgb) {
BaseType_t queuestatus = xQueueSend(rgbLedQueue, &rgb, 0);
if (queuestatus == pdFALSE) {
delete rgb;
}
}
void addToMonoQueue(struct ledInstruction* mono) {
BaseType_t queuestatus = xQueueSend(ledQueue, &mono, 0);
if (queuestatus == pdFALSE) {
delete mono;
}
}
void addFadeColor(CRGB cname) {
struct ledInstructionRGB* rgb = new struct ledInstructionRGB;
rgb->ledColor = cname;
rgb->fadeTime = 750;
rgb->length = 0;
addToRGBQueue(rgb);
}
void addFadeMono(uint8_t value) {
struct ledInstruction* mono = new struct ledInstruction;
mono->value = value;
mono->fadeTime = 750;
mono->length = 0;
addToMonoQueue(mono);
}
void shortBlink(CRGB cname) {
struct ledInstructionRGB* rgb = new struct ledInstructionRGB;
rgb->ledColor = CRGB::Black;
rgb->fadeTime = 0;
rgb->length = 3;
addToRGBQueue(rgb);
rgb = new struct ledInstructionRGB;
rgb->ledColor = cname;
rgb->ledColor.maximizeBrightness(0x80);
rgb->fadeTime = 0;
rgb->length = 10;
addToRGBQueue(rgb);
rgb = new struct ledInstructionRGB;
rgb->ledColor = CRGB::Black;
rgb->fadeTime = 0;
rgb->length = 3;
addToRGBQueue(rgb);
}
void showRGB() {
FastLED.show();
}
void showMono(uint8_t brightness) {
ledcWrite(7, gamma12[brightness]);
}
volatile uint16_t rgbIdlePeriod = 800;
volatile uint16_t monoIdlePeriod = 900;
volatile CRGB rgbIdleColor = CRGB::Green;
uint8_t monoValue = 0;
void rgbIdleStep() {
static bool dirUp = true;
static uint16_t step = 0;
if (dirUp) {
// up
step++;
if (step == rgbIdlePeriod) {
dirUp = false;
}
} else {
// down
step--;
if (step == 0) {
dirUp = true;
}
}
CRGB newvalue = blend(CRGB::Black, (const CRGB&)rgbIdleColor, gamma8[map(step, 0, rgbIdlePeriod, 0, 255)]);
if (newvalue != leds[0]) {
leds[0] = newvalue;
showRGB();
}
}
void monoIdleStep() {
static bool dirUp = true;
static uint16_t step = 0;
if (dirUp) {
// up
step++;
if (step == monoIdlePeriod) {
dirUp = false;
}
} else {
// down
step--;
if (step == 0) {
dirUp = true;
}
}
uint8_t newvalue = map(step, 0, monoIdlePeriod, 0, 255);
if (newvalue != monoValue) {
monoValue = newvalue;
showMono(newvalue);
}
}
void ledTask(void* parameter) {
FastLED.addLeds<WS2812B, FLASHER_RGB_LED, GRB>(leds, 1); // GRB ordering is typical
leds[0] = CRGB::Blue;
showRGB();
rgbLedQueue = xQueueCreate(30, sizeof(struct ledInstructionRGB*));
ledQueue = xQueueCreate(30, sizeof(struct ledInstruction*));
digitalWrite(FLASHER_LED, HIGH);
pinMode(FLASHER_LED, OUTPUT);
ledcSetup(7, 9500, 12); // 141251 okay // 101251 okay
ledcAttachPin(FLASHER_LED, 7);
struct ledInstructionRGB* rgb = nullptr;
struct ledInstruction* monoled = nullptr;
// open with a nice RGB crossfade
addFadeColor(CRGB::Red);
addFadeColor(CRGB::Green);
addFadeColor(CRGB::Blue);
addFadeColor(CRGB::Red);
addFadeColor(CRGB::Green);
addFadeColor(CRGB::Blue);
addFadeMono(255);
addFadeMono(127);
addFadeMono(255);
addFadeMono(0);
CRGB oldColor = CRGB::Black;
uint8_t oldBrightness = 0;
uint16_t rgbInstructionFadeTime = 0;
uint16_t monoInstructionFadeTime = 0;
while (1) {
// handle RGB led instructions
if (rgb == nullptr) {
// fetch a led instruction
BaseType_t q = xQueueReceive(rgbLedQueue, &rgb, 1);
if (q == pdTRUE) {
rgbInstructionFadeTime = rgb->fadeTime;
if (rgb->fadeTime <= 1) {
leds[0] = rgb->ledColor;
showRGB();
}
} else {
// no commands, run idle led task
rgbIdleStep();
}
} else {
// process instruction
if (rgb->fadeTime) {
rgb->fadeTime--;
leds[0] = blend(rgb->ledColor, oldColor, map(rgb->fadeTime, 0, rgbInstructionFadeTime, 0, 255));
showRGB();
} else if (rgb->length) {
rgb->length--;
} else {
oldColor = rgb->ledColor;
delete rgb;
rgb = nullptr;
}
}
// handle flasher LED (single color)
if (monoled == nullptr) {
BaseType_t q = xQueueReceive(ledQueue, &monoled, 1);
if (q == pdTRUE) {
monoInstructionFadeTime = monoled->fadeTime;
if (monoled->fadeTime <= 1) {
showMono(gamma12[monoled->value]);
}
} else {
monoIdleStep();
}
} else {
if (monoled->fadeTime) {
monoled->fadeTime--;
showMono(map(monoled->fadeTime, 0, monoInstructionFadeTime, monoled->value, oldBrightness));
} else if (monoled->length) {
monoled->length--;
} else {
oldBrightness = monoled->value;
delete monoled;
monoled = nullptr;
}
}
vTaskDelay(1 / portTICK_PERIOD_MS);
}
}

View File

@@ -14,6 +14,8 @@
#include "usbflasher.h"
#include "web.h"
#include "leds.h"
void timeTask(void* parameter) {
while (1) {
time_t now;
@@ -51,8 +53,6 @@ void setup() {
Serial.printf("Free heap: %d", ESP.getFreeHeap());
Serial.printf("Total PSRAM: %d", ESP.getPsramSize());
Serial.printf("Free PSRAM: %d", ESP.getFreePsram());
pinMode(ONBOARD_LED, OUTPUT);
digitalWrite(ONBOARD_LED, HIGH);
xTaskCreate(usbFlasherTask, "flasher", 10000, NULL, configMAX_PRIORITIES - 10, NULL);
@@ -66,6 +66,7 @@ void setup() {
xTaskCreate(garbageCollection, "pending-data cleanup", 5000, NULL, 1, NULL);
xTaskCreate(webSocketSendProcess, "ws", 5000, NULL, configMAX_PRIORITIES - 10, NULL);
xTaskCreate(timeTask, "timed tasks", 10000, NULL, 2, NULL);
xTaskCreate(ledTask, "handles leds", 5000, NULL, 10, NULL);
}
void loop() {

View File

@@ -321,9 +321,6 @@ void processXferTimeout(struct espXferComplete* xfc) {
}
void processDataReq(struct espAvailDataReq* eadr) {
digitalWrite(ONBOARD_LED, LOW);
char buffer[64];
uint8_t src[8];
*((uint64_t*)src) = swap64(*((uint64_t*)eadr->src));
@@ -367,8 +364,6 @@ void processDataReq(struct espAvailDataReq* eadr) {
sprintf(buffer, "<ADR %02X%02X%02X%02X%02X%02X\n\0", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Serial.print(buffer);
wsSendTaginfo(mac);
digitalWrite(ONBOARD_LED, HIGH);
}
void refreshAllPending() {

26
esp32_fw/src/powermgt.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include <Arduino.h>
#include "powermgt.h"
#include "settings.h"
// On the OpenEPaperLink board, there is no in-rush current limiting. The tags that can be connected to the board can have significant capacity, which,
// when drained, will cause the 3v3 rail to sag enough to reset the ESP32. This is obviously not great. To prevent this from happening, we ramp up/down the
// voltage with PWM. Ramping down really is unnecessary, as the board has a resistor to dump the charge into.
void rampTagPower(uint8_t pin, bool up) {
if (up) {
ledcSetup(0, 152000, 8); // 141251 okay // 101251 okay
ledcWrite(0, 254);
vTaskDelay(10 / portTICK_PERIOD_MS);
ledcAttachPin(pin, 0);
pinMode(pin, OUTPUT);
for (uint8_t c = 254; c != 0xFF; c--) {
ledcWrite(0, c);
vTaskDelay(1 / portTICK_PERIOD_MS);
}
digitalWrite(pin, LOW);
ledcDetachPin(pin);
digitalWrite(pin, LOW);
} else {
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
}
}

View File

@@ -89,7 +89,7 @@ uint8_t pktlen = 0;
uint8_t pktindex = 0;
char lastchar = 0;
uint8_t charindex = 0;
uint64_t waitingForVersion = 0;
uint64_t waitingForVersion = 0;
uint16_t version;
void ShortRXWaitLoop() {
@@ -112,7 +112,7 @@ void Ping() {
void SerialRXLoop() {
if (Serial1.available()) {
lastchar = Serial1.read();
//Serial.write(lastchar);
// Serial.write(lastchar);
switch (RXState) {
case ZBS_RX_WAIT_HEADER:
Serial.write(lastchar);
@@ -228,10 +228,37 @@ void SerialRXLoop() {
extern uint8_t* getDataForFile(File* file);
void zbsRxTask(void* parameter) {
Serial1.begin(230400, SERIAL_8N1, RXD1, TXD1);
void simplePowerOn() {
pinMode(FLASHER_AP_SS, INPUT);
pinMode(FLASHER_AP_CLK, INPUT);
pinMode(FLASHER_AP_MOSI, INPUT);
pinMode(FLASHER_AP_MISO, INPUT);
//simplePowerOn();
pinMode(FLASHER_AP_RESET, OUTPUT);
digitalWrite(FLASHER_AP_RESET, LOW);
ledcSetup(0, 152000, 8); //152kHz PWM
ledcWrite(0, 254);
vTaskDelay(10 / portTICK_PERIOD_MS);
ledcAttachPin(FLASHER_AP_POWER, 0);
pinMode(FLASHER_AP_POWER, OUTPUT);
for (uint8_t c = 254; c != 0xFF; c--) {
ledcWrite(0, c);
vTaskDelay(1 / portTICK_PERIOD_MS);
}
digitalWrite(FLASHER_AP_POWER, LOW);
ledcDetachPin(FLASHER_AP_POWER);
digitalWrite(FLASHER_AP_POWER, LOW);
vTaskDelay(1 / portTICK_PERIOD_MS);
digitalWrite(FLASHER_AP_RESET, HIGH);
}
void zbsRxTask(void* parameter) {
pinMode(FLASHER_AP_TXD, OUTPUT);
Serial1.begin(230400, SERIAL_8N1, FLASHER_AP_RXD, FLASHER_AP_TXD);
simplePowerOn();
bool firstrun = true;
Serial1.print("VER?");
@@ -245,17 +272,17 @@ void zbsRxTask(void* parameter) {
vTaskDelay(1 / portTICK_PERIOD_MS);
if (waitingForVersion) {
if (esp_timer_get_time() - waitingForVersion > 10000*1000ULL) {
if (esp_timer_get_time() - waitingForVersion > 10000 * 1000ULL) {
waitingForVersion = 0;
//performDeviceFlash();
// performDeviceFlash();
Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag.");
Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware");
//simplePowerOn();
// simplePowerOn();
wsErr("The AP tag crashed. Restarting tag, regenerating all pending info.");
refreshAllPending();
}
}
if (version && firstrun) {
Serial.printf("ZBS/Zigbee FW version: %04X\n", version);
uint16_t fsversion;

View File

@@ -1,6 +1,7 @@
#include <Arduino.h>
#include "USB.h"
#include "powermgt.h"
#include "settings.h"
#include "zbs_interface.h"
@@ -170,17 +171,6 @@ static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t eve
}
}
void flasherTaskBegin() {
flasherCmdQueue = xQueueCreate(10, sizeof(struct flasherCommand*));
#if ARDUINO_USB_MODE
#warning Wrong USB mode is in use, check settings in platformio.ini
#endif
USB.onEvent(usbEventCallback);
USBSerial.onEvent(usbEventCallback);
USBSerial.begin();
USB.begin();
}
typedef enum {
CMD_GET_VERSION = 1,
CMD_RESET_ESP = 2,
@@ -223,7 +213,7 @@ void processFlasherCommand(struct flasherCommand* cmd) {
ESP.restart();
break;
case CMD_ZBS_BEGIN:
if (zbs != nullptr){
if (zbs != nullptr) {
delete zbs;
}
zbs = new ZBS_interface;
@@ -235,6 +225,8 @@ void processFlasherCommand(struct flasherCommand* cmd) {
curspeed = spi_speed;
if (cmd->data[0] & 2) {
temp_buff[0] = zbs->begin(FLASHER_AP_SS, FLASHER_AP_CLK, FLASHER_AP_MOSI, FLASHER_AP_MISO, FLASHER_AP_RESET, FLASHER_AP_POWER, spi_speed);
} else if (cmd->data[0] & 4) {
temp_buff[0] = zbs->begin(FLASHER_ALT_SS, FLASHER_ALT_CLK, FLASHER_ALT_MOSI, FLASHER_ALT_MISO, FLASHER_ALT_RESET, 255, spi_speed);
} else {
temp_buff[0] = zbs->begin(FLASHER_EXT_SS, FLASHER_EXT_CLK, FLASHER_EXT_MOSI, FLASHER_EXT_MISO, FLASHER_EXT_RESET, FLASHER_EXT_POWER, spi_speed);
}
@@ -333,7 +325,14 @@ void processFlasherCommand(struct flasherCommand* cmd) {
}
void usbFlasherTask(void* parameter) {
flasherTaskBegin();
flasherCmdQueue = xQueueCreate(10, sizeof(struct flasherCommand*));
#if ARDUINO_USB_MODE
#warning Wrong USB mode is in use, check settings in platformio.ini
#endif
USB.onEvent(usbEventCallback);
USBSerial.onEvent(usbEventCallback);
USBSerial.begin();
USB.begin();
struct flasherCommand* cmd;
while (true) {
BaseType_t queuereceive = xQueueReceive(flasherCmdQueue, &cmd, portMAX_DELAY);

View File

@@ -16,6 +16,7 @@
#include "newproto.h"
#include "settings.h"
#include "tag_db.h"
#include "leds.h"
extern uint8_t data_to_send[];
@@ -51,6 +52,7 @@ void webSocketSendProcess(void *parameter) {
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
shortBlink(CRGB::BlueViolet);
switch (type) {
case WS_EVT_CONNECT:
// client connected

View File

@@ -7,6 +7,8 @@
#include <stdint.h>
#include <stdio.h>
#include "powermgt.h"
uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO, uint8_t RESET, uint8_t POWER, uint32_t spi_speed) {
_SS_PIN = SS;
_CLK_PIN = CLK;
@@ -25,7 +27,7 @@ uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO
digitalWrite(_CLK_PIN, LOW);
digitalWrite(_MOSI_PIN, HIGH);
if(!spi)spi = new SPIClass(HSPI);
if (!spi) spi = new SPIClass(HSPI);
spiSettings = SPISettings(spi_speed, MSBFIRST, SPI_MODE0);
spi_ready = 0;
@@ -39,33 +41,16 @@ uint8_t ZBS_interface::begin(uint8_t SS, uint8_t CLK, uint8_t MOSI, uint8_t MISO
return check_connection();
}
void ZBS_interface::setSpeed(uint32_t speed){
void ZBS_interface::setSpeed(uint32_t speed) {
spiSettings = SPISettings(speed, MSBFIRST, SPI_MODE0);
}
ZBS_interface::~ZBS_interface(){
ZBS_interface::~ZBS_interface() {
delete spi;
}
void ZBS_interface::set_power(uint8_t state) {
if (_POWER_PIN != -1) {
if (state) {
ledcSetup(0, 20000, 8);
ledcWrite(0, 255);
ledcAttachPin(_POWER_PIN, 0);
pinMode(_POWER_PIN, OUTPUT);
for (uint8_t c = 254; c != 0xFF; c--) {
ledcWrite(0, c);
vTaskDelay(1 / portTICK_PERIOD_MS);
}
digitalWrite(_POWER_PIN, LOW);
ledcDetachPin(_POWER_PIN);
digitalWrite(_POWER_PIN, LOW);
} else {
pinMode(_POWER_PIN, OUTPUT);
digitalWrite(_POWER_PIN, HIGH);
}
if (_POWER_PIN != 255) {
rampTagPower(_POWER_PIN, state);
}
}

BIN
esp32_fw/test.bin2 Normal file

Binary file not shown.