RGB LED number configurable (not tested)

This commit is contained in:
whowechina 2023-11-26 13:10:50 +08:00
parent 1eafa6a21a
commit 4f21536f7a
5 changed files with 61 additions and 181 deletions

View File

@ -12,9 +12,9 @@
#define RGB_PIN 13
#define RGB_ORDER GRB // or RGB
#define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6 }
#define RGB_BUTTON_MAP { 5, 4, 3, 2, 1, 0, 7, 6, 8, 9 }
#define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2 }
#define BUTTON_DEF { 1, 0, 4, 5, 8, 9, 3, 2, 10, 11 }
/* HID Keycode: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h */
// P1: WEDCXZAQ34 P2: (Numpad)89632147*-

View File

@ -17,9 +17,11 @@
#define SENSE_LIMIT_MAX 9
#define SENSE_LIMIT_MIN -9
static void disp_color()
static void disp_rgb()
{
printf("[Color]\n");
printf("[RGB]\n");
printf(" Number per button: %d, number per aux: %d\n",
mai_cfg->rgb.per_button, mai_cfg->rgb.per_aux);
printf(" Key on: %06x, off: %06x\n Level: %d\n",
mai_cfg->color.key_on, mai_cfg->color.key_off, mai_cfg->color.level);
}
@ -56,23 +58,23 @@ static void disp_hid()
void handle_display(int argc, char *argv[])
{
const char *usage = "Usage: display [color|sense|hid]\n";
const char *usage = "Usage: display [rgb|sense|hid]\n";
if (argc > 1) {
printf(usage);
return;
}
if (argc == 0) {
disp_color();
disp_rgb();
disp_sense();
disp_hid();
return;
}
const char *choices[] = {"color", "sense", "hid"};
const char *choices[] = {"rgb", "sense", "hid"};
switch (cli_match_prefix(choices, 3, argv[0])) {
case 0:
disp_color();
disp_rgb();
break;
case 1:
disp_sense();
@ -86,6 +88,29 @@ void handle_display(int argc, char *argv[])
}
}
static void handle_rgb(int argc, char *argv[])
{
const char *usage = "Usage: rgb <1..16> <1..16>\n";
if (argc != 2) {
printf(usage);
return;
}
int per_button = cli_extract_non_neg_int(argv[0], 0);
int per_aux = cli_extract_non_neg_int(argv[1], 0);
if ((per_button < 1) || (per_button > 16) ||
(per_aux < 1) || (per_aux > 16)) {
printf(usage);
return;
}
mai_cfg->rgb.per_button = per_button;
mai_cfg->rgb.per_aux = per_aux;
config_changed();
disp_rgb();
}
static void handle_level(int argc, char *argv[])
{
const char *usage = "Usage: level <0..255>\n";
@ -102,7 +127,7 @@ static void handle_level(int argc, char *argv[])
mai_cfg->color.level = level;
config_changed();
disp_color();
disp_rgb();
}
static void handle_stat(int argc, char *argv[])
@ -341,6 +366,7 @@ static void handle_factory_reset()
void commands_init()
{
cli_register("display", handle_display, "Display all config.");
cli_register("rgb", handle_rgb, "Set RGB LED number for main button and aux buttons.");
cli_register("level", handle_level, "Set LED brightness level.");
cli_register("stat", handle_stat, "Display or reset statistics.");
cli_register("hid", handle_hid, "Set HID mode.");

View File

@ -26,9 +26,17 @@ static mai_cfg_t default_cfg = {
.joy = 1,
.nkro = 0,
},
.rgb = {
.per_button = 8,
.per_aux = 2,
}
};
mai_runtime_t *mai_runtime;
static inline bool in_range(int val, int min, int max)
{
return (val >= min) && (val <= max);
}
static void config_loaded()
{
@ -37,22 +45,28 @@ static void config_loaded()
mai_cfg->sense.filter = default_cfg.sense.filter;
config_changed();
}
if ((mai_cfg->sense.global > 9) || (mai_cfg->sense.global < -9)) {
if (!in_range(mai_cfg->sense.global, -9, 9)) {
mai_cfg->sense.global = default_cfg.sense.global;
config_changed();
}
for (int i = 0; i < 32; i++) {
if ((mai_cfg->sense.keys[i] > 9) || (mai_cfg->sense.keys[i] < -9)) {
if (!in_range(mai_cfg->sense.keys[i], -9, 9)) {
mai_cfg->sense.keys[i] = default_cfg.sense.keys[i];
config_changed();
}
}
if ((mai_cfg->sense.debounce_touch > 7) |
(mai_cfg->sense.debounce_release > 7)) {
if (!in_range(mai_cfg->sense.debounce_touch, 0, 7) ||
!in_range(mai_cfg->sense.debounce_release, 0, 7)) {
mai_cfg->sense.debounce_touch = default_cfg.sense.debounce_touch;
mai_cfg->sense.debounce_release = default_cfg.sense.debounce_release;
config_changed();
}
if (!in_range(mai_cfg->rgb.per_button, 1, 16) ||
!in_range(mai_cfg->rgb.per_aux, 1, 16)) {
mai_cfg->rgb = default_cfg.rgb;
config_changed();
}
}
void config_changed()

View File

@ -26,6 +26,10 @@ typedef struct __attribute__((packed)) {
uint8_t joy : 4;
uint8_t nkro : 4;
} hid;
struct {
uint8_t per_button;
uint8_t per_aux;
} rgb;
} mai_cfg_t;
typedef struct {

View File

@ -94,7 +94,10 @@ static void drive_led()
last = now;
for (int i = 0; i < ARRAY_SIZE(rgb_buf); i++) {
pio_sm_put_blocking(pio0, 0, rgb_buf[i] << 8u);
int num = (i < 8) ? mai_cfg->rgb.per_button : mai_cfg->rgb.per_aux;
for (int j = 0; j < num; j++) {
pio_sm_put_blocking(pio0, 0, rgb_buf[i] << 8u);
}
}
}
@ -150,170 +153,3 @@ void rgb_update()
{
drive_led();
}
#if 0
#if defined(__AVR_ATmega32U4__) || defined(ARDUINO_SAMD_ZERO)
#pragma message "当前的开发板是 ATmega32U4 或 SAMD_ZERO"
#define SerialDevice SerialUSB
#define LED_PIN 13
#elif defined(ARDUINO_ESP8266_NODEMCU_ESP12E)
#pragma message "当前的开发板是 NODEMCU_ESP12E"
#define SerialDevice Serial
#define LED_PIN D5
#elif defined(ARDUINO_NodeMCU_32S)
#pragma message "当前的开发板是 NodeMCU_32S"
#define SerialDevice Serial
#define LED_PIN 13
#else
#error "未经测试的开发板,请检查串口和阵脚定义"
#endif
#include "FastLED.h"
#define NUM_LEDS 11
CRGBArray<NUM_LEDS> leds;
enum {
LedGs8Bit = 0x31,//49
LedGs8BitMulti = 0x32,//50
LedGs8BitMultiFade = 0x33,//51
LedFet = 0x39,//57
LedGsUpdate = 0x3C,//60
LedDirect = 0x82,
};
typedef union {
uint8_t base[64];
struct {
struct {
uint8_t dstNodeID;
uint8_t srcNodeID;
uint8_t length;
uint8_t cmd;
};
union {
struct { //39
uint8_t color[11][3];//CRGB
};
struct { //9
uint8_t BodyLed;
uint8_t ExtLed;
uint8_t SideLed;
};
struct { //LedGs8Bit
uint8_t index;
uint8_t r;
uint8_t g;
uint8_t b;
};
struct { //LedGs8BitMulti,LedGs8BitMultiFade
uint8_t start;
uint8_t end;//length
uint8_t skip;
uint8_t mr;
uint8_t mg;
uint8_t mb;
uint8_t speed;
};
};
};
} Packet;
static Packet req;
static uint8_t len, r, checksum;
static bool escape = false;
static uint8_t packet_read() {
while (SerialDevice.available()) {
r = SerialDevice.read();
if (r == 0xE0) {
len = 0;
checksum = 0;
continue;
}
if (r == 0xD0) {
escape = true;
continue;
}
if (escape) {
r++;
escape = false;
}
if (len - 3 == req.length && checksum == r) {
return req.cmd;
}
req.base[len++] = r;
checksum += r;
}
return 0;
}
void setup() {
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(30);
FastLED.clear();
SerialDevice.begin(115200);
leds(0, 7) = 0xFFFFFF;
FastLED.delay(1000);
}
unsigned long fade_start, fade_end, progress;
uint8_t led_start, led_end, fade_tag;
CRGB fade_prev, fade_taget;
void loop() {
switch (packet_read()) {
case LedGs8Bit:
leds[req.index] = CRGB(req.r, req.g, req.b);
break;
case LedGs8BitMulti:
if (req.end == 0x20) {
req.end = NUM_LEDS;
}
leds(req.start, req.end - 1) = CRGB(req.mr, req.mg, req.mb);
fade_prev = CRGB(req.mr, req.mg, req.mb);
fade_tag = 0;
break;
case LedGs8BitMultiFade:
fade_taget = CRGB(req.mr, req.mg, req.mb);
fade_start = millis();
fade_end = fade_start + (4095 / req.speed * 8);
led_start = req.start;
led_end = req.end - 1;
fade_tag = 1;
break;
case LedFet://框体灯,只有白色,值代表亮度,会多次发送实现渐变,需要立刻刷新
leds[8] = blend(0x000000, 0xFFFFFF, req.BodyLed);
leds[9] = blend(0x000000, 0xFFFFFF, req.ExtLed);//same as BodyLed
leds[10] = blend(0x000000, 0xFFFFFF, req.SideLed);//00 or FF
FastLED.show();
break;
case LedGsUpdate://提交灯光数据
FastLED.show();
break;
}
if (!fade_tag)return;
if (millis() > fade_end) {
progress = 255;
fade_tag = 0;
} else {
progress = map(millis(), fade_start, fade_end, 0, 255);
}
leds(led_start, led_end) = blend(fade_prev, fade_taget, progress);
FastLED.show();
}
#endif