Merge branch 'master' into patch-api
This commit is contained in:
commit
55817f31f9
@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
// 10 bits
|
// 10 bits
|
||||||
#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION
|
#ifndef USERMOD_SN_PHOTORESISTOR_ADC_PRECISION
|
||||||
#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0
|
#define USERMOD_SN_PHOTORESISTOR_ADC_PRECISION 1024.0f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// resistor size 10K hms
|
// resistor size 10K hms
|
||||||
#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE
|
#ifndef USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE
|
||||||
#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0
|
#define USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE 10000.0f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// only report if differance grater than offset value
|
// only report if differance grater than offset value
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
#ifndef USERMOD_BATTERY_ADC_PRECISION
|
#ifndef USERMOD_BATTERY_ADC_PRECISION
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
// 12 bits
|
// 12 bits
|
||||||
#define USERMOD_BATTERY_ADC_PRECISION 4095.0
|
#define USERMOD_BATTERY_ADC_PRECISION 4095.0f
|
||||||
#else
|
#else
|
||||||
// 10 bits
|
// 10 bits
|
||||||
#define USERMOD_BATTERY_ADC_PRECISION 1024.0
|
#define USERMOD_BATTERY_ADC_PRECISION 1024.0f
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -39,11 +39,11 @@
|
|||||||
// https://batterybro.com/blogs/18650-wholesale-battery-reviews/18852515-when-to-recycle-18650-batteries-and-how-to-start-a-collection-center-in-your-vape-shop
|
// https://batterybro.com/blogs/18650-wholesale-battery-reviews/18852515-when-to-recycle-18650-batteries-and-how-to-start-a-collection-center-in-your-vape-shop
|
||||||
// Discharge voltage: 2.5 volt + .1 for personal safety
|
// Discharge voltage: 2.5 volt + .1 for personal safety
|
||||||
#ifndef USERMOD_BATTERY_MIN_VOLTAGE
|
#ifndef USERMOD_BATTERY_MIN_VOLTAGE
|
||||||
#define USERMOD_BATTERY_MIN_VOLTAGE 2.6
|
#define USERMOD_BATTERY_MIN_VOLTAGE 2.6f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef USERMOD_BATTERY_MAX_VOLTAGE
|
#ifndef USERMOD_BATTERY_MAX_VOLTAGE
|
||||||
#define USERMOD_BATTERY_MAX_VOLTAGE 4.2
|
#define USERMOD_BATTERY_MAX_VOLTAGE 4.2f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class UsermodBatteryBasic : public Usermod
|
class UsermodBatteryBasic : public Usermod
|
||||||
|
@ -272,7 +272,7 @@ class MultiRelay : public Usermod {
|
|||||||
|
|
||||||
void publishHomeAssistantAutodiscovery() {
|
void publishHomeAssistantAutodiscovery() {
|
||||||
for (uint8_t i = 0; i < MULTI_RELAY_MAX_RELAYS; i++) {
|
for (uint8_t i = 0; i < MULTI_RELAY_MAX_RELAYS; i++) {
|
||||||
char uid[16], json_str[1024], buf[128];
|
char uid[24], json_str[1024], buf[128];
|
||||||
size_t payload_size;
|
size_t payload_size;
|
||||||
sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i);
|
sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i);
|
||||||
|
|
||||||
|
@ -31,9 +31,33 @@ This usermod requires the `U8g2` and `Wire` libraries. See the
|
|||||||
`platformio_override.ini.sample` found in the Rotary Encoder
|
`platformio_override.ini.sample` found in the Rotary Encoder
|
||||||
UI usermod folder for how to include these using `platformio_override.ini`.
|
UI usermod folder for how to include these using `platformio_override.ini`.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
* `enabled` - enable/disable usermod
|
||||||
|
* `pin` - GPIO pins used for display; I2C displays use Clk & Data; SPI displays can use SCK, MOSI, CS, DC & RST
|
||||||
|
* `type` - display type in numeric format
|
||||||
|
* 1 = I2C SSD1306 128x32
|
||||||
|
* 2 = I2C SH1106 128x32
|
||||||
|
* 3 = I2C SSD1306 128x64 (4 double-height lines)
|
||||||
|
* 4 = I2C SSD1305 128x32
|
||||||
|
* 5 = I2C SSD1305 128x64 (4 double-height lines)
|
||||||
|
* 6 = SPI SSD1306 128x32
|
||||||
|
* 7 = SPI SSD1306 128x64 (4 double-height lines)
|
||||||
|
* `contrast` - set display contrast (higher contrast may reduce display lifetime)
|
||||||
|
* `refreshRateSec` - time in seconds for display refresh
|
||||||
|
* `screenTimeOutSec` - screen saver time-out in seconds
|
||||||
|
* `flip` - flip/rotate display 180°
|
||||||
|
* `sleepMode` - enable/disable screen saver
|
||||||
|
* `clockMode` - enable/disable clock display in screen saver mode
|
||||||
|
* `i2c-freq-kHz` - I2C clock frequency in kHz (may help reduce dropped frames, range: 400-3400)
|
||||||
|
|
||||||
## Change Log
|
## Change Log
|
||||||
|
|
||||||
2021-02
|
2021-02
|
||||||
* First public release
|
* First public release
|
||||||
|
|
||||||
2021-04
|
2021-04
|
||||||
* Adaptation for runtime configuration.
|
* Adaptation for runtime configuration.
|
||||||
|
|
||||||
|
2021-11
|
||||||
|
* Added configuration option description.
|
@ -25,6 +25,10 @@
|
|||||||
|
|
||||||
//The SCL and SDA pins are defined here.
|
//The SCL and SDA pins are defined here.
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#define HW_PIN_SCL 22
|
||||||
|
#define HW_PIN_SDA 21
|
||||||
|
#define HW_PIN_CLOCKSPI 18
|
||||||
|
#define HW_PIN_DATASPI 23
|
||||||
#ifndef FLD_PIN_SCL
|
#ifndef FLD_PIN_SCL
|
||||||
#define FLD_PIN_SCL 22
|
#define FLD_PIN_SCL 22
|
||||||
#endif
|
#endif
|
||||||
@ -47,6 +51,10 @@
|
|||||||
#define FLD_PIN_RESET 26
|
#define FLD_PIN_RESET 26
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
#define HW_PIN_SCL 5
|
||||||
|
#define HW_PIN_SDA 4
|
||||||
|
#define HW_PIN_CLOCKSPI 14
|
||||||
|
#define HW_PIN_DATASPI 13
|
||||||
#ifndef FLD_PIN_SCL
|
#ifndef FLD_PIN_SCL
|
||||||
#define FLD_PIN_SCL 5
|
#define FLD_PIN_SCL 5
|
||||||
#endif
|
#endif
|
||||||
@ -70,6 +78,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FLD_TYPE
|
||||||
|
#ifndef FLD_SPI_DEFAULT
|
||||||
|
#define FLD_TYPE SSD1306
|
||||||
|
#else
|
||||||
|
#define FLD_TYPE SSD1306_SPI
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// When to time out to the clock or blank the screen
|
// When to time out to the clock or blank the screen
|
||||||
// if SLEEP_MODE_ENABLED.
|
// if SLEEP_MODE_ENABLED.
|
||||||
#define SCREEN_TIMEOUT_MS 60*1000 // 1 min
|
#define SCREEN_TIMEOUT_MS 60*1000 // 1 min
|
||||||
@ -115,11 +131,11 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
#ifndef FLD_SPI_DEFAULT
|
#ifndef FLD_SPI_DEFAULT
|
||||||
int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1}; // I2C pins: SCL, SDA
|
int8_t ioPin[5] = {FLD_PIN_SCL, FLD_PIN_SDA, -1, -1, -1}; // I2C pins: SCL, SDA
|
||||||
uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000)
|
uint32_t ioFrequency = 400000; // in Hz (minimum is 100000, baseline is 400000 and maximum should be 3400000)
|
||||||
DisplayType type = SSD1306; // display type
|
|
||||||
#else
|
#else
|
||||||
int8_t ioPin[5] = {FLD_PIN_CLOCKSPI, FLD_PIN_DATASPI, FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // SPI pins: CLK, MOSI, CS, DC, RST
|
int8_t ioPin[5] = {FLD_PIN_CLOCKSPI, FLD_PIN_DATASPI, FLD_PIN_CS, FLD_PIN_DC, FLD_PIN_RESET}; // SPI pins: CLK, MOSI, CS, DC, RST
|
||||||
DisplayType type = SSD1306_SPI; // display type
|
uint32_t ioFrequency = 1000000; // in Hz (minimum is 500kHz, baseline is 1MHz and maximum should be 20MHz)
|
||||||
#endif
|
#endif
|
||||||
|
DisplayType type = FLD_TYPE; // display type
|
||||||
bool flip = false; // flip display 180°
|
bool flip = false; // flip display 180°
|
||||||
uint8_t contrast = 10; // screen contrast
|
uint8_t contrast = 10; // screen contrast
|
||||||
uint8_t lineHeight = 1; // 1 row or 2 rows
|
uint8_t lineHeight = 1; // 1 row or 2 rows
|
||||||
@ -127,6 +143,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms
|
uint32_t screenTimeout = SCREEN_TIMEOUT_MS; // in ms
|
||||||
bool sleepMode = true; // allow screen sleep?
|
bool sleepMode = true; // allow screen sleep?
|
||||||
bool clockMode = false; // display clock
|
bool clockMode = false; // display clock
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
// Next variables hold the previous known values to determine if redraw is
|
// Next variables hold the previous known values to determine if redraw is
|
||||||
// required.
|
// required.
|
||||||
@ -150,6 +167,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
|
|
||||||
// strings to reduce flash memory usage (used more than twice)
|
// strings to reduce flash memory usage (used more than twice)
|
||||||
static const char _name[];
|
static const char _name[];
|
||||||
|
static const char _enabled[];
|
||||||
static const char _contrast[];
|
static const char _contrast[];
|
||||||
static const char _refreshRate[];
|
static const char _refreshRate[];
|
||||||
static const char _screenTimeOut[];
|
static const char _screenTimeOut[];
|
||||||
@ -169,88 +187,72 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
// gets called once at boot. Do all initialization that doesn't depend on
|
// gets called once at boot. Do all initialization that doesn't depend on
|
||||||
// network here
|
// network here
|
||||||
void setup() {
|
void setup() {
|
||||||
if (type == NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
|
|
||||||
|
bool isHW;
|
||||||
|
PinOwner po = PinOwner::UM_FourLineDisplay;
|
||||||
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
if (type == SSD1306_SPI || type == SSD1306_SPI64) {
|
||||||
PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true}, { ioPin[2], true }, { ioPin[3], true}, { ioPin[4], true }};
|
isHW = (ioPin[0]==HW_PIN_CLOCKSPI && ioPin[1]==HW_PIN_DATASPI);
|
||||||
if (!pinManager.allocateMultiplePins(pins, 5, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
PinManagerPinType pins[5] = { { ioPin[0], true }, { ioPin[1], true }, { ioPin[2], true }, { ioPin[3], true }, { ioPin[4], true }};
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 5, po)) { type=NONE; return; }
|
||||||
} else {
|
} else {
|
||||||
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true} };
|
isHW = (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA);
|
||||||
if (!pinManager.allocateMultiplePins(pins, 2, PinOwner::UM_FourLineDisplay)) { type=NONE; return; }
|
PinManagerPinType pins[2] = { { ioPin[0], true }, { ioPin[1], true } };
|
||||||
|
if (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
|
||||||
|
if (!pinManager.allocateMultiplePins(pins, 2, po)) { type=NONE; return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("Allocating display."));
|
DEBUG_PRINTLN(F("Allocating display."));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SSD1306:
|
case SSD1306:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SH1106:
|
case SH1106:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SH1106_128X64_WINSTAR_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1306_64:
|
case SSD1306_64:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1305:
|
case SSD1305:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_NONAME_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SSD1305_64:
|
case SSD1305_64:
|
||||||
#ifdef ESP8266
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
||||||
if (!(ioPin[0]==5 && ioPin[1]==4))
|
else u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_SW_I2C(ioPin[0], ioPin[1]); // SCL, SDA, reset
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(U8X8_PIN_NONE, ioPin[0], ioPin[1]); // Pins are Reset, SCL, SDA
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
case SSD1306_SPI:
|
case SSD1306_SPI:
|
||||||
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
else
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
|
||||||
lineHeight = 1;
|
lineHeight = 1;
|
||||||
break;
|
break;
|
||||||
case SSD1306_SPI64:
|
case SSD1306_SPI64:
|
||||||
if (!(ioPin[0]==FLD_PIN_CLOCKSPI && ioPin[1]==FLD_PIN_DATASPI)) // if not overridden these sould be HW accellerated
|
if (!isHW) u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_SW_SPI(ioPin[0], ioPin[1], ioPin[2], ioPin[3], ioPin[4]);
|
else u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
||||||
else
|
|
||||||
u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[2], ioPin[3], ioPin[4]); // Pins are cs, dc, reset
|
|
||||||
lineHeight = 2;
|
lineHeight = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
u8x8 = nullptr;
|
u8x8 = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr == u8x8) {
|
if (nullptr == u8x8) {
|
||||||
DEBUG_PRINTLN(F("Display init failed."));
|
DEBUG_PRINTLN(F("Display init failed."));
|
||||||
for (byte i=0; i<5 && ioPin[i]>=0; i++) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
pinManager.deallocateMultiplePins((const uint8_t*)ioPin, (type == SSD1306_SPI || type == SSD1306_SPI64) ? 5 : 2, po);
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
initDone = true;
|
initDone = true;
|
||||||
DEBUG_PRINTLN(F("Starting display."));
|
DEBUG_PRINTLN(F("Starting display."));
|
||||||
if (!(type == SSD1306_SPI || type == SSD1306_SPI64)) u8x8->setBusClock(ioFrequency); // can be used for SPI too
|
/*if (!(type == SSD1306_SPI || type == SSD1306_SPI64))*/ u8x8->setBusClock(ioFrequency); // can be used for SPI too
|
||||||
u8x8->begin();
|
u8x8->begin();
|
||||||
setFlipMode(flip);
|
setFlipMode(flip);
|
||||||
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
setContrast(contrast); //Contrast setup will help to preserve OLED lifetime. In case OLED need to be brighter increase number up to 255
|
||||||
@ -266,7 +268,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* Da loop.
|
* Da loop.
|
||||||
*/
|
*/
|
||||||
void loop() {
|
void loop() {
|
||||||
if (millis() - lastUpdate < (clockMode?1000:refreshRate) || strip.isUpdating()) return;
|
if (!enabled || millis() - lastUpdate < (clockMode?1000:refreshRate) || strip.isUpdating()) return;
|
||||||
lastUpdate = millis();
|
lastUpdate = millis();
|
||||||
|
|
||||||
redraw(false);
|
redraw(false);
|
||||||
@ -276,40 +278,40 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* Wrappers for screen drawing
|
* Wrappers for screen drawing
|
||||||
*/
|
*/
|
||||||
void setFlipMode(uint8_t mode) {
|
void setFlipMode(uint8_t mode) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setFlipMode(mode);
|
u8x8->setFlipMode(mode);
|
||||||
}
|
}
|
||||||
void setContrast(uint8_t contrast) {
|
void setContrast(uint8_t contrast) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setContrast(contrast);
|
u8x8->setContrast(contrast);
|
||||||
}
|
}
|
||||||
void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) {
|
void drawString(uint8_t col, uint8_t row, const char *string, bool ignoreLH=false) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
||||||
if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string);
|
if (!ignoreLH && lineHeight==2) u8x8->draw1x2String(col, row, string);
|
||||||
else u8x8->drawString(col, row, string);
|
else u8x8->drawString(col, row, string);
|
||||||
}
|
}
|
||||||
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
void draw2x2String(uint8_t col, uint8_t row, const char *string) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
u8x8->setFont(u8x8_font_chroma48medium8_r);
|
||||||
u8x8->draw2x2String(col, row, string);
|
u8x8->draw2x2String(col, row, string);
|
||||||
}
|
}
|
||||||
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) {
|
void drawGlyph(uint8_t col, uint8_t row, char glyph, const uint8_t *font, bool ignoreLH=false) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setFont(font);
|
u8x8->setFont(font);
|
||||||
if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph);
|
if (!ignoreLH && lineHeight==2) u8x8->draw1x2Glyph(col, row, glyph);
|
||||||
else u8x8->drawGlyph(col, row, glyph);
|
else u8x8->drawGlyph(col, row, glyph);
|
||||||
}
|
}
|
||||||
uint8_t getCols() {
|
uint8_t getCols() {
|
||||||
if (type==NONE) return 0;
|
if (type==NONE || !enabled) return 0;
|
||||||
return u8x8->getCols();
|
return u8x8->getCols();
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->clear();
|
u8x8->clear();
|
||||||
}
|
}
|
||||||
void setPowerSave(uint8_t save) {
|
void setPowerSave(uint8_t save) {
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
u8x8->setPowerSave(save);
|
u8x8->setPowerSave(save);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +329,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
static bool showName = false;
|
static bool showName = false;
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
|
||||||
if (type==NONE) return;
|
if (type == NONE || !enabled) return;
|
||||||
if (overlayUntil > 0) {
|
if (overlayUntil > 0) {
|
||||||
if (now >= overlayUntil) {
|
if (now >= overlayUntil) {
|
||||||
// Time to display the overlay has elapsed.
|
// Time to display the overlay has elapsed.
|
||||||
@ -438,6 +440,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
|
|
||||||
void drawLine(uint8_t line, Line4Type lineType) {
|
void drawLine(uint8_t line, Line4Type lineType) {
|
||||||
char lineBuffer[LINE_BUFFER_SIZE];
|
char lineBuffer[LINE_BUFFER_SIZE];
|
||||||
|
uint8_t printedChars;
|
||||||
switch(lineType) {
|
switch(lineType) {
|
||||||
case FLD_LINE_BRIGHTNESS:
|
case FLD_LINE_BRIGHTNESS:
|
||||||
sprintf_P(lineBuffer, PSTR("Brightness %3d"), bri);
|
sprintf_P(lineBuffer, PSTR("Brightness %3d"), bri);
|
||||||
@ -452,10 +455,16 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
drawString(2, line*lineHeight, lineBuffer);
|
drawString(2, line*lineHeight, lineBuffer);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_MODE:
|
case FLD_LINE_MODE:
|
||||||
showCurrentEffectOrPalette(knownMode, JSON_mode_names, line);
|
printedChars = extractModeName(knownMode, JSON_mode_names, lineBuffer, LINE_BUFFER_SIZE-1);
|
||||||
|
for (;printedChars < getCols()-2 && printedChars < LINE_BUFFER_SIZE-3; printedChars++) lineBuffer[printedChars]=' ';
|
||||||
|
lineBuffer[printedChars] = 0;
|
||||||
|
drawString(2, line*lineHeight, lineBuffer);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_PALETTE:
|
case FLD_LINE_PALETTE:
|
||||||
showCurrentEffectOrPalette(knownPalette, JSON_palette_names, line);
|
printedChars = extractModeName(knownPalette, JSON_palette_names, lineBuffer, LINE_BUFFER_SIZE-1);
|
||||||
|
for (;printedChars < getCols()-2 && printedChars < LINE_BUFFER_SIZE-3; printedChars++) lineBuffer[printedChars]=' ';
|
||||||
|
lineBuffer[printedChars] = 0;
|
||||||
|
drawString(2, line*lineHeight, lineBuffer);
|
||||||
break;
|
break;
|
||||||
case FLD_LINE_TIME:
|
case FLD_LINE_TIME:
|
||||||
default:
|
default:
|
||||||
@ -464,41 +473,6 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the current effect or palette (desiredEntry)
|
|
||||||
* on the appropriate line (row).
|
|
||||||
*/
|
|
||||||
void showCurrentEffectOrPalette(int knownMode, const char *qstring, uint8_t row) {
|
|
||||||
char lineBuffer[LINE_BUFFER_SIZE];
|
|
||||||
uint8_t qComma = 0;
|
|
||||||
bool insideQuotes = false;
|
|
||||||
uint8_t printedChars = 0;
|
|
||||||
char singleJsonSymbol;
|
|
||||||
|
|
||||||
// Find the mode name in JSON
|
|
||||||
for (size_t i = 0; i < strlen_P(qstring); i++) {
|
|
||||||
singleJsonSymbol = pgm_read_byte_near(qstring + i);
|
|
||||||
if (singleJsonSymbol == '\0') break;
|
|
||||||
switch (singleJsonSymbol) {
|
|
||||||
case '"':
|
|
||||||
insideQuotes = !insideQuotes;
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
break;
|
|
||||||
case ',':
|
|
||||||
qComma++;
|
|
||||||
default:
|
|
||||||
if (!insideQuotes || (qComma != knownMode)) break;
|
|
||||||
lineBuffer[printedChars++] = singleJsonSymbol;
|
|
||||||
}
|
|
||||||
if ((qComma > knownMode) || (printedChars >= getCols()-2) || printedChars >= sizeof(lineBuffer)-2) break;
|
|
||||||
}
|
|
||||||
for (;printedChars < getCols()-2 && printedChars < sizeof(lineBuffer)-2; printedChars++) lineBuffer[printedChars]=' ';
|
|
||||||
lineBuffer[printedChars] = 0;
|
|
||||||
drawString(2, row*lineHeight, lineBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If there screen is off or in clock is displayed,
|
* If there screen is off or in clock is displayed,
|
||||||
* this will return true. This allows us to throw away
|
* this will return true. This allows us to throw away
|
||||||
@ -506,6 +480,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* to wake up the screen.
|
* to wake up the screen.
|
||||||
*/
|
*/
|
||||||
bool wakeDisplay() {
|
bool wakeDisplay() {
|
||||||
|
if (type == NONE || !enabled) return false;
|
||||||
knownHour = 99;
|
knownHour = 99;
|
||||||
if (displayTurnedOff) {
|
if (displayTurnedOff) {
|
||||||
// Turn the display back on
|
// Turn the display back on
|
||||||
@ -522,6 +497,8 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* Clears the screen and prints on the middle two lines.
|
* Clears the screen and prints on the middle two lines.
|
||||||
*/
|
*/
|
||||||
void overlay(const char* line1, const char *line2, long showHowLong) {
|
void overlay(const char* line1, const char *line2, long showHowLong) {
|
||||||
|
if (type == NONE || !enabled) return;
|
||||||
|
|
||||||
if (displayTurnedOff) {
|
if (displayTurnedOff) {
|
||||||
// Turn the display back on (includes clear())
|
// Turn the display back on (includes clear())
|
||||||
sleepOrClock(false);
|
sleepOrClock(false);
|
||||||
@ -583,6 +560,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
* the useAMPM configuration.
|
* the useAMPM configuration.
|
||||||
*/
|
*/
|
||||||
void showTime(bool fullScreen = true) {
|
void showTime(bool fullScreen = true) {
|
||||||
|
if (type == NONE || !enabled) return;
|
||||||
char lineBuffer[LINE_BUFFER_SIZE];
|
char lineBuffer[LINE_BUFFER_SIZE];
|
||||||
|
|
||||||
updateLocalTime();
|
updateLocalTime();
|
||||||
@ -676,10 +654,12 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
*/
|
*/
|
||||||
void addToConfig(JsonObject& root) {
|
void addToConfig(JsonObject& root) {
|
||||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||||
|
top[FPSTR(_enabled)] = enabled;
|
||||||
JsonArray io_pin = top.createNestedArray("pin");
|
JsonArray io_pin = top.createNestedArray("pin");
|
||||||
for (byte i=0; i<5; i++) io_pin.add(ioPin[i]);
|
for (byte i=0; i<5; i++) io_pin.add(ioPin[i]);
|
||||||
top["help4PinTypes"] = F("Clk,Data,CS,DC,RST"); // help for Settings page
|
top["help4Pins"] = F("Clk,Data,CS,DC,RST"); // help for Settings page
|
||||||
top["type"] = type;
|
top["type"] = type;
|
||||||
|
top["help4Type"] = F("1=SSD1306,2=SH1106,3=SSD1306_128x64,4=SSD1305,5=SSD1305_128x64,6=SSD1306_SPI,7=SSD1306_SPI_128x64"); // help for Settings page
|
||||||
top[FPSTR(_flip)] = (bool) flip;
|
top[FPSTR(_flip)] = (bool) flip;
|
||||||
top[FPSTR(_contrast)] = contrast;
|
top[FPSTR(_contrast)] = contrast;
|
||||||
top[FPSTR(_refreshRate)] = refreshRate/1000;
|
top[FPSTR(_refreshRate)] = refreshRate/1000;
|
||||||
@ -710,6 +690,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enabled = top[FPSTR(_enabled)] | enabled;
|
||||||
newType = top["type"] | newType;
|
newType = top["type"] | newType;
|
||||||
for (byte i=0; i<5; i++) newPin[i] = top["pin"][i] | ioPin[i];
|
for (byte i=0; i<5; i++) newPin[i] = top["pin"][i] | ioPin[i];
|
||||||
flip = top[FPSTR(_flip)] | flip;
|
flip = top[FPSTR(_flip)] | flip;
|
||||||
@ -718,6 +699,9 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
screenTimeout = (top[FPSTR(_screenTimeOut)] | screenTimeout/1000) * 1000;
|
screenTimeout = (top[FPSTR(_screenTimeOut)] | screenTimeout/1000) * 1000;
|
||||||
sleepMode = top[FPSTR(_sleepMode)] | sleepMode;
|
sleepMode = top[FPSTR(_sleepMode)] | sleepMode;
|
||||||
clockMode = top[FPSTR(_clockMode)] | clockMode;
|
clockMode = top[FPSTR(_clockMode)] | clockMode;
|
||||||
|
if (newType == SSD1306_SPI || newType == SSD1306_SPI64)
|
||||||
|
ioFrequency = min(20000, max(500, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency
|
||||||
|
else
|
||||||
ioFrequency = min(3400, max(100, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency
|
ioFrequency = min(3400, max(100, (int)(top[FPSTR(_busClkFrequency)] | ioFrequency/1000))) * 1000; // limit frequency
|
||||||
|
|
||||||
DEBUG_PRINT(FPSTR(_name));
|
DEBUG_PRINT(FPSTR(_name));
|
||||||
@ -733,10 +717,10 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
for (byte i=0; i<5; i++) if (ioPin[i] != newPin[i]) { pinsChanged = true; break; }
|
||||||
if (pinsChanged || type!=newType) {
|
if (pinsChanged || type!=newType) {
|
||||||
if (type != NONE) delete u8x8;
|
if (type != NONE) delete u8x8;
|
||||||
for (byte i=0; i<5; i++) {
|
PinOwner po = PinOwner::UM_FourLineDisplay;
|
||||||
if (ioPin[i]>=0) pinManager.deallocatePin(ioPin[i], PinOwner::UM_FourLineDisplay);
|
if (ioPin[0]==HW_PIN_SCL && ioPin[1]==HW_PIN_SDA) po = PinOwner::HW_I2C; // allow multiple allocations of HW I2C bus pins
|
||||||
ioPin[i] = newPin[i];
|
pinManager.deallocateMultiplePins((const uint8_t *)ioPin, (type == SSD1306_SPI || type == SSD1306_SPI64) ? 5 : 2, po);
|
||||||
}
|
for (byte i=0; i<5; i++) ioPin[i] = newPin[i];
|
||||||
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
if (ioPin[0]<0 || ioPin[1]<0) { // data & clock must be > -1
|
||||||
type = NONE;
|
type = NONE;
|
||||||
return true;
|
return true;
|
||||||
@ -750,7 +734,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
if (needsRedraw && !wakeDisplay()) redraw(true);
|
if (needsRedraw && !wakeDisplay()) redraw(true);
|
||||||
}
|
}
|
||||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||||
return !(top[_busClkFrequency]).isNull();
|
return !top[FPSTR(_enabled)].isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -764,6 +748,7 @@ class FourLineDisplayUsermod : public Usermod {
|
|||||||
|
|
||||||
// strings to reduce flash memory usage (used more than twice)
|
// strings to reduce flash memory usage (used more than twice)
|
||||||
const char FourLineDisplayUsermod::_name[] PROGMEM = "4LineDisplay";
|
const char FourLineDisplayUsermod::_name[] PROGMEM = "4LineDisplay";
|
||||||
|
const char FourLineDisplayUsermod::_enabled[] PROGMEM = "enabled";
|
||||||
const char FourLineDisplayUsermod::_contrast[] PROGMEM = "contrast";
|
const char FourLineDisplayUsermod::_contrast[] PROGMEM = "contrast";
|
||||||
const char FourLineDisplayUsermod::_refreshRate[] PROGMEM = "refreshRateSec";
|
const char FourLineDisplayUsermod::_refreshRate[] PROGMEM = "refreshRateSec";
|
||||||
const char FourLineDisplayUsermod::_screenTimeOut[] PROGMEM = "screenTimeOutSec";
|
const char FourLineDisplayUsermod::_screenTimeOut[] PROGMEM = "screenTimeOutSec";
|
||||||
|
@ -81,7 +81,6 @@
|
|||||||
#define SEGLEN _virtualSegmentLength
|
#define SEGLEN _virtualSegmentLength
|
||||||
#define SEGACT SEGMENT.stop
|
#define SEGACT SEGMENT.stop
|
||||||
#define SPEED_FORMULA_L 5U + (50U*(255U - SEGMENT.speed))/SEGLEN
|
#define SPEED_FORMULA_L 5U + (50U*(255U - SEGMENT.speed))/SEGLEN
|
||||||
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))
|
|
||||||
|
|
||||||
// some common colors
|
// some common colors
|
||||||
#define RED (uint32_t)0xFF0000
|
#define RED (uint32_t)0xFF0000
|
||||||
@ -409,8 +408,9 @@ class WS2812FX {
|
|||||||
* Flags that before the next effect is calculated,
|
* Flags that before the next effect is calculated,
|
||||||
* the internal segment state should be reset.
|
* the internal segment state should be reset.
|
||||||
* Call resetIfRequired before calling the next effect function.
|
* Call resetIfRequired before calling the next effect function.
|
||||||
|
* Safe to call from interrupts and network requests.
|
||||||
*/
|
*/
|
||||||
inline void reset() { _requiresReset = true; }
|
inline void markForReset() { _requiresReset = true; }
|
||||||
private:
|
private:
|
||||||
uint16_t _dataLen = 0;
|
uint16_t _dataLen = 0;
|
||||||
bool _requiresReset = false;
|
bool _requiresReset = false;
|
||||||
|
@ -67,7 +67,12 @@
|
|||||||
//do not call this method from system context (network callback)
|
//do not call this method from system context (network callback)
|
||||||
void WS2812FX::finalizeInit(void)
|
void WS2812FX::finalizeInit(void)
|
||||||
{
|
{
|
||||||
RESET_RUNTIME;
|
//reset segment runtimes
|
||||||
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
|
||||||
|
_segment_runtimes[i].markForReset();
|
||||||
|
_segment_runtimes[i].resetIfRequired();
|
||||||
|
}
|
||||||
|
|
||||||
_hasWhiteChannel = _isOffRefreshRequired = false;
|
_hasWhiteChannel = _isOffRefreshRequired = false;
|
||||||
|
|
||||||
//if busses failed to load, add default (fresh install, FS issue, ...)
|
//if busses failed to load, add default (fresh install, FS issue, ...)
|
||||||
@ -373,7 +378,7 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) {
|
|||||||
|
|
||||||
if (_segments[segid].mode != m)
|
if (_segments[segid].mode != m)
|
||||||
{
|
{
|
||||||
_segment_runtimes[segid].reset();
|
_segment_runtimes[segid].markForReset();
|
||||||
_segments[segid].mode = m;
|
_segments[segid].mode = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -612,12 +617,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping,
|
|||||||
seg.spacing = spacing;
|
seg.spacing = spacing;
|
||||||
}
|
}
|
||||||
if (offset < UINT16_MAX) seg.offset = offset;
|
if (offset < UINT16_MAX) seg.offset = offset;
|
||||||
_segment_runtimes[n].reset();
|
_segment_runtimes[n].markForReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::restartRuntime() {
|
void WS2812FX::restartRuntime() {
|
||||||
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
|
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) {
|
||||||
_segment_runtimes[i].reset();
|
_segment_runtimes[i].markForReset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,9 +653,9 @@ void WS2812FX::resetSegments() {
|
|||||||
_segments[i].cct = 127;
|
_segments[i].cct = 127;
|
||||||
_segments[i].speed = DEFAULT_SPEED;
|
_segments[i].speed = DEFAULT_SPEED;
|
||||||
_segments[i].intensity = DEFAULT_INTENSITY;
|
_segments[i].intensity = DEFAULT_INTENSITY;
|
||||||
_segment_runtimes[i].reset();
|
_segment_runtimes[i].markForReset();
|
||||||
}
|
}
|
||||||
_segment_runtimes[0].reset();
|
_segment_runtimes[0].markForReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::makeAutoSegments() {
|
void WS2812FX::makeAutoSegments() {
|
||||||
|
@ -72,21 +72,23 @@ void doublePressAction(uint8_t b)
|
|||||||
bool isButtonPressed(uint8_t i)
|
bool isButtonPressed(uint8_t i)
|
||||||
{
|
{
|
||||||
if (btnPin[i]<0) return false;
|
if (btnPin[i]<0) return false;
|
||||||
|
uint8_t pin = btnPin[i];
|
||||||
|
|
||||||
switch (buttonType[i]) {
|
switch (buttonType[i]) {
|
||||||
case BTN_TYPE_NONE:
|
case BTN_TYPE_NONE:
|
||||||
case BTN_TYPE_RESERVED:
|
case BTN_TYPE_RESERVED:
|
||||||
break;
|
break;
|
||||||
case BTN_TYPE_PUSH:
|
case BTN_TYPE_PUSH:
|
||||||
case BTN_TYPE_SWITCH:
|
case BTN_TYPE_SWITCH:
|
||||||
if (digitalRead(btnPin[i]) == LOW) return true;
|
if (digitalRead(pin) == LOW) return true;
|
||||||
break;
|
break;
|
||||||
case BTN_TYPE_PUSH_ACT_HIGH:
|
case BTN_TYPE_PUSH_ACT_HIGH:
|
||||||
case BTN_TYPE_PIR_SENSOR:
|
case BTN_TYPE_PIR_SENSOR:
|
||||||
if (digitalRead(btnPin[i]) == HIGH) return true;
|
if (digitalRead(pin) == HIGH) return true;
|
||||||
break;
|
break;
|
||||||
case BTN_TYPE_TOUCH:
|
case BTN_TYPE_TOUCH:
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
if (touchRead(btnPin[i]) <= touchThreshold) return true;
|
if (touchRead(pin) <= touchThreshold) return true;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,13 @@ bool PinManagerClass::allocateMultiplePins(const managed_pin_type * mptArray, by
|
|||||||
byte bi = gpio - 8*by;
|
byte bi = gpio - 8*by;
|
||||||
bitWrite(pinAlloc[by], bi, true);
|
bitWrite(pinAlloc[by], bi, true);
|
||||||
ownerTag[gpio] = tag;
|
ownerTag[gpio] = tag;
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
DEBUG_PRINT(F("PIN ALLOC: Pin "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" allocated by "));
|
||||||
|
DebugPrintOwnerTag(tag);
|
||||||
|
DEBUG_PRINTLN(F(""));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -155,6 +162,13 @@ bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
|||||||
byte bi = gpio - 8*by;
|
byte bi = gpio - 8*by;
|
||||||
bitWrite(pinAlloc[by], bi, true);
|
bitWrite(pinAlloc[by], bi, true);
|
||||||
ownerTag[gpio] = tag;
|
ownerTag[gpio] = tag;
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
DEBUG_PRINT(F("PIN ALLOC: Pin "));
|
||||||
|
DEBUG_PRINT(gpio);
|
||||||
|
DEBUG_PRINT(F(" allocated by "));
|
||||||
|
DebugPrintOwnerTag(tag);
|
||||||
|
DEBUG_PRINTLN(F(""));
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({0});
|
|||||||
WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({BTNPIN});
|
WLED_GLOBAL int8_t btnPin[WLED_MAX_BUTTONS] _INIT({BTNPIN});
|
||||||
#endif
|
#endif
|
||||||
#ifndef RLYPIN
|
#ifndef RLYPIN
|
||||||
WLED_GLOBAL int8_t rlyPin _INIT(12);
|
WLED_GLOBAL int8_t rlyPin _INIT(-1);
|
||||||
#else
|
#else
|
||||||
WLED_GLOBAL int8_t rlyPin _INIT(RLYPIN);
|
WLED_GLOBAL int8_t rlyPin _INIT(RLYPIN);
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,36 +80,41 @@ float asin_t(float x) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://stackoverflow.com/a/42542593
|
// declare a template with no implementation, and only one specialization
|
||||||
#define A 0.0776509570923569
|
// this allows hiding the constants, while ensuring ODR causes optimizations
|
||||||
#define B -0.287434475393028
|
// to still apply. (Fixes issues with conflicting 3rd party #define's)
|
||||||
#define C ((HALF_PI/2) - A - B)
|
template <typename T> T atan_t(T x);
|
||||||
|
template<>
|
||||||
//polynominal factors for approximation between 1 and 5
|
|
||||||
#define C0 0.089494f
|
|
||||||
#define C1 0.974207f
|
|
||||||
#define C2 -0.326175f
|
|
||||||
#define C3 0.05375f
|
|
||||||
#define C4 -0.003445f
|
|
||||||
|
|
||||||
float atan_t(float x) {
|
float atan_t(float x) {
|
||||||
bool neg = (x < 0);
|
//For A/B/C, see https://stackoverflow.com/a/42542593
|
||||||
|
static const double A { 0.0776509570923569 };
|
||||||
|
static const double B { -0.287434475393028 };
|
||||||
|
static const double C { ((HALF_PI/2) - A - B) };
|
||||||
|
// polynominal factors for approximation between 1 and 5
|
||||||
|
static const float C0 { 0.089494f };
|
||||||
|
static const float C1 { 0.974207f };
|
||||||
|
static const float C2 { -0.326175f };
|
||||||
|
static const float C3 { 0.05375f };
|
||||||
|
static const float C4 { -0.003445f };
|
||||||
|
|
||||||
#ifdef WLED_DEBUG_MATH
|
#ifdef WLED_DEBUG_MATH
|
||||||
float xinput = x;
|
float xinput = x;
|
||||||
#endif
|
#endif
|
||||||
|
bool neg = (x < 0);
|
||||||
x = std::abs(x);
|
x = std::abs(x);
|
||||||
float res;
|
float res;
|
||||||
if (x > 5.0f) { //atan(x) converges to pi/2 - (1/x) for large values
|
if (x > 5.0f) { // atan(x) converges to pi/2 - (1/x) for large values
|
||||||
res = HALF_PI - (1.0f/x);
|
res = HALF_PI - (1.0f/x);
|
||||||
}
|
} else if (x > 1.0f) { //1 < x < 5
|
||||||
else if (x > 1.0f) { //1 < x < 5
|
|
||||||
float xx = x * x;
|
float xx = x * x;
|
||||||
res = (C4*xx*xx)+(C3*xx*x)+(C2*xx)+(C1*x)+C0;
|
res = (C4*xx*xx)+(C3*xx*x)+(C2*xx)+(C1*x)+C0;
|
||||||
} else { //this approximation is only for x <= 1
|
} else { // this approximation is only for x <= 1
|
||||||
float xx = x * x;
|
float xx = x * x;
|
||||||
res = ((A*xx + B)*xx + C)*x;
|
res = ((A*xx + B)*xx + C)*x;
|
||||||
}
|
}
|
||||||
if (neg) res = -res;
|
if (neg) {
|
||||||
|
res = -res;
|
||||||
|
}
|
||||||
#ifdef WLED_DEBUG_MATH
|
#ifdef WLED_DEBUG_MATH
|
||||||
Serial.printf("atan,%f,%f,%f\n",xinput,res,atan(xinput));
|
Serial.printf("atan,%f,%f,%f\n",xinput,res,atan(xinput));
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,8 +46,6 @@ void handleSerial()
|
|||||||
static byte red = 0x00;
|
static byte red = 0x00;
|
||||||
static byte green = 0x00;
|
static byte green = 0x00;
|
||||||
|
|
||||||
uint16_t nBytes = 0;
|
|
||||||
|
|
||||||
while (Serial.available() > 0)
|
while (Serial.available() > 0)
|
||||||
{
|
{
|
||||||
yield();
|
yield();
|
||||||
|
Loading…
Reference in New Issue
Block a user