mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 20:56:35 +00:00
Add generic SystemWaitIfBusy() to fix WS2812 led flicker
Add generic SystemWaitIfBusy() to fix WS2812 led flicker
This commit is contained in:
parent
4be618fe7b
commit
fc67cca8b4
@ -310,6 +310,7 @@ struct TasmotaGlobal_t {
|
|||||||
bool no_autoexec; // Disable autoexec
|
bool no_autoexec; // Disable autoexec
|
||||||
|
|
||||||
uint8_t user_globals[3]; // User set global temp/hum/press
|
uint8_t user_globals[3]; // User set global temp/hum/press
|
||||||
|
uint8_t busy_time; // Time in ms to allow executing of time critical functions
|
||||||
uint8_t init_state; // Tasmota init state
|
uint8_t init_state; // Tasmota init state
|
||||||
uint8_t heartbeat_inverted; // Heartbeat pulse inverted flag
|
uint8_t heartbeat_inverted; // Heartbeat pulse inverted flag
|
||||||
uint8_t spi_enabled; // SPI configured
|
uint8_t spi_enabled; // SPI configured
|
||||||
|
@ -2210,6 +2210,31 @@ bool TimeReachedUsec(uint32_t timer)
|
|||||||
return (passed >= 0);
|
return (passed >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemSetBusy(uint32_t busy) {
|
||||||
|
/*
|
||||||
|
TasmotaGlobal.busy_time = millis();
|
||||||
|
SetNextTimeInterval(TasmotaGlobal.busy_time, busy +1);
|
||||||
|
if (!TasmotaGlobal.busy_time) {
|
||||||
|
TasmotaGlobal.busy_time++;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
TasmotaGlobal.busy_time = busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemWaitIfBusy(void) {
|
||||||
|
if (TasmotaGlobal.busy_time) {
|
||||||
|
/*
|
||||||
|
// Calls to millis() interrupt RMT and defeats our goal
|
||||||
|
if (!TimeReached(TasmotaGlobal.busy_time)) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
delay(TasmotaGlobal.busy_time);
|
||||||
|
|
||||||
|
TasmotaGlobal.busy_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Syslog
|
* Syslog
|
||||||
*
|
*
|
||||||
|
@ -39,15 +39,15 @@ typedef NeoPixelBus<NeoGrbwFeature, NeoEsp32RmtNSk6812Method> neopixel_sk6812_gr
|
|||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Native functions mapped to Berry functions
|
* Native functions mapped to Berry functions
|
||||||
*
|
*
|
||||||
* import unishox
|
* import unishox
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
// # Native commands
|
// # Native commands
|
||||||
// # 00 : ctor
|
// # 00 : ctor
|
||||||
// # 01 : begin void -> void
|
// # 01 : begin void -> void
|
||||||
// # 02 : show void -> void
|
// # 02 : show void -> void
|
||||||
// # 03 : CanShow void -> bool
|
// # 03 : CanShow void -> bool
|
||||||
@ -88,7 +88,7 @@ extern "C" {
|
|||||||
int32_t argc = be_top(vm); // Get the number of arguments
|
int32_t argc = be_top(vm); // Get the number of arguments
|
||||||
if (argc >= 2 && be_isint(vm, 2)) {
|
if (argc >= 2 && be_isint(vm, 2)) {
|
||||||
int32_t cmd = be_toint(vm, 2);
|
int32_t cmd = be_toint(vm, 2);
|
||||||
|
|
||||||
if (0 == cmd) { // 00 : ctor (leds:int, gpio:int) -> void
|
if (0 == cmd) { // 00 : ctor (leds:int, gpio:int) -> void
|
||||||
if (!(argc >= 6 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6))) {
|
if (!(argc >= 6 && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5) && be_isint(vm, 6))) {
|
||||||
be_raise(vm, "value_error", "bad arguments for neopixelbus:ctor");
|
be_raise(vm, "value_error", "bad arguments for neopixelbus:ctor");
|
||||||
@ -136,6 +136,7 @@ extern "C" {
|
|||||||
case 2: // # 02 : show void -> void
|
case 2: // # 02 : show void -> void
|
||||||
if (s_ws2812_grb) s_ws2812_grb->Show();
|
if (s_ws2812_grb) s_ws2812_grb->Show();
|
||||||
if (s_sk6812_grbw) s_sk6812_grbw->Show();
|
if (s_sk6812_grbw) s_sk6812_grbw->Show();
|
||||||
|
SystemSetBusy(4);
|
||||||
break;
|
break;
|
||||||
case 3: // # 03 : CanShow void -> bool
|
case 3: // # 03 : CanShow void -> bool
|
||||||
if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->CanShow());
|
if (s_ws2812_grb) be_pushbool(vm, s_ws2812_grb->CanShow());
|
||||||
@ -154,7 +155,7 @@ extern "C" {
|
|||||||
uint8_t * pixels;
|
uint8_t * pixels;
|
||||||
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
|
if (s_ws2812_grb) pixels = s_ws2812_grb->Pixels();
|
||||||
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
|
if (s_sk6812_grbw) pixels = s_sk6812_grbw->Pixels();
|
||||||
|
|
||||||
be_pushcomptr(vm, pixels);
|
be_pushcomptr(vm, pixels);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -196,11 +197,11 @@ extern "C" {
|
|||||||
|
|
||||||
if (s_ws2812_grb) {
|
if (s_ws2812_grb) {
|
||||||
RgbColor rgb = s_ws2812_grb->GetPixelColor(idx);
|
RgbColor rgb = s_ws2812_grb->GetPixelColor(idx);
|
||||||
be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B);
|
be_pushint(vm, (rgb.R << 16) | (rgb.G << 8) | rgb.B);
|
||||||
}
|
}
|
||||||
if (s_sk6812_grbw) {
|
if (s_sk6812_grbw) {
|
||||||
RgbwColor rgbw = s_sk6812_grbw->GetPixelColor(idx);
|
RgbwColor rgbw = s_sk6812_grbw->GetPixelColor(idx);
|
||||||
be_pushint(vm, (rgbw.W << 24) | (rgb.R << 16) | (rgb.G << 8) | rgb.B);
|
be_pushint(vm, (rgbw.W << 24) | (rgb.R << 16) | (rgb.G << 8) | rgb.B);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -212,6 +212,11 @@ long wsmap(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;
|
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ws2812LibStripShow(void) {
|
||||||
|
strip->Show();
|
||||||
|
SystemSetBusy(Settings->light_pixels >> 2); // 256 / 64 = 4
|
||||||
|
}
|
||||||
|
|
||||||
void Ws2812StripShow(void)
|
void Ws2812StripShow(void)
|
||||||
{
|
{
|
||||||
#if (USE_WS2812_CTYPE > NEO_3LED)
|
#if (USE_WS2812_CTYPE > NEO_3LED)
|
||||||
@ -232,7 +237,7 @@ void Ws2812StripShow(void)
|
|||||||
strip->SetPixelColor(i, c);
|
strip->SetPixelColor(i, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strip->Show();
|
Ws2812LibStripShow();
|
||||||
}
|
}
|
||||||
|
|
||||||
int mod(int a, int b)
|
int mod(int a, int b)
|
||||||
@ -549,7 +554,7 @@ void Ws2812DDP(void)
|
|||||||
void Ws2812Clear(void)
|
void Ws2812Clear(void)
|
||||||
{
|
{
|
||||||
strip->ClearTo(0);
|
strip->ClearTo(0);
|
||||||
strip->Show();
|
Ws2812LibStripShow();
|
||||||
Ws2812.show_next = 1;
|
Ws2812.show_next = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +580,7 @@ void Ws2812SetColor(uint32_t led, uint8_t red, uint8_t green, uint8_t blue, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!Ws2812.suspend_update) {
|
if (!Ws2812.suspend_update) {
|
||||||
strip->Show();
|
Ws2812LibStripShow();
|
||||||
Ws2812.show_next = 1;
|
Ws2812.show_next = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -616,7 +621,7 @@ void Ws2812ForceSuspend (void)
|
|||||||
void Ws2812ForceUpdate (void)
|
void Ws2812ForceUpdate (void)
|
||||||
{
|
{
|
||||||
Ws2812.suspend_update = false;
|
Ws2812.suspend_update = false;
|
||||||
strip->Show();
|
Ws2812LibStripShow();
|
||||||
Ws2812.show_next = 1;
|
Ws2812.show_next = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -634,7 +639,7 @@ bool Ws2812SetChannels(void)
|
|||||||
void Ws2812ShowScheme(void)
|
void Ws2812ShowScheme(void)
|
||||||
{
|
{
|
||||||
uint32_t scheme = Settings->light_scheme - Ws2812.scheme_offset;
|
uint32_t scheme = Settings->light_scheme - Ws2812.scheme_offset;
|
||||||
|
|
||||||
#ifdef USE_NETWORK_LIGHT_SCHEMES
|
#ifdef USE_NETWORK_LIGHT_SCHEMES
|
||||||
if ((scheme != 9) && (ddp_udp_up)) {
|
if ((scheme != 9) && (ddp_udp_up)) {
|
||||||
ddp_udp.stop();
|
ddp_udp.stop();
|
||||||
@ -797,7 +802,7 @@ size_t Ws2812StripGetPixelSize(void) {
|
|||||||
// return true if strip was dirty and an actual refresh was triggered
|
// return true if strip was dirty and an actual refresh was triggered
|
||||||
bool Ws2812StripRefresh(void) {
|
bool Ws2812StripRefresh(void) {
|
||||||
if (strip->IsDirty()) {
|
if (strip->IsDirty()) {
|
||||||
strip->Show();
|
Ws2812LibStripShow();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -317,11 +317,8 @@ uint16_t AdcRead(uint32_t pin, uint32_t factor) {
|
|||||||
// factor 3 = 8 samples
|
// factor 3 = 8 samples
|
||||||
// factor 4 = 16 samples
|
// factor 4 = 16 samples
|
||||||
// factor 5 = 32 samples
|
// factor 5 = 32 samples
|
||||||
#ifdef USE_LIGHT
|
SystemWaitIfBusy();
|
||||||
if ((XLGT_01 == TasmotaGlobal.light_driver) && LightPower()) {
|
|
||||||
delay(5); // analogRead() interferes with DMA/RMT so wait for a decent amount of time
|
|
||||||
}
|
|
||||||
#endif // USE_LIGHT
|
|
||||||
uint32_t samples = 1 << factor;
|
uint32_t samples = 1 << factor;
|
||||||
uint32_t analog = 0;
|
uint32_t analog = 0;
|
||||||
for (uint32_t i = 0; i < samples; i++) {
|
for (uint32_t i = 0; i < samples; i++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user