mirror of
https://github.com/DashyFox/StackSport.git
synced 2025-06-28 13:19:41 +00:00
led and rc
This commit is contained in:
@ -8,70 +8,35 @@
|
||||
#include "Indicator.h"
|
||||
#include "ShiftReg.h"
|
||||
#include "SimpleTimer.h"
|
||||
#include "Print.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
const LedMap ledMap = {
|
||||
// ALL - DOWN[0] TO UP[19]
|
||||
{
|
||||
{0, 0b01000000},
|
||||
{0, 0b00100000},
|
||||
{0, 0b00010000},
|
||||
{0, 0b00001000},
|
||||
{0, 0b00000100},
|
||||
{0, 0b00000010},
|
||||
{0, 0b00000001},
|
||||
{1, 0b00000001},
|
||||
{1, 0b00000010},
|
||||
{1, 0b00000100},
|
||||
{ { 0, 0b01000000 }, { 0, 0b00100000 }, { 0, 0b00010000 }, { 0,
|
||||
0b00001000 }, { 0, 0b00000100 }, { 0, 0b00000010 }, { 0,
|
||||
0b00000001 }, { 1, 0b00000001 }, { 1, 0b00000010 }, { 1,
|
||||
0b00000100 },
|
||||
|
||||
{1, 0b01000000},
|
||||
{1, 0b00100000},
|
||||
{1, 0b00010000},
|
||||
{2, 0b00000001},
|
||||
{2, 0b00000010},
|
||||
{2, 0b00000100},
|
||||
{2, 0b00001000},
|
||||
{2, 0b00010000},
|
||||
{2, 0b00100000},
|
||||
{2, 0b01000000},
|
||||
},
|
||||
{ 1, 0b01000000 }, { 1, 0b00100000 }, { 1, 0b00010000 },
|
||||
{ 2, 0b00000001 }, { 2, 0b00000010 }, { 2, 0b00000100 }, { 2,
|
||||
0b00001000 }, { 2, 0b00010000 }, { 2, 0b00100000 }, { 2,
|
||||
0b01000000 }, },
|
||||
// UP - DOWN[0] TO UP[9]
|
||||
{
|
||||
{1, 0b01000000},
|
||||
{1, 0b00100000},
|
||||
{1, 0b00010000},
|
||||
{2, 0b00000001},
|
||||
{2, 0b00000010},
|
||||
{2, 0b00000100},
|
||||
{2, 0b00001000},
|
||||
{2, 0b00010000},
|
||||
{2, 0b00100000},
|
||||
{2, 0b01000000},
|
||||
},
|
||||
{ { 1, 0b01000000 }, { 1, 0b00100000 }, { 1, 0b00010000 }, { 2,
|
||||
0b00000001 }, { 2, 0b00000010 }, { 2, 0b00000100 }, { 2,
|
||||
0b00001000 }, { 2, 0b00010000 }, { 2, 0b00100000 }, { 2,
|
||||
0b01000000 }, },
|
||||
// DOWN - DOWN[0] TO UP[9]
|
||||
{
|
||||
{0, 0b01000000},
|
||||
{0, 0b00100000},
|
||||
{0, 0b00010000},
|
||||
{0, 0b00001000},
|
||||
{0, 0b00000100},
|
||||
{0, 0b00000010},
|
||||
{0, 0b00000001},
|
||||
{1, 0b00000001},
|
||||
{1, 0b00000010},
|
||||
{1, 0b00000100},
|
||||
},
|
||||
{ { 0, 0b01000000 }, { 0, 0b00100000 }, { 0, 0b00010000 }, { 0,
|
||||
0b00001000 }, { 0, 0b00000100 }, { 0, 0b00000010 }, { 0,
|
||||
0b00000001 }, { 1, 0b00000001 }, { 1, 0b00000010 }, { 1,
|
||||
0b00000100 }, },
|
||||
// RED - DOWN[0] TO UP[5]
|
||||
{
|
||||
{1, 0b00000001},
|
||||
{1, 0b00000010},
|
||||
{1, 0b00000100},
|
||||
{ { 1, 0b00000001 }, { 1, 0b00000010 }, { 1, 0b00000100 },
|
||||
|
||||
{1, 0b01000000},
|
||||
{1, 0b00100000},
|
||||
{1, 0b00010000},
|
||||
}
|
||||
};
|
||||
{ 1, 0b01000000 }, { 1, 0b00100000 }, { 1, 0b00010000 }, } };
|
||||
|
||||
static uint8_t ledBuf[3] = { 0, 0, 0 };
|
||||
|
||||
@ -80,35 +45,91 @@ typedef struct {
|
||||
uint16_t count;
|
||||
uint32_t timer;
|
||||
} LedBlinkInfo;
|
||||
typedef struct {
|
||||
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
uint32_t ledCurrent;
|
||||
uint8_t globalDir;
|
||||
uint8_t dir;
|
||||
void (*writeCallback)(uint8_t ledNum, uint8_t state);
|
||||
} LedPingPongInfo;
|
||||
|
||||
static LedBlinkInfo ledBlinkInfo[NUMLEDS * INDICATORS_COUNT];
|
||||
static LedPingPongInfo ledPingPongInfo;
|
||||
|
||||
static uint32_t idle_timer;
|
||||
static void NULL_FUNC(){};
|
||||
static void (*onLedIdle_Callback)() = NULL_FUNC;
|
||||
//static void (*onDone_Callback)() = NULL_FUNC;
|
||||
static void led_PingPong_start_(uint8_t fromLed, uint8_t toLed);
|
||||
static void led_progressbar_(uint8_t fromLed, uint8_t toLed, uint8_t progress, void (*led_writeFunc)(uint8_t, uint8_t));
|
||||
|
||||
//void led_setOnDone(void (*callback)()){
|
||||
// onDone_Callback = callback;
|
||||
//}
|
||||
|
||||
//void led_resetOnDone(){
|
||||
// onDone_Callback = NULL_FUNC;
|
||||
//}
|
||||
|
||||
static long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
static void blinkHandler() {
|
||||
for (int i = 0; i < sizeof(ledBlinkInfo) / sizeof(ledBlinkInfo[0]); ++i) {
|
||||
if(!ledBlinkInfo[i].count || !ledBlinkInfo[i].period){
|
||||
if (!ledBlinkInfo[i].count || !ledBlinkInfo[i].period) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(millis() - ledBlinkInfo[i].timer > ledBlinkInfo[i].period){
|
||||
if (millis() - ledBlinkInfo[i].timer > ledBlinkInfo[i].period) {
|
||||
ledBlinkInfo[i].timer = millis();
|
||||
led_write(ledMap.ALL[i], (ledBlinkInfo[i].count & 1) != 1);
|
||||
ledBlinkInfo[i].count--;
|
||||
if(ledBlinkInfo[i].count != 0xFFFF){
|
||||
led_write(i, (ledBlinkInfo[i].count & 1) != 1);
|
||||
ledBlinkInfo[i].count--;
|
||||
} else {
|
||||
led_write(i, !led_getState(ledMap.ALL[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void led_init(){
|
||||
void led_setIdleCallback(void(*callback)()){
|
||||
onLedIdle_Callback = callback;
|
||||
}
|
||||
void led_resetIdleCallback(){
|
||||
onLedIdle_Callback = NULL_FUNC;
|
||||
}
|
||||
|
||||
void led_init() {
|
||||
memset(ledBlinkInfo, 0x00, sizeof(ledBlinkInfo));
|
||||
memset(&ledPingPongInfo, 0x00, sizeof(ledPingPongInfo));
|
||||
ledPingPongInfo.writeCallback = led_write;
|
||||
}
|
||||
|
||||
void led_show() {
|
||||
idle_timer = millis();
|
||||
SetShiftReg(ledBuf);
|
||||
}
|
||||
|
||||
void led_tick() {
|
||||
blinkHandler();
|
||||
if(onLedIdle_Callback != NULL_FUNC && millis() - idle_timer > LED_IDLE_TIMEOUT){
|
||||
onLedIdle_Callback();
|
||||
led_resetIdleCallback();
|
||||
}
|
||||
}
|
||||
|
||||
void led_write(LedMap_element led, uint8_t state) {
|
||||
void led_write(uint8_t number, uint8_t state) {
|
||||
if(number >= sizeof(ledMap.ALL)/sizeof(ledMap.ALL[0]))
|
||||
return;
|
||||
|
||||
LedMap_element led = ledMap.ALL[number];
|
||||
|
||||
if(led_getState(led) == state)
|
||||
return;
|
||||
|
||||
if (state) {
|
||||
ledBuf[led.byteIndx] |= led.offsetMask;
|
||||
} else {
|
||||
@ -117,7 +138,7 @@ void led_write(LedMap_element led, uint8_t state) {
|
||||
led_show();
|
||||
}
|
||||
|
||||
uint8_t led_getState(LedMap_element led){
|
||||
uint8_t led_getState(LedMap_element led) {
|
||||
return (ledBuf[led.byteIndx] & led.offsetMask) != 0;
|
||||
}
|
||||
|
||||
@ -126,31 +147,259 @@ void led_writeMirror(uint8_t number, uint8_t state) {
|
||||
if (number >= 10) {
|
||||
number = 9;
|
||||
}
|
||||
number+=10;
|
||||
|
||||
led_write(ledMap.UP[number], state);
|
||||
led_write(ledMap.DOWN[9 - number], state);
|
||||
|
||||
led_show();
|
||||
led_write(number, state);
|
||||
led_write(19 - number, state);
|
||||
}
|
||||
|
||||
void led_blink_num(uint8_t ledNum, uint16_t period, uint16_t count){
|
||||
if(ledNum>=sizeof(ledBlinkInfo)/sizeof(ledBlinkInfo[0]))
|
||||
void led_blink_num(uint8_t ledNum, uint16_t period, uint16_t count) {
|
||||
if (ledNum >= sizeof(ledBlinkInfo) / sizeof(ledBlinkInfo[0]))
|
||||
return;
|
||||
ledBlinkInfo[ledNum].count = count*2;
|
||||
if(count == 0xFFFF){
|
||||
ledBlinkInfo[ledNum].count = count;
|
||||
} else {
|
||||
ledBlinkInfo[ledNum].count = count * 2;
|
||||
}
|
||||
ledBlinkInfo[ledNum].period = period;
|
||||
ledBlinkInfo[ledNum].timer = 0; // run immediately
|
||||
}
|
||||
|
||||
void led_blink(LedMap_element led, uint16_t period, uint16_t count) {
|
||||
for (int i = 0; i < sizeof(ledMap.ALL)/sizeof(ledMap.ALL[0]); ++i) {
|
||||
if(memcmp(&led, &ledMap.ALL[i], sizeof(LedMap_element)) == 0){
|
||||
for (int i = 0; i < sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0]); ++i) {
|
||||
if (memcmp(&led, &ledMap.ALL[i], sizeof(LedMap_element)) == 0) {
|
||||
led_blink_num(i, period, count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Общая функция для управления прогрессбаром
|
||||
void led_progressbar_(uint8_t fromLed, uint8_t toLed, uint8_t progress, void (*led_writeFunc)(uint8_t, uint8_t)) {
|
||||
if (progress > 100) {
|
||||
progress = 100;
|
||||
}
|
||||
|
||||
// Проверка на выход за границы массива ledMap.ALL
|
||||
if (fromLed >= sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0])
|
||||
|| toLed >= sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Инициализация переменных в зависимости от направления
|
||||
int8_t dir;
|
||||
uint8_t start;
|
||||
uint8_t end;
|
||||
uint8_t numLeds;
|
||||
if (fromLed < toLed) {
|
||||
start = fromLed;
|
||||
end = toLed;
|
||||
dir = 1; // Заполнение снизу вверх
|
||||
} else {
|
||||
start = toLed;
|
||||
end = fromLed;
|
||||
dir = -1; // Заполнение сверху вниз
|
||||
}
|
||||
|
||||
// Количество светодиодов в прогрессбаре (включая последний светодиод)
|
||||
numLeds = end - start + 1;
|
||||
|
||||
// Рассчитываем, сколько светодиодов нужно включить
|
||||
uint8_t ledsToLight = map(progress, 0, 100, 0, numLeds);
|
||||
|
||||
// Корректировка включения для первого и последнего светодиода
|
||||
if (progress > 0 && ledsToLight == 0) {
|
||||
ledsToLight = 1; // Включаем первый светодиод при любом положительном прогрессе
|
||||
}
|
||||
if (progress == 100) {
|
||||
ledsToLight = numLeds; // Включаем последний светодиод только при прогрессе 100%
|
||||
}
|
||||
|
||||
print("progress ");
|
||||
printNumber(progress);
|
||||
print(" led ");
|
||||
printNumber(ledsToLight);
|
||||
print("\n");
|
||||
|
||||
for (int i = 0; i < numLeds; ++i) {
|
||||
int ledIndex = fromLed + i * dir;
|
||||
|
||||
// Сброс счетчика мигания для включенных светодиодов
|
||||
ledBlinkInfo[ledIndex].count = 0;
|
||||
|
||||
if (i < ledsToLight) {
|
||||
// Включаем светодиод, если он не включен
|
||||
if (!led_getState(ledMap.ALL[ledIndex])) {
|
||||
led_writeFunc(ledIndex, 1); // Используем переданную функцию для включения
|
||||
}
|
||||
} else {
|
||||
// Выключаем светодиод, если он включен
|
||||
if (led_getState(ledMap.ALL[ledIndex])) {
|
||||
led_writeFunc(ledIndex, 0); // Используем переданную функцию для выключения
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Оригинальная функция, использующая led_write
|
||||
void led_progressbar(uint8_t fromLed, uint8_t toLed, uint8_t progress) {
|
||||
led_progressbar_(fromLed, toLed, progress, led_write);
|
||||
}
|
||||
|
||||
// Новая функция, использующая led_writeMirror
|
||||
void led_progressbarMirror(uint8_t fromLed, uint8_t toLed, uint8_t progress) {
|
||||
led_progressbar_(fromLed, toLed, progress, led_writeMirror);
|
||||
}
|
||||
|
||||
|
||||
void led_PingPong_startMirror(uint8_t fromLed, uint8_t toLed){
|
||||
uint8_t half_ledMap_size = (sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0]))/2;
|
||||
if (fromLed >= half_ledMap_size
|
||||
|| toLed >= half_ledMap_size) {
|
||||
return;
|
||||
}
|
||||
ledPingPongInfo.writeCallback = led_writeMirror;
|
||||
led_PingPong_start_(fromLed, toLed);
|
||||
}
|
||||
|
||||
void led_PingPong_start(uint8_t fromLed, uint8_t toLed) {
|
||||
if (fromLed >= sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0])
|
||||
|| toLed >= sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0])) {
|
||||
return;
|
||||
}
|
||||
ledPingPongInfo.writeCallback = led_write;
|
||||
led_PingPong_start_(fromLed, toLed);
|
||||
}
|
||||
void led_PingPong_start_(uint8_t fromLed, uint8_t toLed){
|
||||
if (fromLed < toLed) {
|
||||
ledPingPongInfo.start = fromLed;
|
||||
ledPingPongInfo.end = toLed;
|
||||
ledPingPongInfo.globalDir = 1;
|
||||
} else {
|
||||
ledPingPongInfo.start = toLed;
|
||||
ledPingPongInfo.end = fromLed;
|
||||
ledPingPongInfo.globalDir = 0;
|
||||
}
|
||||
ledPingPongInfo.dir = 1;
|
||||
ledPingPongInfo.ledCurrent = ledPingPongInfo.start;
|
||||
|
||||
for (uint8_t i = ledPingPongInfo.start; i <= ledPingPongInfo.end; i++) {
|
||||
ledBlinkInfo[i].count = 0;
|
||||
if (led_getState(ledMap.ALL[i]))
|
||||
ledPingPongInfo.writeCallback(i, 0);
|
||||
}
|
||||
if(!led_getState(ledMap.ALL[ledPingPongInfo.start]))
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.start, 1);
|
||||
}
|
||||
|
||||
void led_PingPong_next() {
|
||||
// Проверка на выход за границы массива
|
||||
uint8_t ledCount = sizeof(ledMap.ALL) / sizeof(ledMap.ALL[0]);
|
||||
|
||||
// Обработка движения "туда-обратно"
|
||||
if (ledPingPongInfo.globalDir) {
|
||||
// Двигаемся от начала к концу
|
||||
if (ledPingPongInfo.dir) {
|
||||
// Если не дошли до конца и не выходим за границы массива
|
||||
if (ledPingPongInfo.ledCurrent + 1 < ledCount && ledPingPongInfo.ledCurrent + 1 <= ledPingPongInfo.end) {
|
||||
// Включаем следующий светодиод и выключаем текущий
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent + 1, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 0);
|
||||
ledPingPongInfo.ledCurrent++;
|
||||
} else {
|
||||
// Достигли конца — сразу меняем направление и двигаемся обратно
|
||||
ledPingPongInfo.dir = 0;
|
||||
ledPingPongInfo.ledCurrent--;
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent + 1, 0);
|
||||
}
|
||||
} else {
|
||||
// Двигаемся от конца к началу
|
||||
if (ledPingPongInfo.ledCurrent > ledPingPongInfo.start) {
|
||||
// Включаем предыдущий светодиод и выключаем текущий
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent - 1, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 0);
|
||||
ledPingPongInfo.ledCurrent--;
|
||||
} else {
|
||||
// Достигли начала — сразу меняем направление и двигаемся вперед
|
||||
ledPingPongInfo.dir = 1;
|
||||
ledPingPongInfo.ledCurrent++;
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent - 1, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Двигаемся от конца к началу (начальное обратное направление)
|
||||
if (ledPingPongInfo.dir) {
|
||||
// Если не дошли до начала и не выходим за границы массива
|
||||
if (ledPingPongInfo.ledCurrent > ledPingPongInfo.start) {
|
||||
// Включаем предыдущий светодиод и выключаем текущий
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent - 1, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 0);
|
||||
ledPingPongInfo.ledCurrent--;
|
||||
} else {
|
||||
// Достигли начала — сразу меняем направление и двигаемся обратно
|
||||
ledPingPongInfo.dir = 0;
|
||||
ledPingPongInfo.ledCurrent++;
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent - 1, 0);
|
||||
}
|
||||
} else {
|
||||
// Двигаемся от начала к концу (обратное направление)
|
||||
if (ledPingPongInfo.ledCurrent + 1 < ledCount && ledPingPongInfo.ledCurrent + 1 <= ledPingPongInfo.end) {
|
||||
// Включаем следующий светодиод и выключаем текущий
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent + 1, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 0);
|
||||
ledPingPongInfo.ledCurrent++;
|
||||
} else {
|
||||
// Достигли конца — сразу меняем направление и двигаемся обратно
|
||||
ledPingPongInfo.dir = 1;
|
||||
ledPingPongInfo.ledCurrent--;
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent, 1);
|
||||
ledPingPongInfo.writeCallback(ledPingPongInfo.ledCurrent + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void led_showSpeed(uint8_t progressUP, uint8_t progressDOWN){
|
||||
memset(ledBlinkInfo, 0x00, sizeof(ledBlinkInfo));
|
||||
if (progressUP < 70 && progressUP)
|
||||
progressUP = 70;
|
||||
|
||||
if (progressUP > 100) {
|
||||
progressUP = map(progressUP, 100, 199, 0, 100);
|
||||
led_progressbar(13, 19, progressUP);
|
||||
led_progressbar(12, 10, 0);
|
||||
} else if (progressUP < 100) {
|
||||
progressUP = map((100 - progressUP), 0, 30, 0, 100);
|
||||
led_progressbar(13, 19, 0);
|
||||
led_progressbar(12, 10, progressUP);
|
||||
} else {
|
||||
led_progressbar(13, 19, 0);
|
||||
led_progressbar(12, 10, 0);
|
||||
}
|
||||
|
||||
if (progressDOWN < 70 && progressDOWN)
|
||||
progressDOWN = 70;
|
||||
|
||||
if (progressDOWN > 100) {
|
||||
progressDOWN = map(progressDOWN, 100, 199, 0, 100);
|
||||
led_progressbar(7, 0, progressDOWN);
|
||||
led_progressbar(9, 7, 0);
|
||||
} else if (progressDOWN < 100) {
|
||||
progressDOWN = map((100 - progressDOWN), 0, 30, 0, 100);
|
||||
led_progressbar(7, 0, 0);
|
||||
led_progressbar(9, 7, progressDOWN);
|
||||
} else {
|
||||
led_progressbar(7, 0, 0);
|
||||
led_progressbar(9, 7, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void led_clear() {
|
||||
memset(ledBuf, 0x00, sizeof(ledBuf));
|
||||
memset(ledBlinkInfo, 0x00, sizeof(ledBlinkInfo));
|
||||
led_show();
|
||||
}
|
||||
|
Reference in New Issue
Block a user