Now using display_options instead of display_type

This commit is contained in:
Ajith Vasudevan 2021-03-03 18:14:30 +05:30
commit 850aff3ab6
82 changed files with 1559 additions and 171 deletions

View File

@ -7,7 +7,7 @@
- [ ] Only relevant files were touched
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
- [ ] The code change is tested and works on Tasmota core ESP8266 V.2.7.4.9
- [ ] The code change is tested and works on Tasmota core ESP32 V.1.0.5-rc6
- [ ] The code change is tested and works with core ESP32 V.1.0.5
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_

View File

@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
### Changed
- TuyaMcu dimmer timeout (#11121)
- TasmotaSerial library from v3.2.0 to v3.3.0
### Fixed
- Refactor acceleration function for shutter stepper and servo (#11088)

View File

@ -87,6 +87,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
### Changed
- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121)
- TasmotaSerial library from v3.2.0 to v3.3.0
### Fixed
- Refactor acceleration function for shutter stepper and servo [#11088](https://github.com/arendst/Tasmota/issues/11088)

View File

@ -212,6 +212,9 @@ char * copyStr(const char * str) {
return cpy;
}
const char ext_invalid_mem[] PROGMEM = "<--INVALID-->";
const uint32_t min_valid_ptr = 0x3FF00000; // addresses below this line are invalid
int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list va) {
va_list va_cpy;
va_copy(va_cpy, va);
@ -222,7 +225,7 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
char * fmt = fmt_cpy;
const uint32_t ALLOC_SIZE = 12;
static char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
static const char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
uint32_t alloc_idx = 0;
static char hex[20]; // buffer used for 64 bits, favor RAM instead of stack to remove pressure
@ -264,12 +267,13 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
fmt++;
uint32_t cur_val = va_arg(va, uint32_t); // current value
const char ** cur_val_ptr = va_cur_ptr4(va, const char*); // pointer to value on stack
char * new_val_str = (char*) "";
const char * new_val_str = "";
switch (*fmt) {
case 'H': // Hex, decimals indicates the length, default 2
{
if (decimals < 0) { decimals = 0; }
if (decimals > 0) {
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else if (decimals > 0) {
char * hex_char = (char*) malloc(decimals*2 + 2);
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
new_val_str = hex_char;
@ -280,13 +284,16 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
break;
case 'B': // Pointer to SBuffer
{
const SBuffer & buf = *(const SBuffer*)cur_val;
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
if (buf_len) {
char * hex_char = (char*) malloc(buf_len*2 + 2);
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else {
const SBuffer & buf = *(const SBuffer*)cur_val;
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
if (buf_len) {
char * hex_char = (char*) malloc(buf_len*2 + 2);
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
new_val_str = hex_char;
allocs[alloc_idx++] = new_val_str;
}
}
}
break;
@ -315,40 +322,46 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
// Note: float MUST be passed by address, because C alsays promoted float to double when in vararg
case 'f': // input is `float`, printed to float with 2 decimals
{
bool truncate = false;
if (decimals < 0) {
decimals = -decimals;
truncate = true;
}
float number = *(float*)cur_val;
if (isnan(number) || isinf(number)) {
new_val_str = (char*) "null";
} else {
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
if (truncate) {
uint32_t last = strlen(hex) - 1;
// remove trailing zeros
while (hex[last] == '0') {
hex[last--] = 0; // remove last char
}
// remove trailing dot
if (hex[last] == '.') {
hex[last] = 0;
}
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else {
bool truncate = false;
if (decimals < 0) {
decimals = -decimals;
truncate = true;
}
float number = *(float*)cur_val;
if (isnan(number) || isinf(number)) {
new_val_str = "null";
} else {
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
if (truncate) {
uint32_t last = strlen(hex) - 1;
// remove trailing zeros
while (hex[last] == '0') {
hex[last--] = 0; // remove last char
}
// remove trailing dot
if (hex[last] == '.') {
hex[last] = 0;
}
}
new_val_str = copyStr(hex);
allocs[alloc_idx++] = new_val_str;
}
new_val_str = copyStr(hex);
allocs[alloc_idx++] = new_val_str;
}
}
break;
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
case 'X': // input is `uint64_t*`, printed as 16 hex digits (no prefix 0x)
{
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
new_val_str = copyStr(hex);
allocs[alloc_idx++] = new_val_str;
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
else {
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
U64toHex(*(uint64_t*)cur_val, hex, decimals);
new_val_str = copyStr(hex);
allocs[alloc_idx++] = new_val_str;
}
}
break;
// Trying to do String allocation alternatives, but not as interesting as I thought in the beginning
@ -382,7 +395,7 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
// disallocated all temporary strings
for (uint32_t i = 0; i < alloc_idx; i++) {
free(allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
free((void*)allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
allocs[i] = nullptr;
}
free(fmt_cpy); // free the local copy of the format string

View File

@ -1,6 +1,6 @@
{
"name": "TasmotaSerial",
"version": "3.2.0",
"version": "3.3.0",
"keywords": [
"serial", "io", "TasmotaSerial"
],

View File

@ -1,5 +1,5 @@
name=TasmotaSerial
version=3.2.0
version=3.3.0
author=Theo Arends
maintainer=Theo Arends <theo@arends.com>
sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.

View File

@ -109,16 +109,27 @@ bool TasmotaSerial::isValidGPIOpin(int pin) {
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
}
bool TasmotaSerial::begin(long speed, int stop_bits) {
m_stop_bits = ((stop_bits -1) &1) +1;
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
if (config > 2) {
// Legacy support where software serial fakes two stop bits if either stop bits is 2 or parity is not None
m_stop_bits = ((config &0x30) >> 5) +1;
if ((1 == m_stop_bits) && (config &0x03)) {
m_stop_bits++;
}
} else {
m_stop_bits = ((config -1) &1) +1;
#ifdef ESP8266
config = (2 == m_stop_bits) ? (uint32_t)SERIAL_8N2 : (uint32_t)SERIAL_8N1;
#endif // ESP8266
#ifdef ESP32
config = (2 == m_stop_bits) ? SERIAL_8N2 : SERIAL_8N1;
#endif // ESP32
}
if (m_hardserial) {
#ifdef ESP8266
Serial.flush();
if (2 == m_stop_bits) {
Serial.begin(speed, SERIAL_8N2);
} else {
Serial.begin(speed, SERIAL_8N1);
}
Serial.begin(speed, (SerialConfig)config);
if (m_hardswap) {
Serial.swap();
}
@ -131,11 +142,7 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
m_uart = tasmota_serial_index;
tasmota_serial_index--;
TSerial = new HardwareSerial(m_uart);
if (2 == m_stop_bits) {
TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin);
} else {
TSerial->begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin);
}
TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
if (serial_buffer_size > 256) {
TSerial->setRxBufferSize(serial_buffer_size);
}
@ -154,10 +161,6 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
return m_valid;
}
bool TasmotaSerial::begin(void) {
return begin(TM_SERIAL_BAUDRATE);
}
bool TasmotaSerial::hardwareSerial(void) {
#ifdef ESP8266
return m_hardserial;

View File

@ -40,8 +40,7 @@ class TasmotaSerial : public Stream {
TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE);
virtual ~TasmotaSerial();
bool begin(long speed, int stop_bits = 1);
bool begin(void);
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
bool hardwareSerial(void);
int peek(void);

View File

@ -26,18 +26,29 @@
const char * k_current_json_buffer = "";
// returns nibble value or -1 if not an hex digit
static int32_t asc2byte(char chr) {
if (chr >= '0' && chr <= '9') { return chr - '0'; }
else if (chr >= 'A' && chr <= 'F') { return chr + 10 - 'A'; }
else if (chr >= 'a' && chr <= 'f') { return chr + 10 - 'a'; }
return -1;
}
/*********************************************************************************************\
* Lightweight String to Float, because atof() or strtof() takes 10KB
*
* To remove code, exponents are not parsed
* (commented out below, just in case we need them after all)
*
* Moved to double to be able to parse 32 bits int as well without loss in accuracy
\*********************************************************************************************/
// Inspired from https://searchcode.com/codesearch/view/22115068/
float json_strtof(const char* s) {
double JsonParserToken::json_strtof(const char* s) {
const char* p = s;
float value = 0.;
double value = 0.;
int32_t sign = +1;
float factor;
double factor;
uint32_t base = 10; // support hex mode if start with Ox or OX
// unsigned int expo;
while (isspace(*p)){ // skip any leading white-spaces
@ -45,22 +56,30 @@ float json_strtof(const char* s) {
}
switch (*p) {
case '-': sign = -1;
case '-': sign = -1; // no break on purpose
case '+': p++;
default : break;
}
while ((unsigned int)(*p - '0') < 10u) {
value = value*10 + (*p++ - '0');
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { // detect hex mode
base = 16;
p += 2;
}
int32_t v; // temp nibble value
while ((v = asc2byte(*p)) >= 0) {
value = value * base + v;
p++;
}
if (*p == '.' ) {
factor = 1.0f;
p++;
while ((unsigned int)(*p - '0') < 10u) {
factor *= 0.1f;
value += (*p++ - '0') * factor;
while ((v = asc2byte(*p)) >= 0) {
factor /= base;
value += v * factor;
p++;
}
}

View File

@ -114,6 +114,9 @@ public:
JsonParserObject getObject(void) const;
JsonParserArray getArray(void) const;
// general parser from string to int/hex/float
static double json_strtof(const char* s);
public:
// the following should be 'protected' but then it can't be accessed by iterators
const jsmntok_t * t;

View File

@ -549,6 +549,9 @@ void Renderer::setDrawMode(uint8_t mode) {
void Renderer::invertDisplay(boolean i) {
}
void Renderer::reverseDisplay(boolean i) {
}
void Renderer::setScrollMargins(uint16_t top, uint16_t bottom) {
}

View File

@ -38,6 +38,7 @@ public:
virtual void pushColors(uint16_t *data, uint16_t len, boolean first);
virtual void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
virtual void invertDisplay(boolean i);
virtual void reverseDisplay(boolean i);
virtual void setScrollMargins(uint16_t top, uint16_t bottom);
virtual void scrollTo(uint16_t y);
void setDrawMode(uint8_t mode);

View File

@ -568,6 +568,28 @@ void ILI9341_2::invertDisplay(boolean i) {
SPI_END_TRANSACTION();
}
void ILI9341_2::reverseDisplay(boolean i) {
SPI_BEGIN_TRANSACTION();
ILI9341_2_CS_LOW
if (i) {
writecmd(ILI9341_2_FRMCTR1);
spiwrite(0x00);
spiwrite(0x13);
writecmd(ILI9341_2_MADCTL);
spiwrite(0x01);
spiwrite(0x08);
} else {
writecmd(ILI9341_2_FRMCTR1);
spiwrite(0x00);
spiwrite(0x18);
writecmd(ILI9341_2_MADCTL);
spiwrite(0x01);
spiwrite(0x48);
}
ILI9341_2_CS_HIGH
SPI_END_TRANSACTION();
}
void ili9342_dimm(uint8_t dim);
// dimmer 0-100

View File

@ -138,6 +138,7 @@ class ILI9341_2 : public Renderer {
void dim(uint8_t dim);
void pushColors(uint16_t *data, uint16_t len, boolean first);
void invertDisplay(boolean i);
void reverseDisplay(boolean i);
void spiwrite(uint8_t c);
void spiwrite16(uint16_t c);
void spiwrite32(uint32_t c);

View File

@ -0,0 +1,78 @@
# XPT2046 Touchscreen Arduino Library
XPT2046_Touchscreen is a library for the XPT2046 resistive touchscreen controllers used on many low cost TFT displays.
![ILI9431Test Example Program](doc/ILI9431Test.jpg)
## Setup Functions
First, create an instance of the library for your touchscreen. The digital pin
used for chip select is required. The normal MISO, MOSI and SCK pins will be
used automatically.
#define CS_PIN 8
XPT2046_Touchscreen ts(CS_PIN);
The use of the Touch interrupt pin can be optionally specified. If the Teensy
pin specified is actively connected to the T_IRQ display pin then the normal
touch calls will respond, but can be called more often as each call returns
without hardware access when no interrupt was recorded.
#define TIRQ_PIN 2
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);
In setup(), use the begin() function to initialize the touchscreen, and
optionally use setRotation(n), where n is 0 to 3, matching the rotation
setting in ILI9341_t3, Adafruit_ILI9341 or other Adafruit compatible TFT
libraries.
ts.begin();
ts.setRotation(1);
## Reading Touch Info
The touched() function tells if the display is currently being touched,
returning true or false.
if (ts.touched()) {
// do something....
}
You can read the touch coordinates with readData()
uint16_t x, y, z;
ts.readData(&x, &y, &z);
or with getPoint(), which returns a TS_Point object:
TS_Point p = ts.getPoint();
Serial.print("x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.print(p.y);
The Z coordinate represents the amount of pressure applied to the screen.
## Adafruit Library Compatibility
XPT2046_Touchscreen is meant to be a compatible with sketches written for Adafruit_STMPE610, offering the same functions, parameters and numerical ranges as Adafruit's library.
## Using The Interrupt Pin : Built in support when connected nothing else is needed. When specified as above
no SPI calls are made unless a Touch was detected. On normal connections - this means the Teensy LED
won't blink on every touch query.
## Using The Interrupt Pin : Custom use would preclude the normal built in usage. The warning below is justified.
The XPT2046 chip has an interrupt output, which is typically labeled T_IRQ on many low cost TFT displays. No special software support is needed in this library. The interrupt pin always outputs a digital signal related to the touch controller signals, which is LOW when the display is touched. It also is driven low while software reads the touch position.
The interrupt can be used as a wakeup signal, if you put your microcontroller into a deep sleep mode. Normally, you would stop reading the touch data, then enable the interrupt pin with attachInterrupt(), and then configure your processor to wake when the interrupt occurs, before enter a deep sleep mode. Upon waking, you would normally disable the interrupt before reading the display, to prevent false interrupts caused by the process of reading touch positions.
You can also use the interrupt to respond to touch events. Setup might look similar to this:
SPI.usingInterrupt(digitalPinToInterrupt(pin))
attachInterrupt(digitalPinToInterrupt(pin), myFunction, FALLING);
However, inside your interrupt function, if the display is no longer being touched, any attempt to read the touch position will cause the interrupt pin to create another falling edge. This can lead to an infinite loop of falsely triggered interrupts. Special care is needed to avoid triggering more interrupts on the low signal due to reading the touch position.
For most applications, regularly reading the touch position from the main program is much simpler.

View File

@ -0,0 +1,219 @@
/* Touchscreen library for XPT2046 Touch Controller Chip
* Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "XPT2046_Touchscreen.h"
#define Z_THRESHOLD 400
#define Z_THRESHOLD_INT 75
#define MSEC_THRESHOLD 3
#define SPI_SETTING SPISettings(2000000, MSBFIRST, SPI_MODE0)
static XPT2046_Touchscreen *isrPinptr;
void isrPin(void);
bool XPT2046_Touchscreen::begin(SPIClass &wspi)
{
_pspi = &wspi;
_pspi->begin();
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH);
if (255 != tirqPin) {
pinMode( tirqPin, INPUT );
attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
isrPinptr = this;
}
return true;
}
#if defined(_FLEXIO_SPI_H_)
#define FLEXSPI_SETTING FlexIOSPISettings(2000000, MSBFIRST, SPI_MODE0)
bool XPT2046_Touchscreen::begin(FlexIOSPI &wflexspi)
{
_pspi = nullptr; // make sure we dont use this one...
_pflexspi = &wflexspi;
_pflexspi->begin();
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH);
if (255 != tirqPin) {
pinMode( tirqPin, INPUT );
attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
isrPinptr = this;
}
return true;
}
#endif
ISR_PREFIX
void isrPin( void )
{
XPT2046_Touchscreen *o = isrPinptr;
o->isrWake = true;
}
TS_Point XPT2046_Touchscreen::getPoint()
{
update();
return TS_Point(xraw, yraw, zraw);
}
bool XPT2046_Touchscreen::tirqTouched()
{
return (isrWake);
}
bool XPT2046_Touchscreen::touched()
{
update();
return (zraw >= Z_THRESHOLD);
}
void XPT2046_Touchscreen::readData(uint16_t *x, uint16_t *y, uint8_t *z)
{
update();
*x = xraw;
*y = yraw;
*z = zraw;
}
bool XPT2046_Touchscreen::bufferEmpty()
{
return ((millis() - msraw) < MSEC_THRESHOLD);
}
static int16_t besttwoavg( int16_t x , int16_t y , int16_t z ) {
int16_t da, db, dc;
int16_t reta = 0;
if ( x > y ) da = x - y; else da = y - x;
if ( x > z ) db = x - z; else db = z - x;
if ( z > y ) dc = z - y; else dc = y - z;
if ( da <= db && da <= dc ) reta = (x + y) >> 1;
else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
else reta = (y + z) >> 1; // else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
return (reta);
}
// TODO: perhaps a future version should offer an option for more oversampling,
// with the RANSAC algorithm https://en.wikipedia.org/wiki/RANSAC
void XPT2046_Touchscreen::update()
{
int16_t data[6];
int z;
if (!isrWake) return;
uint32_t now = millis();
if (now - msraw < MSEC_THRESHOLD) return;
if (_pspi) {
_pspi->beginTransaction(SPI_SETTING);
digitalWrite(csPin, LOW);
_pspi->transfer(0xB1 /* Z1 */);
int16_t z1 = _pspi->transfer16(0xC1 /* Z2 */) >> 3;
z = z1 + 4095;
int16_t z2 = _pspi->transfer16(0x91 /* X */) >> 3;
z -= z2;
if (z >= Z_THRESHOLD) {
_pspi->transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
data[0] = _pspi->transfer16(0xD1 /* Y */) >> 3;
data[1] = _pspi->transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
data[2] = _pspi->transfer16(0xD1 /* Y */) >> 3;
data[3] = _pspi->transfer16(0x91 /* X */) >> 3;
}
else data[0] = data[1] = data[2] = data[3] = 0; // Compiler warns these values may be used unset on early exit.
data[4] = _pspi->transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
data[5] = _pspi->transfer16(0) >> 3;
digitalWrite(csPin, HIGH);
_pspi->endTransaction();
}
#if defined(_FLEXIO_SPI_H_)
else if (_pflexspi) {
_pflexspi->beginTransaction(FLEXSPI_SETTING);
digitalWrite(csPin, LOW);
_pflexspi->transfer(0xB1 /* Z1 */);
int16_t z1 = _pflexspi->transfer16(0xC1 /* Z2 */) >> 3;
z = z1 + 4095;
int16_t z2 = _pflexspi->transfer16(0x91 /* X */) >> 3;
z -= z2;
if (z >= Z_THRESHOLD) {
_pflexspi->transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
data[0] = _pflexspi->transfer16(0xD1 /* Y */) >> 3;
data[1] = _pflexspi->transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
data[2] = _pflexspi->transfer16(0xD1 /* Y */) >> 3;
data[3] = _pflexspi->transfer16(0x91 /* X */) >> 3;
}
else data[0] = data[1] = data[2] = data[3] = 0; // Compiler warns these values may be used unset on early exit.
data[4] = _pflexspi->transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
data[5] = _pflexspi->transfer16(0) >> 3;
digitalWrite(csPin, HIGH);
_pflexspi->endTransaction();
}
#endif
// If we do not have either _pspi or _pflexspi than bail.
else return;
//Serial.printf("z=%d :: z1=%d, z2=%d ", z, z1, z2);
if (z < 0) z = 0;
if (z < Z_THRESHOLD) { // if ( !touched ) {
// Serial.println();
zraw = 0;
if (z < Z_THRESHOLD_INT) { // if ( !touched ) {
if (255 != tirqPin) isrWake = false;
}
return;
}
zraw = z;
// Average pair with least distance between each measured x then y
//Serial.printf(" z1=%d,z2=%d ", z1, z2);
//Serial.printf("p=%d, %d,%d %d,%d %d,%d", zraw,
//data[0], data[1], data[2], data[3], data[4], data[5]);
int16_t x = besttwoavg( data[0], data[2], data[4] );
int16_t y = besttwoavg( data[1], data[3], data[5] );
//Serial.printf(" %d,%d", x, y);
//Serial.println();
if (z >= Z_THRESHOLD) {
msraw = now; // good read completed, set wait
switch (rotation) {
case 0:
xraw = 4095 - y;
yraw = x;
break;
case 1:
xraw = x;
yraw = y;
break;
case 2:
xraw = y;
yraw = 4095 - x;
break;
default: // 3
xraw = 4095 - x;
yraw = 4095 - y;
}
}
}

View File

@ -0,0 +1,89 @@
/* Touchscreen library for XPT2046 Touch Controller Chip
* Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice, development funding notice, and this permission
* notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _XPT2046_Touchscreen_h_
#define _XPT2046_Touchscreen_h_
#include "Arduino.h"
#include <SPI.h>
#if defined(__IMXRT1062__)
#if __has_include(<FlexIOSPI.h>)
#include <FlexIOSPI.h>
#endif
#endif
#if ARDUINO < 10600
#error "Arduino 1.6.0 or later (SPI library) is required"
#endif
class TS_Point {
public:
TS_Point(void) : x(0), y(0), z(0) {}
TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
int16_t x, y, z;
};
class XPT2046_Touchscreen {
public:
constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq=255)
: csPin(cspin), tirqPin(tirq) { }
bool begin(SPIClass &wspi = SPI);
#if defined(_FLEXIO_SPI_H_)
bool begin(FlexIOSPI &wflexspi);
#endif
TS_Point getPoint();
bool tirqTouched();
bool touched();
void readData(uint16_t *x, uint16_t *y, uint8_t *z);
bool bufferEmpty();
uint8_t bufferSize() { return 1; }
void setRotation(uint8_t n) { rotation = n % 4; }
// protected:
volatile bool isrWake=true;
private:
void update();
uint8_t csPin, tirqPin, rotation=1;
int16_t xraw=0, yraw=0, zraw=0;
uint32_t msraw=0x80000000;
SPIClass *_pspi = nullptr;
#if defined(_FLEXIO_SPI_H_)
FlexIOSPI *_pflexspi = nullptr;
#endif
};
#ifndef ISR_PREFIX
#if defined(ESP8266)
#define ISR_PREFIX ICACHE_RAM_ATTR
#elif defined(ESP32)
// TODO: should this also be ICACHE_RAM_ATTR ??
#define ISR_PREFIX IRAM_ATTR
#else
#define ISR_PREFIX
#endif
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@ -0,0 +1,64 @@
Please use this form only to report code defects or bugs.
For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.
Arduino: forum.arduino.cc
Teensy: forum.pjrc.com
ESP8266: www.esp8266.com
ESP32: www.esp32.com
Adafruit Feather/Metro/Trinket: forums.adafruit.com
Particle Photon: community.particle.io
If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code!
Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.
----------------------------- Remove above -----------------------------
### Description
Describe your problem.
### Steps To Reproduce Problem
Please give detailed instructions needed for anyone to attempt to reproduce the problem.
### Hardware & Software
Board
Shields / modules used
Arduino IDE version
Teensyduino version (if using Teensy)
Version info & package name (from Tools > Boards > Board Manager)
Operating system & version
Any other software or hardware?
### Arduino Sketch
```cpp
// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
#include <Arduino.h>
// libraries: give links/details so anyone can compile your code for the same result
void setup() {
}
void loop() {
}
```
### Errors or Incorrect Output
If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears.

View File

@ -0,0 +1,69 @@
#include <ILI9341_t3.h>
#include <font_Arial.h> // from ILI9341_t3
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#define CS_PIN 8
#define TFT_DC 9
#define TFT_CS 10
// MOSI=11, MISO=12, SCK=13
XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN 2
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
void setup() {
Serial.begin(38400);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000));
}
boolean wastouched = true;
void loop() {
boolean istouched = ts.touched();
if (istouched) {
TS_Point p = ts.getPoint();
if (!wastouched) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_YELLOW);
tft.setFont(Arial_60);
tft.setCursor(60, 80);
tft.print("Touch");
}
tft.fillRect(100, 150, 140, 60, ILI9341_BLACK);
tft.setTextColor(ILI9341_GREEN);
tft.setFont(Arial_24);
tft.setCursor(100, 150);
tft.print("X = ");
tft.print(p.x);
tft.setCursor(100, 180);
tft.print("Y = ");
tft.print(p.y);
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.println(p.y);
} else {
if (wastouched) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(ILI9341_RED);
tft.setFont(Arial_48);
tft.setCursor(120, 50);
tft.print("No");
tft.setCursor(80, 120);
tft.print("Touch");
}
Serial.println("no touch");
}
wastouched = istouched;
delay(100);
}

View File

@ -0,0 +1,33 @@
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#define CS_PIN 8
// MOSI=11, MISO=12, SCK=13
//XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN 2
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
void setup() {
Serial.begin(38400);
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000));
}
void loop() {
if (ts.touched()) {
TS_Point p = ts.getPoint();
Serial.print("Pressure = ");
Serial.print(p.z);
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.print(p.y);
delay(30);
Serial.println();
}
}

View File

@ -0,0 +1,37 @@
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
#define CS_PIN 8
// MOSI=11, MISO=12, SCK=13
// The TIRQ interrupt signal must be used for this example.
#define TIRQ_PIN 2
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
void setup() {
Serial.begin(38400);
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000));
}
void loop() {
// tirqTouched() is much faster than touched(). For projects where other SPI chips
// or other time sensitive tasks are added to loop(), using tirqTouched() can greatly
// reduce the delay added to loop() when the screen has not been touched.
if (ts.tirqTouched()) {
if (ts.touched()) {
TS_Point p = ts.getPoint();
Serial.print("Pressure = ");
Serial.print(p.z);
Serial.print(", x = ");
Serial.print(p.x);
Serial.print(", y = ");
Serial.print(p.y);
delay(30);
Serial.println();
}
}
}

View File

@ -0,0 +1,8 @@
XPT2046_Touchscreen KEYWORD1
TS_Point KEYWORD1
getPoint KEYWORD2
touched KEYWORD2
readData KEYWORD2
bufferEmpty KEYWORD2
bufferSize KEYWORD2
setRotation KEYWORD2

View File

@ -0,0 +1,13 @@
{
"name": "XPT2046_Touchscreen",
"keywords": "display, tft, lcd, graphics, spi, touchscreen",
"description": "Touchscreens using the XPT2046 controller chip. Many very low cost color TFT displays with touch screens have this chip.",
"exclude": "doc",
"repository":
{
"type": "git",
"url": "https://github.com/PaulStoffregen/XPT2046_Touchscreen.git"
},
"frameworks": "arduino",
"platforms": "*"
}

View File

@ -0,0 +1,10 @@
name=XPT2046_Touchscreen
version=1.3
author=Paul Stoffregen
maintainer=Paul Stoffregen
sentence=Touchscreens using the XPT2046 controller chip.
paragraph=Many very low cost color TFT displays with touch screens have this chip.
category=Display
url=https://github.com/PaulStoffregen/XPT2046_Touchscreen
architectures=*

View File

@ -504,6 +504,9 @@ void be_gc_collect(bvm *vm)
if (vm->gc.status & GC_HALT) {
return; /* the GC cannot run for some reason */
}
#if BE_USE_OBSERVABILITY_HOOK
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
#endif
/* step 1: set root-set reference objects to unscanned */
premark_internal(vm); /* object internal the VM */
premark_global(vm); /* global objects */
@ -520,4 +523,7 @@ void be_gc_collect(bvm *vm)
reset_fixedlist(vm);
/* step 5: calculate the next GC threshold */
vm->gc.threshold = next_threshold(vm->gc);
#if BE_USE_OBSERVABILITY_HOOK
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage);
#endif
}

View File

@ -398,6 +398,9 @@ BERRY_API bvm* be_vm_new(void)
be_globalvar_init(vm);
be_gc_setpause(vm, 1);
be_loadlibs(vm);
#if BE_USE_OBSERVABILITY_HOOK
vm->obshook = NULL;
#endif
return vm;
}
@ -1051,3 +1054,10 @@ void be_dofunc(bvm *vm, bvalue *v, int argc)
default: call_error(vm, v);
}
}
BERRY_API void be_set_obs_hook(bvm *vm, beobshook hook)
{
#if BE_USE_OBSERVABILITY_HOOK
vm->obshook = hook;
#endif
}

View File

@ -86,6 +86,9 @@ struct bvm {
bmap *ntvclass; /* native class table */
blist *registry; /* registry list */
struct bgc gc;
#if BE_USE_OBSERVABILITY_HOOK
beobshook obshook;
#endif
#if BE_USE_DEBUG_HOOK
bvalue hook;
bbyte hookmask;

View File

@ -273,6 +273,14 @@ typedef void(*bntvhook)(bvm *vm, bhookinfo *info);
#define be_assert(expr) ((void)0)
#endif
/* Observability hook */
typedef void(*beobshook)(bvm *vm, int event, ...);
enum beobshookevents {
BE_OBS_GC_START, // start of GC, arg = allocated size
BE_OBS_GC_END, // end of GC, arg = allocated size
};
/* FFI functions */
#define be_writestring(s) be_writebuffer((s), strlen(s))
#define be_writenewline() be_writebuffer("\n", 1)
@ -406,6 +414,9 @@ BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib);
BERRY_API bvm* be_vm_new(void);
BERRY_API void be_vm_delete(bvm *vm);
/* Observability hook */
BERRY_API void be_set_obs_hook(bvm *vm, beobshook hook);
/* code load APIs */
BERRY_API int be_loadbuffer(bvm *vm,
const char *name, const char *buffer, size_t length);

View File

@ -18,6 +18,7 @@ extern int l_respCmndStr(bvm *vm);
extern int l_respCmndDone(bvm *vm);
extern int l_respCmndError(bvm *vm);
extern int l_respCmndFailed(bvm *vm);
extern int l_resolveCmnd(bvm *vm);
// #if !BE_USE_PRECOMPILED_OBJECT
#if 1 // TODO we will do pre-compiled later
@ -36,6 +37,7 @@ be_native_module_attr_table(tasmota_ntv) {
be_native_module_function("respcmnd_done", l_respCmndDone),
be_native_module_function("respcmnd_error", l_respCmndError),
be_native_module_function("respcmnd_failed", l_respCmndFailed),
be_native_module_function("resolvecmnd", l_resolveCmnd),
be_native_module_str("_operators", "=<>!|"),
};

View File

@ -14,6 +14,8 @@ extern int b_wire_available(bvm *vm);
extern int b_wire_write(bvm *vm);
extern int b_wire_read(bvm *vm);
extern int b_wire_validread(bvm *vm);
// #if !BE_USE_PRECOMPILED_OBJECT
#if 1 // TODO we will do pre-compiled later
be_native_module_attr_table(wire) {
@ -23,6 +25,7 @@ be_native_module_attr_table(wire) {
be_native_module_function("available", b_wire_available),
be_native_module_function("write", b_wire_write),
be_native_module_function("read", b_wire_read),
be_native_module_function("validread", b_wire_validread),
};
be_define_native_module(wire, NULL);

View File

@ -64,6 +64,12 @@
**/
#define BE_DEBUG_VAR_INFO 0
/* Macro: BE_USE_OBSERVABILITY_HOOK
* Use the obshook function to report low-level actions.
* Default: 0
**/
#define BE_USE_OBSERVABILITY_HOOK 1
/* Macro: BE_STACK_TOTAL_MAX
* Set the maximum total stack size.
* Default: 20000

View File

@ -124,16 +124,16 @@ lib_extra_dirs = ${library.lib_extra_dirs}
[core32]
; Activate Stage Core32 by removing ";" in next 3 lines, if you want to override the standard core32
platform_packages = ${core32_stage.platform_packages}
build_unflags = ${core32_stage.build_unflags}
build_flags = ${core32_stage.build_flags}
;platform_packages = ${core32_stage.platform_packages}
;build_unflags = ${core32_stage.build_unflags}
;build_flags = ${core32_stage.build_flags}
[core32_stage]
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc7/esp32-1.0.5-rc7.zip
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}
;-DESP32_STAGE=true
-DESP32_STAGE=true
[library]
shared_libdeps_dir = lib

View File

@ -94,8 +94,7 @@ build_flags = ${esp_defaults.build_flags}
[core32]
platform = espressif32 @ 3.0.0
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc6/esp32-1.0.5-rc6.zip
platformio/tool-mklittlefs @ ~1.203.200522
platform = espressif32 @ 3.1.0
platform_packages = platformio/tool-mklittlefs @ ~1.203.200522
build_unflags = ${esp32_defaults.build_unflags}
build_flags = ${esp32_defaults.build_flags}

View File

@ -550,7 +550,7 @@
#define D_CMND_ZIGBEE_PERMITJOIN "PermitJoin"
#define D_CMND_ZIGBEE_STATUS "Status"
#define D_CMND_ZIGBEE_RESET "Reset"
#define D_JSON_ZIGBEE_CC2530 "CC2530"
#define D_JSON_ZIGBEE_CC2530 "CCxxxx"
#define D_JSON_ZIGBEE_EZSP "EZSP"
#define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug
#define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -673,6 +673,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
#define D_SENSOR_EPAPER29_CS "EPaper29 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -670,6 +670,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 TX"
#define D_SENSOR_MCP39F5_RX "MCP39F5 RX"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 TX"
#define D_SENSOR_CSE7766_RX "CSE7766 RX"
#define D_SENSOR_PN532_TX "PN532 TX"
@ -777,6 +779,7 @@
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
#define D_SENSOR_EPAPER29_CS "EPaper29 CS"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_EPAPER42_CS "EPaper42 CS"
#define D_SENSOR_SSD1351_CS "SSD1351 CS"
#define D_SENSOR_SSD1351_DC "SSD1351 DC"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -666,7 +666,7 @@
#define D_SENSOR_MAX31855_CS "MX31855 - CS"
#define D_SENSOR_MAX31855_CLK "MX31855 - CLK"
#define D_SENSOR_MAX31855_DO "MX31855 - DO"
#define D_SENSOR_MAX31865_CS "MX31865 CS"
#define D_SENSOR_MAX31865_CS "MX31865 - CS"
#define D_SENSOR_NRG_SEL "HLWBL - SEL" // Suffix "i"
#define D_SENSOR_NRG_CF1 "HLWBL - CF1"
#define D_SENSOR_HLW_CF "HLW8012 - CF"
@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 - TX"
#define D_SENSOR_MCP39F5_RX "MCP39F5 - RX"
#define D_SENSOR_MCP39F5_RST "MCP39F5 - Reset"
#define D_SENSOR_CSE7761_TX "CSE7761 - Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 - Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 - TX"
#define D_SENSOR_CSE7766_RX "CSE7766 - RX"
#define D_SENSOR_PN532_TX "PN532 - TX"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 - CS"
#define D_SENSOR_NRF24_CS "NRF24 - CS"
#define D_SENSOR_NRF24_DC "NRF24 - DC"
#define D_SENSOR_XPT2046_CS "XPT2046 - CS"
#define D_SENSOR_ILI9341_CS "ILI9341 - CS"
#define D_SENSOR_ILI9341_DC "ILI9341 - DC"
#define D_SENSOR_ILI9488_CS "ILI9488 - CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -674,6 +674,8 @@
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
#define D_SENSOR_PN532_TX "PN532 Tx"
@ -777,6 +779,7 @@
#define D_SENSOR_RC522_CS "RC522 CS"
#define D_SENSOR_NRF24_CS "NRF24 CS"
#define D_SENSOR_NRF24_DC "NRF24 DC"
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
#define D_SENSOR_ILI9488_CS "ILI9488 CS"

View File

@ -275,8 +275,11 @@
#define KEY_SWAP_DOUBLE_PRESS false // [SetOption11] Swap button single and double press functionality
#define KEY_ONLY_SINGLE_PRESS false // [SetOption13] Enable only single press to speed up button press recognition
#define MQTT_BUTTONS false // [SetOption73] Detach buttons from relays and send multi-press and hold MQTT messages instead
#define SWITCH_DEBOUNCE_TIME 50 // [SwitchDebounce] Number of mSeconds switch press debounce time
#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, FOLLOWMULTI, FOLLOWMULTI_INV (the wall switch state)
#define MQTT_SWITCHES false // [SetOption114] Detach switches from relays and send MQTT messages instead
#define TEMP_CONVERSION false // [SetOption8] Return temperature in (false = Celsius or true = Fahrenheit)
#define PRESSURE_CONVERSION false // [SetOption24] Return pressure in (false = hPa or true = mmHg)
@ -330,6 +333,7 @@
#define SHUTTER_SUPPORT false // [SetOption80] Enable shutter support
#define PCF8574_INVERT_PORTS false // [SetOption81] Invert all ports on PCF8574 devices
#define ZIGBEE_FRIENDLY_NAMES false // [SetOption83] Enable Zigbee FriendlyNames instead of ShortAddresses when possible
#define ZIGBEE_DISTINCT_TOPICS false // [SetOption89] Enable unique device topic based on Zigbee device ShortAddr
#define ZIGBEE_RMV_ZBRECEIVED false // [SetOption100] Remove ZbReceived form JSON message
#define ZIGBEE_INDEX_EP false // [SetOption101] Add the source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3
@ -515,6 +519,9 @@
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
#define I2CDRIVERS_0_31 0xFFFFFFFF // Enable I2CDriver0 to I2CDriver31
#define I2CDRIVERS_32_63 0xFFFFFFFF // Enable I2CDriver32 to I2CDriver63
#define I2CDRIVERS_64_95 0xFFFFFFFF // Enable I2CDriver64 to I2CDriver95
#ifdef USE_I2C
// #define USE_SHT // [I2cDriver8] Enable SHT1X sensor (+1k4 code)
@ -883,6 +890,8 @@
//#define USE_IBEACON_ESP32
//#define USE_WEBCAM // Add support for webcam
#define USE_CSE7761 // Add support for CSE7761 Energy monitor as used in Sonoff Dual R3
#endif // ESP32
/*********************************************************************************************\

View File

@ -327,6 +327,18 @@ typedef struct {
uint8_t dpid = 0;
} TuyaFnidDpidMap;
typedef union {
uint8_t data;
struct {
uint8_t ilimode : 3;
uint8_t Invert : 1;
uint8_t spare2 : 1;
uint8_t spare3 : 1;
uint8_t spare4 : 1;
uint8_t spare5 : 1;
};
} DisplayOptions;
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
const uint8_t MAX_TUYA_FUNCTIONS = 16;
@ -355,7 +367,6 @@ struct {
uint8_t text_pool_290[66]; // 290
// End of single char array of 698 chars max ****************
uint8_t display_model; // 2D2
uint8_t display_mode; // 2D3
uint8_t display_refresh; // 2D4
@ -375,7 +386,7 @@ struct {
uint8_t param[PARAM8_SIZE]; // 2FC SetOption32 .. SetOption49
int16_t toffset[2]; // 30E
uint8_t display_font; // 312
uint8_t display_type; // 313
DisplayOptions display_options; // 313
uint8_t free_314[43]; // 314

View File

@ -726,6 +726,7 @@ void SettingsDefaultSet2(void) {
flag3.no_power_feedback |= APP_NO_RELAY_SCAN;
flag3.fast_power_cycle_disable |= APP_DISABLE_POWERCYCLE;
flag3.bootcount_update |= DEEPSLEEP_BOOTCOUNT;
flag3.mqtt_buttons |= MQTT_BUTTONS;
Settings.save_data = SAVE_DATA;
Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY;
Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36
@ -833,6 +834,7 @@ void SettingsDefaultSet2(void) {
flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN;
flag5.mqtt_info_retain |= MQTT_INFO_RETAIN;
flag5.mqtt_state_retain |= MQTT_STATE_RETAIN;
flag5.mqtt_switches |= MQTT_SWITCHES;
// flag.mqtt_serial |= 0;
flag.device_index_enable |= MQTT_POWER_FORMAT;
flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE;
@ -1058,6 +1060,7 @@ void SettingsDefaultSet2(void) {
flag3.shutter_mode |= SHUTTER_SUPPORT;
flag3.pcf8574_ports_inverted |= PCF8574_INVERT_PORTS;
flag4.zigbee_use_names |= ZIGBEE_FRIENDLY_NAMES;
flag4.zigbee_distinct_topics |= ZIGBEE_DISTINCT_TOPICS;
flag4.remove_zbreceived |= ZIGBEE_RMV_ZBRECEIVED;
flag4.zb_index_ep |= ZIGBEE_INDEX_EP;
flag4.mqtt_tls |= MQTT_TLS_ENABLED;
@ -1072,6 +1075,7 @@ void SettingsDefaultSet2(void) {
Settings.flag2 = flag2;
Settings.flag3 = flag3;
Settings.flag4 = flag4;
Settings.flag5 = flag5;
}
/********************************************************************************************/
@ -1102,9 +1106,9 @@ void SettingsDefaultWebColor(void) {
}
void SettingsEnableAllI2cDrivers(void) {
Settings.i2c_drivers[0] = 0xFFFFFFFF;
Settings.i2c_drivers[1] = 0xFFFFFFFF;
Settings.i2c_drivers[2] = 0xFFFFFFFF;
Settings.i2c_drivers[0] = I2CDRIVERS_0_31;
Settings.i2c_drivers[1] = I2CDRIVERS_32_63;
Settings.i2c_drivers[2] = I2CDRIVERS_64_95;
}
/********************************************************************************************/

View File

@ -238,6 +238,11 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
#define KNX_MAX_device_param 31
#define MAX_KNXTX_CMNDS 5
// XPT2046 resistive touch driver min/max raw values
#define XPT2046_MINX 192
#define XPT2046_MAXX 3895
#define XPT2046_MINY 346
#define XPT2046_MAXY 3870
/*********************************************************************************************\
* Enumeration
\*********************************************************************************************/

View File

@ -153,6 +153,8 @@ enum UserSelectablePins {
GPIO_TM1638CLK, GPIO_TM1638DIO, GPIO_TM1638STB, // TM1638 interface
GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control
GPIO_SSD1351_DC,
GPIO_XPT2046_CS, // XPT2046 SPI Chip Select
GPIO_CSE7761_TX, GPIO_CSE7761_RX, // CSE7761 Serial interface (Dual R3)
GPIO_SENSOR_END };
enum ProgramSelectablePins {
@ -326,6 +328,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|"
D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|"
D_SENSOR_SSD1351_DC "|"
D_SENSOR_XPT2046_CS "|"
D_SENSOR_CSE7761_TX "|" D_SENSOR_CSE7761_RX "|"
;
const char kSensorNamesFixed[] PROGMEM =
@ -415,6 +419,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#ifdef USE_DISPLAY_ILI9341
AGPIO(GPIO_ILI9341_CS),
AGPIO(GPIO_ILI9341_DC),
#ifdef USE_XPT2046
AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select
#endif
#endif // USE_DISPLAY_ILI9341
#ifdef USE_DISPLAY_ILI9488
AGPIO(GPIO_ILI9488_CS),
@ -568,6 +576,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
#if defined(USE_I2C) && defined(USE_ADE7953)
AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ
#endif
#ifdef USE_CSE7761
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3)
#endif
#ifdef USE_CSE7766
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)
AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2)
@ -2623,7 +2635,7 @@ const mytmplt kModules[] PROGMEM = {
AGPIO(GPIO_USER), // 2 IO GPIO2, SPKR_DATA
AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD
AGPIO(GPIO_SDCARD_CS), // 4 IO GPIO4, SPI_CS_CARD
0, // 5 IO GPIO5, SPI_CS_LCD
AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, SPI_CS_LCD
// 6 IO GPIO6, Flash CLK
// 7 IO GPIO7, Flash D0
// 8 IO GPIO8, Flash D1
@ -2633,7 +2645,7 @@ const mytmplt kModules[] PROGMEM = {
0, // 12 (I)O GPIO12, SPKR_CLK
AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
0, // 15 (I)O GPIO15, SPI_DC_LCD
AGPIO(GPIO_ILI9341_DC), // 15 (I)O GPIO15, SPI_DC_LCD
0, // 16 IO GPIO16, PSRAM_CS
0, // 17 IO GPIO17, PSRAM_CLK
AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, SPI_CLK

View File

@ -82,6 +82,7 @@ Examples :
#define WIFI_DNS MY_DNS // If not using DHCP set DNS IP address (might be equal to WIFI_GATEWAY)
#endif
// !!! Remember that your changes GOES AT THE BOTTOM OF THIS FILE right before the last #endif !!!
*/

View File

@ -84,6 +84,8 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log
#define D_CMND_DISP_SCROLLTEXT "ScrollText"
#define D_CMND_DISP_TYPE "Type"
#define D_CMND_DISP_ILIMODE "ILIMode"
#define D_CMND_DISP_ILIINVERT "Invert"
enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND,
@ -115,7 +117,7 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SETLEDS "|" D_CMND_DISP_SETLED "|"
D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_TYPE
D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_TYPE "|" D_CMND_DISP_ILIMODE "|" D_CMND_DISP_ILIINVERT
;
void (* const DisplayCommand[])(void) PROGMEM = {
@ -128,7 +130,7 @@ void (* const DisplayCommand[])(void) PROGMEM = {
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC,
&CmndDisplayBrightness, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC,
&CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplaySetLEDs, &CmndDisplaySetLED,
&CmndDisplayButtons, &CmndDisplayScrollText, &CmndDisplayType
&CmndDisplayButtons, &CmndDisplayScrollText, &CmndDisplayType, &CmndDisplayILIMOde , &CmndDisplayILIInvert
};
char *dsp_str;
@ -1904,13 +1906,13 @@ void CmndDisplayScrollText(void)
void CmndDisplayType(void)
{
if(ArgC() == 0) {
XdrvMailbox.payload = Settings.display_type;
XdrvMailbox.payload = Settings.display_options.data;
} else {
uint8_t prev_type = Settings.display_type;
uint8_t prev_type = Settings.display_options.data;
if(prev_type != XdrvMailbox.payload) {
if (!renderer) {
XdspCall(FUNC_DISPLAY_TYPE);
Settings.display_type = XdrvMailbox.payload;
Settings.display_options.data = XdrvMailbox.payload;
}
}
}
@ -1941,10 +1943,29 @@ void CmndDisplayFont(void)
ResponseCmndNumber(Settings.display_font);
}
void CmndDisplayILIMOde(void)
{
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload < 16)) {
Settings.display_options.ilimode = XdrvMailbox.payload;
TasmotaGlobal.restart_flag = 2;
}
ResponseCmndNumber(Settings.display_options.ilimode);
}
void CmndDisplayILIInvert(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
Settings.display_options.Invert = XdrvMailbox.payload;
if (renderer) renderer->invertDisplay(Settings.display_options.Invert);
}
ResponseCmndNumber(Settings.display_options.Invert);
}
void CmndDisplayRotate(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) {
if (Settings.display_rotate != XdrvMailbox.payload) {
if ((Settings.display_rotate) != XdrvMailbox.payload) {
/*
// Needs font info regarding height and width
if ((Settings.display_rotate &1) != (XdrvMailbox.payload &1)) {
@ -2033,7 +2054,6 @@ void CmndDisplayRows(void)
/*********************************************************************************************\
* optional drivers
\*********************************************************************************************/
#ifdef USE_TOUCH_BUTTONS
// very limited path size, so, add .jpg
void draw_picture(char *path, uint32_t xp, uint32_t yp, uint32_t xs, uint32_t ys, uint32_t ocol, bool inverted) {
@ -2588,6 +2608,7 @@ void AddValue(uint8_t num,float fval) {
}
#endif // USE_GRAPH
#if defined(USE_FT5206) || defined(USE_XPT2046)
#ifdef USE_FT5206
#include <FT5206.h>
@ -2624,11 +2645,49 @@ uint32_t Touch_Status(uint32_t sel) {
return 0;
}
}
#endif
#if defined(USE_XPT2046) && defined(USE_DISPLAY_ILI9341)
#include <XPT2046_Touchscreen.h>
XPT2046_Touchscreen *touchp;
TS_Point pLoc;
bool XPT2046_found;
bool Touch_Init(uint16_t CS) {
touchp = new XPT2046_Touchscreen(CS);
XPT2046_found = touchp->begin();
if (XPT2046_found) {
AddLog(LOG_LEVEL_INFO, PSTR("TS: XPT2046"));
}
return XPT2046_found;
}
uint32_t Touch_Status(uint32_t sel) {
if (XPT2046_found) {
switch (sel) {
case 0:
return touchp->touched();
case 1:
return pLoc.x;
case 2:
return pLoc.y;
}
return 0;
} else {
return 0;
}
}
#endif
#ifdef USE_TOUCH_BUTTONS
void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
#if defined(USE_FT5206)
ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#elif defined(USE_XPT2046)
ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
#endif
MqttPublishTeleSensor();
}
@ -2649,10 +2708,13 @@ uint8_t rbutt=0;
uint8_t vbutt=0;
if (touchp->touched()) {
if (touchp->touched()) {
// did find a hit
#if defined(USE_FT5206)
pLoc = touchp->getPoint(0);
#elif defined(USE_XPT2046)
pLoc = touchp->getPoint();
#endif
if (renderer) {
#ifdef USE_M5STACK_CORE2
@ -2677,7 +2739,7 @@ uint8_t vbutt=0;
rotconvert(&pLoc.x, &pLoc.y);
//AddLog(LOG_LEVEL_INFO, PSTR("touch %d - %d"), pLoc.x, pLoc.y);
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y);
// now must compare with defined buttons
for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) {
if (buttons[count]) {

View File

@ -191,6 +191,9 @@ public:
int32_t getInt(void) const;
uint32_t getUInt(void) const;
bool getBool(void) const;
// optimistically try to get any value as literal or in string - double to not lose precision for 32 bits
double getOptimisticDouble(void) const;
//
const SBuffer * getRaw(void) const;
// always return a point to a string, if not defined then empty string.
@ -437,6 +440,17 @@ JsonGeneratorArray & Z_attribute::newJsonArray(void) {
}
// get num values
double Z_attribute::getOptimisticDouble(void) const {
switch (type) {
case Za_type::Za_bool:
case Za_type::Za_uint: return (double) val.uval32;
case Za_type::Za_int: return (double) val.ival32;
case Za_type::Za_float: return (double) val.fval;
case Za_type::Za_str: return JsonParserToken::json_strtof(val.sval);
default: return 0.0;
}
}
float Z_attribute::getFloat(void) const {
switch (type) {
case Za_type::Za_bool:

View File

@ -1739,6 +1739,10 @@ void ZCLFrame::syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribu
if (0x64 == attrid) {
attr_list.addAttributePMEM(PSTR("SmokeDensity")).copyVal(attr);
}
} else if (modelId.startsWith(F("lumi.sensor_wleak"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttributePMEM(PSTR("Water")).copyVal(attr);
}
} else if (modelId.startsWith(F("lumi.sensor_natgas"))) { // gas leak
if (0x64 == attrid) {
attr_list.addAttributePMEM(PSTR("GasDensity")).copyVal(attr);

View File

@ -418,7 +418,7 @@ int32_t ZNP_Reboot(int32_t res, SBuffer &buf) {
}
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
"\"Status\":%d,\"Message\":\"CC2530 booted\",\"RestartReason\":\"%s\""
"\"Status\":%d,\"Message\":\"CCxxxx booted\",\"RestartReason\":\"%s\""
",\"MajorRel\":%d,\"MinorRel\":%d}}"),
ZIGBEE_STATUS_BOOT, reason_str,
major_rel, minor_rel);

View File

@ -265,7 +265,7 @@ void ZigbeeInputLoop(void) {
}
} else {
// the buffer timed-out, print error and discard
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %_B"), zigbee_buffer);
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %_B"), zigbee_buffer);
}
zigbee_buffer->setLen(0); // empty buffer
escape = false;

View File

@ -235,7 +235,7 @@ void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
// Write Tuya-Moes attribute
//
bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
double val_d = attr.getFloat();
double val_d = attr.getOptimisticDouble();
const char * val_str = attr.getStr();
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
@ -294,7 +294,7 @@ bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
// Send Attribute Write, apply mutlipliers before
//
bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok) {
double val_d = attr.getFloat();
double val_d = attr.getOptimisticDouble();
const char * val_str = attr.getStr();
if (attr.key_is_str) { return false; } // couldn't find attr if so skip

View File

@ -177,6 +177,17 @@ extern "C" {
ResponseCmndFailed();
be_return_nil(vm);
}
// update XdrvMailbox.command with actual command
int32_t l_resolveCmnd(bvm *vm);
int32_t l_resolveCmnd(bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 1 && be_isstring(vm, 1)) {
const char *msg = be_tostring(vm, 1);
strlcpy(XdrvMailbox.command, msg, CMDSZ);
}
be_return_nil(vm); // Return nil when something goes wrong
}
}
/*********************************************************************************************\
@ -277,6 +288,24 @@ extern "C" {
be_return_nil(vm); // Return nil when something goes wrong
}
// Berry: `validread(address:int, reg:int, size:int) -> int or nil`
int32_t b_wire_validread(struct bvm *vm);
int32_t b_wire_validread(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 3 && be_isint(vm, 1) && be_isint(vm, 2) && be_isint(vm, 3)) {
uint8_t addr = be_toint(vm, 1);
uint8_t reg = be_toint(vm, 2);
uint8_t size = be_toint(vm, 3);
bool ok = I2cValidRead(addr, reg, size);
if (ok) {
be_pushint(vm, i2c_buffer);
} else {
be_pushnil(vm);
}
be_return(vm); // Return
}
be_return_nil(vm); // Return nil when something goes wrong
}
}
/*********************************************************************************************\

View File

@ -44,7 +44,7 @@ const char berry_prog[] =
// Map all native functions to methods
// Again, this will be eventually pre-compiled
"var getfreeheap, publish, cmd, getoption, millis, timereached, yield "
"var respcmnd, respcmndstr, respcmnd_done, respcmnd_error, respcmnd_failed "
"var respcmnd, respcmndstr, respcmnd_done, respcmnd_error, respcmnd_failed, resolvecmnd "
"def init_ntv() "
"import tasmota_ntv "
"self.getfreeheap = tasmota_ntv.getfreeheap "
@ -61,6 +61,7 @@ const char berry_prog[] =
"self.respcmnd_done = tasmota_ntv.respcmnd_done "
"self.respcmnd_error = tasmota_ntv.respcmnd_error "
"self.respcmnd_failed = tasmota_ntv.respcmnd_failed "
"self.resolvecmnd = tasmota_ntv.resolvecmnd "
"end "
"def init() "
@ -207,8 +208,11 @@ const char berry_prog[] =
"var payload_json = json.load(payload) "
"var cmd_found = self.findkeyi(self._cmd, cmd) "
"if cmd_found != nil "
"return self._cmd[cmd_found](cmd_found, idx, payload, payload_json) "
"self.resolvecmnd(cmd_found) " // set the command name in XdrvMailbox.command
"self._cmd[cmd_found](cmd_found, idx, payload, payload_json) "
"return true "
"end "
"return false "
"end "
// Force gc and return allocated memory
@ -259,23 +263,6 @@ const char berry_prog[] =
// "try compile('/autoexec.be','file')() except .. log('BRY: no /autoexec.bat file') end "
// Wire
"wire.validread = def(addr, reg, size) "
"var ret = nil "
"for i:0..2 "
"wire.begintransmission(addr) "
"wire.write(reg) "
"if wire.endtransmission(false) == 0 "
"wire.requestfrom(addr, size) "
"if wire.available() == size "
"for j:0..size-1 "
"ret = ((ret != nil ? ret : 0) << 8) + wire.read() "
"end "
"return ret "
"end "
"end "
"end "
"wire.endtransmission() "
"end "
;
#endif // USE_BERRY

View File

@ -102,7 +102,7 @@ bool callBerryRule(void) {
}
bool callBerryCommand(void) {
const char * command = nullptr;
bool serviced = false;
checkBeTop();
be_getglobal(berry.vm, "_exec_cmd");
@ -111,16 +111,21 @@ bool callBerryCommand(void) {
be_pushint(berry.vm, XdrvMailbox.index);
be_pushstring(berry.vm, XdrvMailbox.data);
int ret = be_pcall(berry.vm, 3);
command = be_tostring(berry.vm, 3);
strlcpy(XdrvMailbox.topic, command, CMDSZ);
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Command (%s) serviced=%d"), XdrvMailbox.command, serviced);
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: top=%d", be_top(berry.vm));
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(1)=%s", be_typename(berry.vm, 1));
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(2)=%s", be_typename(berry.vm, 2));
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(3)=%s", be_typename(berry.vm, 3));
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(4)=%s", be_typename(berry.vm, 4));
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(5)=%s", be_typename(berry.vm, 5));
serviced = be_tobool(berry.vm, 1); // return value is in slot 1
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: serviced=%d", serviced);
be_pop(berry.vm, 4); // remove function object
} else {
be_pop(berry.vm, 1); // remove nil object
}
checkBeTop();
return command != nullptr; // TODO event not handled
return serviced; // TODO event not handled
}
size_t callBerryGC(void) {
@ -173,6 +178,35 @@ void callBerryFunctionVoid(const char * fname) {
checkBeTop();
}
/*********************************************************************************************\
* VM Observability
\*********************************************************************************************/
void BerryObservability(bvm *vm, int32_t event...);
void BerryObservability(bvm *vm, int32_t event...) {
va_list param;
va_start(param, event);
static int32_t vm_usage = 0;
static uint32_t gc_time = 0;
switch (event) {
case BE_OBS_GC_START:
{
gc_time = millis();
vm_usage = va_arg(param, int32_t);
}
break;
case BE_OBS_GC_END:
{
int32_t vm_usage2 = va_arg(param, int32_t);
uint32_t gc_elapsed = millis() - gc_time;
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "GC from %i to %i bytes (in %d ms)"), vm_usage, vm_usage2, gc_elapsed);
}
break;
default: break;
}
va_end(param);
}
/*********************************************************************************************\
* VM Init
\*********************************************************************************************/
@ -191,6 +225,7 @@ void BrReset(void) {
bool berry_init_ok = false;
do {
berry.vm = be_vm_new(); /* create a virtual machine instance */
be_set_obs_hook(berry.vm, &BerryObservability);
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry VM created, RAM used=%u"), be_gc_memcount(berry.vm));
// Register functions
@ -264,12 +299,12 @@ void CmndBrRun(void) {
} while (0);
if (0 == ret_code) {
// AddLog(LOG_LEVEL_INFO, "run: top=%d", be_top(berry.vm));
// AddLog(LOG_LEVEL_INFO, "run: type(1)=%s", be_typename(berry.vm, 1));
// AddLog(LOG_LEVEL_INFO, "run: type(2)=%s", be_typename(berry.vm, 2));
// code taken from REPL, look first at top, and if nil, look at return value
if (be_isnil(berry.vm, 0)) {
ret_val = be_tostring(berry.vm, -1);
} else {
ret_val = be_tostring(berry.vm, 0);
}
ret_val = be_tostring(berry.vm, 1);
Response_P("{\"" D_PRFX_BR "\":\"%s\"}", ret_val); // can't use XdrvMailbox.command as it may have been overwritten by subcommand
be_pop(berry.vm, 1);
} else {

View File

@ -19,7 +19,7 @@
#ifdef USE_SPI
#ifdef USE_DISPLAY
#if (defined(USE_DISPLAY_ILI9341) || defined(USE_DISPLAY_ILI9342))
#ifdef USE_DISPLAY_ILI9341
#define XDSP_04 4
@ -29,26 +29,30 @@ extern uint8_t *buffer;
extern uint8_t color_type;
ILI9341_2 *ili9341_2;
#ifdef USE_FT5206
#if defined(USE_FT5206)
#include <FT5206.h>
uint8_t ili9342_ctouch_counter = 0;
#elif defined(USE_XPT2046)
#include <XPT2046_Touchscreen.h>
uint8_t ili9342_ctouch_counter = 0;
#endif // USE_FT5206
bool tft_init_done = false;
#define ILI9341_ID 1
#define ILI9342_ID 2
//Settings.display_options.ilimode = ILI9341_ID;
/*********************************************************************************************/
void ILI9341_InitDriver()
{
#if (defined(USE_M5STACK_CORE2) || defined(USE_M5STACK_CORE_BASIC))
if (TasmotaGlobal.spi_enabled) {
#else
// There are displays without CS
if (PinUsed(GPIO_ILI9341_CS) || PinUsed(GPIO_ILI9341_DC) &&
(TasmotaGlobal.spi_enabled || TasmotaGlobal.soft_spi_enabled)) {
#endif
Settings.display_model = XDSP_04;
@ -62,35 +66,25 @@ void ILI9341_InitDriver()
// disable screen buffer
buffer = NULL;
#ifdef USE_DISPLAY_ILI9341
uint8_t dtype = 1;
#else
uint8_t dtype = 3; // sign ili9342 with variable spi pins
#endif // USE_DISPLAY_ILI9341
if (!Settings.display_options.ilimode) {
Settings.display_options.ilimode = ILI9341_ID;
}
// default colors
fg_color = ILI9341_WHITE;
bg_color = ILI9341_BLACK;
#ifdef USE_M5STACK_CORE2
// fixed pins on m5stack core2
ili9341_2 = new ILI9341_2(5, -2, 15, -2);
#elif defined(USE_M5STACK_CORE_BASIC)
// int8_t cs, int8_t res, int8_t dc, int8_t bp)
ili9341_2 = new ILI9341_2(14, 33, 27, 32);
#else
// check for special case with 2 SPI busses (ESP32 bitcoin)
if (TasmotaGlobal.soft_spi_enabled) {
// Init renderer, may use hardware spi, however we use SSPI defintion because SD card uses SPI definition (2 spi busses)
if (PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_MISO) && PinUsed(GPIO_SSPI_SCLK)) {
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, dtype);
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, Settings.display_options.ilimode & 3);
}
} else if (TasmotaGlobal.spi_enabled) {
if (PinUsed(GPIO_ILI9341_DC)) {
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, dtype);
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, Settings.display_options.ilimode & 3);
}
}
#endif // USE_M5STACK_CORE2
if (ili9341_2 == nullptr) {
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI934x invalid GPIOs"));
@ -99,6 +93,7 @@ void ILI9341_InitDriver()
ili9341_2->init(Settings.display_width, Settings.display_height);
renderer = ili9341_2;
renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font);
renderer->dim(Settings.display_dimmer);
@ -107,11 +102,7 @@ void ILI9341_InitDriver()
renderer->setTextFont(2);
renderer->setTextSize(1);
renderer->setTextColor(ILI9341_WHITE, ILI9341_BLACK);
#ifdef USE_DISPLAY_ILI9341
renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9341 TFT!", ILI9341_WHITE, 0);
#else
renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9342 TFT!", ILI9341_WHITE, 0);
#endif
renderer->DrawStringAt(50, (Settings.display_height/2)-12, (Settings.display_options.ilimode & 3)==ILI9341_ID?"ILI9341 TFT!":"ILI9342 TFT!", ILI9341_WHITE, 0);
delay(1000);
#endif // SHOW_SPLASH
@ -136,15 +127,16 @@ void ILI9341_InitDriver()
#endif // USE_FT5206
#endif // ESP32
tft_init_done = true;
#ifdef USE_DISPLAY_ILI9341
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9341"));
#else
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9342"));
#ifdef USE_XPT2046
Touch_Init(Pin(GPIO_XPT2046_CS));
#endif
tft_init_done = true;
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9341"));
}
}
void core2_disp_pwr(uint8_t on);
void core2_disp_dim(uint8_t dim);
@ -160,11 +152,11 @@ void ili9342_dimm(uint8_t dim) {
#endif
}
#ifdef ESP32
#ifdef USE_FT5206
#if defined(USE_FT5206) || defined(USE_XPT2046)
#ifdef USE_TOUCH_BUTTONS
void ili9342_RotConvert(int16_t *x, int16_t *y) {
#if defined(USE_FT5206)
void TS_RotConvert(int16_t *x, int16_t *y) {
int16_t temp;
if (renderer) {
@ -189,6 +181,38 @@ int16_t temp;
}
}
}
#elif defined(USE_XPT2046)
void TS_RotConvert(int16_t *x, int16_t *y) {
int16_t temp;
if (renderer) {
uint8_t rot = renderer->getRotation();
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: before convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height());
temp = map(*x,XPT2046_MINX,XPT2046_MAXX, renderer->height(), 0);
*x = map(*y,XPT2046_MINY,XPT2046_MAXY, renderer->width(), 0);
*y = temp;
switch (rot) {
case 0:
break;
case 1:
temp = *y;
*y = renderer->width() - *x;
*x = temp;
break;
case 2:
*x = renderer->width() - *x;
*y = renderer->height() - *y;
break;
case 3:
temp = *y;
*y = *x;
*x = renderer->height() - temp;
break;
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: after convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height());
}
}
#endif
// check digitizer hit
void ili9342_CheckTouch() {
@ -196,12 +220,12 @@ ili9342_ctouch_counter++;
if (2 == ili9342_ctouch_counter) {
// every 100 ms should be enough
ili9342_ctouch_counter = 0;
Touch_Check(ili9342_RotConvert);
Touch_Check(TS_RotConvert);
}
}
#endif // USE_TOUCH_BUTTONS
#endif // USE_FT5206
#endif // ESP32
#ifdef USE_DISPLAY_MODES1TO5
@ -235,7 +259,7 @@ bool Ili9341Header(void) {
void Ili9341InitMode(void) {
// renderer->setRotation(Settings.display_rotate); // 0
#ifdef USE_DISPLAY_ILI9341
renderer->invertDisplay(0);
// renderer->invertDisplay(0);
#endif
renderer->fillScreen(ILI9341_BLACK);
renderer->setTextWrap(false); // Allow text to run off edges
@ -360,10 +384,15 @@ bool Xdsp04(uint8_t function)
case DISPLAY_INIT_MODE:
renderer->clearDisplay();
break;
#ifdef USE_FT5206
#if defined(USE_FT5206) || defined(USE_XPT2046)
#ifdef USE_TOUCH_BUTTONS
case FUNC_DISPLAY_EVERY_50_MSECOND:
#if defined(USE_FT5206)
if (FT5206_found) {
#elif defined(USE_XPT2046)
if (XPT2046_found) {
#endif
ili9342_CheckTouch();
}
break;

363
tasmota/xnrg_19_cse7761.ino Normal file
View File

@ -0,0 +1,363 @@
/*
xnrg_19_cse7761.ino - CSE7761 energy sensor support for Tasmota
Copyright (C) 2021 Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_ENERGY_SENSOR
#ifdef USE_CSE7761
/*********************************************************************************************\
* CSE7761 - Energy (Sonoff Dual R3 Pow)
*
* Based on datasheet from ChipSea
\*********************************************************************************************/
#define XNRG_19 19
#define CSE7761_K1 2 // Current channel sampling resistance in milli Ohm
#define CSE7761_K2 2 // Voltage divider resistance in 1k/1M
#define CSE7761_2POWER22 4194304
#define CSE7761_2POWER23 8388608
#define CSE7761_2POWER31 2147483648
enum CSE7761 { RmsIAC, RmsIBC, RmsUC, PowerPAC, PowerPBC, PowerSC, EnergyAc, EnergyBC };
#include <TasmotaSerial.h>
TasmotaSerial *Cse7761Serial = nullptr;
struct {
uint32_t voltage_rms = 0;
uint32_t current_rms[2] = { 0 };
uint32_t active_power[2] = { 0 };
uint16_t coefficient[8] = { 0 };
uint8_t init = 0;
bool found = false;
} CSE7761Data;
void Cse7761Write(uint32_t reg, uint32_t data) {
uint8_t buffer[5];
buffer[0] = 0xA5;
buffer[1] = reg;
uint32_t len = 2;
if (data) {
if (data < 0xFF) {
buffer[2] = data & 0xFF;
len = 3;
} else {
buffer[2] = (data >> 8) & 0xFF;
buffer[3] = data & 0xFF;
len = 4;
}
uint8_t crc = 0;
for (uint32_t i = 0; i < len; i++) {
crc += buffer[i];
}
buffer[len] = ~crc;
len++;
}
Cse7761Serial->write(buffer, len);
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Send %d, Data %*_H"), len, len, buffer);
}
uint32_t Cse7761Read(uint32_t reg, uint32_t request) {
Cse7761Serial->flush();
Cse7761Write(reg, 0);
uint8_t buffer[8];
uint32_t rcvd = 0;
uint32_t timeout = millis() + 3;
while (!TimeReached(timeout)) {
int value = Cse7761Serial->read();
if ((value > -1) && (rcvd < sizeof(buffer) -1)) {
buffer[rcvd++] = value;
}
}
if (!rcvd) {
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Rcvd %d"), rcvd);
return 0;
}
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Rcvd %d, Data %*_H"), rcvd, rcvd, buffer);
int result = 0;
uint8_t crc = 0xA5 + reg;
for (uint32_t i = 0; i < rcvd -1; i++) {
result = (result << 8) | buffer[i];
crc += buffer[i];
}
crc = ~crc;
if (crc != buffer[rcvd]) {
result = 0;
}
return result;
}
bool Cse7761ChipInit(void) {
uint16_t calc_chksum = 0xFFFF;
for (uint32_t i = 0; i < 8; i++) {
CSE7761Data.coefficient[i] = Cse7761Read(0x70 + i, 2);
calc_chksum += CSE7761Data.coefficient[i];
}
uint16_t dummy = Cse7761Read(0x6E, 2);
uint16_t coeff_chksum = Cse7761Read(0x6F, 2);
if (calc_chksum != coeff_chksum) {
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Coefficients invalid"));
// return false;
}
delay(3);
Cse7761Write(0xEA, 0xE5); // Enable write operation
delay(5);
uint8_t sys_status = Cse7761Read(0x43, 1);
if (sys_status & 0x10) { // Write enable to protected registers (WREN)
delay(3);
/*
System Control Register (SYSCON) Addr:0x00 Default value: 0x0A04
Bit name Function description
15-11 NC -, the default is 1
10 ADC2ON
=1, means ADC current channel B is on (Sonoff Dual R3 Pow)
=0, means ADC current channel B is closed
9 NC -, the default is 1.
8-6 PGAIB[2:0] Current channel B analog gain selection highest bit
=1XX, PGA of current channel B=16
=011, PGA of current channel B=8
=010, PGA of current channel B=4
=001, PGA of current channel B=2
=000, PGA of current channel B=1 (Sonoff Dual R3 Pow)
5-3 PGAU[2:0] Highest bit of voltage channel analog gain selection
=1XX, PGA of current channel U=16
=011, PGA of current channel U=8
=010, PGA of current channel U=4
=001, PGA of current channel U=2 (Sonoff Dual R3 Pow)
=000, PGA of current channel U=1
2-0 PGAIA[2:0] Current channel A analog gain selection highest bit
=1XX, PGA of current channel A=16
=011, PGA of current channel A=8
=010, PGA of current channel A=4
=001, PGA of current channel A=2
=000, PGA of current channel A=1 (Sonoff Dual R3 Pow)
*/
Cse7761Write(0x80, 0xFF04); // Set SYSCON
/*
Energy Measure Control Register (EMUCON) Addr:0x01 Default value: 0x0000
Bit name Function description
15-14 Tsensor_Step[1:0] Measurement steps of temperature sensor:
=2'b00 The first step of temperature sensor measurement, the Offset of OP1 and OP2 is +/+. (Sonoff Dual R3 Pow)
=2'b01 The second step of temperature sensor measurement, the Offset of OP1 and OP2 is +/-.
=2'b10 The third step of temperature sensor measurement, the Offset of OP1 and OP2 is -/+.
=2'b11 The fourth step of temperature sensor measurement, the Offset of OP1 and OP2 is -/-.
After measuring these four results and averaging, the AD value of the current measured temperature can be obtained.
13 tensor_en Temperature measurement module control
=0 when the temperature measurement module is closed; (Sonoff Dual R3 Pow)
=1 when the temperature measurement module is turned on;
12 comp_off Comparator module close signal:
=0 when the comparator module is in working state
=1 when the comparator module is off (Sonoff Dual R3 Pow)
11-10 Pmode[1:0] Selection of active energy calculation method:
Pmode =00, both positive and negative active energy participate in the accumulation,
the accumulation method is algebraic sum mode, the reverse REVQ symbol indicates to active power; (Sonoff Dual R3 Pow)
Pmode = 01, only accumulate positive active energy;
Pmode = 10, both positive and negative active energy participate in the accumulation,
and the accumulation method is absolute value method. No reverse active power indication;
Pmode =11, reserved, the mode is the same as Pmode =00
9 NC -
8 ZXD1 The initial value of ZX output is 0, and different waveforms are output according to the configuration of ZXD1 and ZXD0:
=0, it means that the ZX output changes only at the selected zero-crossing point (Sonoff Dual R3 Pow)
=1, indicating that the ZX output changes at both the positive and negative zero crossings
7 ZXD0
=0, indicates that the positive zero-crossing point is selected as the zero-crossing detection signal (Sonoff Dual R3 Pow)
=1, indicating that the negative zero-crossing point is selected as the zero-crossing detection signal
6 HPFIBOFF
=0, enable current channel B digital high-pass filter (Sonoff Dual R3 Pow)
=1, turn off the digital high-pass filter of current channel B
5 HPFIAOFF
=0, enable current channel A digital high-pass filter (Sonoff Dual R3 Pow)
=1, turn off the digital high-pass filter of current channel A
4 HPFUOFF
=0, enable U channel digital high pass filter (Sonoff Dual R3 Pow)
=1, turn off the U channel digital high-pass filter
3-2 NC -
1 PBRUN
=1, enable PFB pulse output and active energy register accumulation; (Sonoff Dual R3 Pow)
=0 (default), turn off PFB pulse output and active energy register accumulation.
0 PARUN
=1, enable PFA pulse output and active energy register accumulation; (Sonoff Dual R3 Pow)
=0 (default), turn off PFA pulse output and active energy register accumulation.
*/
Cse7761Write(0x81, 0x1003); // Set EMUCON
/*
Energy Measure Control Register (EMUCON2) Addr: 0x13 Default value: 0x0001
Bit name Function description
15-13 NC -
12 SDOCmos
=1, SDO pin CMOS open-drain output (Sonoff Dual R3 Pow)
=0, SDO pin CMOS output
11 EPB_CB Energy_PB clear signal control, the default is 0, and it needs to be configured to 1 in UART mode.
Clear after reading is not supported in UART mode
=1, Energy_PB will not be cleared after reading; (Sonoff Dual R3 Pow)
=0, Energy_PB is cleared after reading;
10 EPA_CB Energy_PA clear signal control, the default is 0, it needs to be configured to 1 in UART mode,
Clear after reading is not supported in UART mode
=1, Energy_PA will not be cleared after reading; (Sonoff Dual R3 Pow)
=0, Energy_PA is cleared after reading;
9-8 DUPSEL[1:0] Average register update frequency control
=00, Update frequency 3.4Hz
=01, Update frequency 6.8Hz
=10, Update frequency 13.65Hz
=11, Update frequency 27.3Hz (Sonoff Dual R3 Pow)
7 CHS_IB Current channel B measurement selection signal
=1, measure the current of channel B (Sonoff Dual R3 Pow)
=0, measure the internal temperature of the chip
6 PfactorEN Power factor function enable
=1, turn on the power factor output function (Sonoff Dual R3 Pow)
=0, turn off the power factor output function
5 WaveEN Waveform data, instantaneous data output enable signal
=1, turn on the waveform data output function
=0, turn off the waveform data output function (Sonoff Dual R3 Pow)
4 SAGEN Voltage drop detection enable signal, WaveEN=1 must be configured first
=1, turn on the voltage drop detection function
=0, turn off the voltage drop detection function (Sonoff Dual R3 Pow)
3 OverEN Overvoltage, overcurrent, and overload detection enable signal, WaveEN=1 must be configured first
=1, turn on the overvoltage, overcurrent, and overload detection functions
=0, turn off the overvoltage, overcurrent, and overload detection functions (Sonoff Dual R3 Pow)
2 ZxEN Zero-crossing detection, phase angle, voltage frequency measurement enable signal
=1, turn on the zero-crossing detection, phase angle, and voltage frequency measurement functions
=0, disable zero-crossing detection, phase angle, voltage frequency measurement functions (Sonoff Dual R3 Pow)
1 PeakEN Peak detect enable signal
=1, turn on the peak detection function
=0, turn off the peak detection function (Sonoff Dual R3 Pow)
0 NC Default is 1
*/
Cse7761Write(0x93, 0x0FC1); // Set EMUCON2
} else {
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Write enable failed"));
// return false;
}
delay(80);
Cse7761Write(0xEA, 0xDC); // Close write operation
return true;
}
void Cse7761GetData(void) {
CSE7761Data.voltage_rms = Cse7761Read(0x26, 3);
CSE7761Data.current_rms[0] = Cse7761Read(0x24, 3);
CSE7761Data.active_power[0] = Cse7761Read(0x2C, 4);
CSE7761Data.current_rms[1] = Cse7761Read(0x25, 3);
CSE7761Data.active_power[1] = Cse7761Read(0x2D, 4);
if (Energy.power_on) { // Powered on
Energy.voltage[0] = ((float)CSE7761Data.voltage_rms * ((double)CSE7761Data.coefficient[RmsUC] / (CSE7761_K2 * 2 * CSE7761_2POWER22))) / 1000; // V
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] * ((double)CSE7761Data.coefficient[PowerPAC + channel] / (CSE7761_K1 * CSE7761_K2 * 2 * CSE7761_2POWER31)); // W
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] * ((double)CSE7761Data.coefficient[RmsIAC + channel] / (CSE7761_K1 * 2 * CSE7761_2POWER23)); // mA
}
}
uint32_t active_power_sum = (Energy.active_power[0] + Energy.active_power[1]) * 1000;
if (active_power_sum) {
Energy.kWhtoday_delta += active_power_sum / 36;
EnergyUpdateToday();
}
} else { // Powered off
Energy.data_valid[0] = ENERGY_WATCHDOG;
Energy.data_valid[1] = ENERGY_WATCHDOG;
}
}
/********************************************************************************************/
void Cse7761EverySecond(void) {
if (CSE7761Data.init) {
if (2 == CSE7761Data.init) {
Cse7761Write(0xEA, 0x96); // Reset chip
}
else if (1 == CSE7761Data.init) {
uint16_t syscon = Cse7761Read(0x00, 2); // Default 0x0A04
if (0x0A04 == syscon) {
CSE7761Data.found = Cse7761ChipInit();
}
if (CSE7761Data.found) {
AddLog(LOG_LEVEL_INFO, PSTR("C61: CSE7761 found"));
}
}
CSE7761Data.init--;
}
else {
if (CSE7761Data.found) {
Cse7761GetData();
}
}
}
void Cse7761SnsInit(void) {
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX), Pin(GPIO_CSE7761_TX), 1);
if (Cse7761Serial->begin(38400, SERIAL_8E1)) {
if (Cse7761Serial->hardwareSerial()) {
// SetSerial(38400, TS_SERIAL_8E1);
ClaimSerial();
}
} else {
TasmotaGlobal.energy_driver = ENERGY_NONE;
}
}
void Cse7761DrvInit(void) {
if (PinUsed(GPIO_CSE7761_RX) && PinUsed(GPIO_CSE7761_TX)) {
CSE7761Data.found = false;
CSE7761Data.init = 3; // Init setup steps
Energy.phase_count = 2; // Handle two channels as two phases
Energy.voltage_common = true; // Use common voltage
TasmotaGlobal.energy_driver = XNRG_19;
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xnrg19(uint8_t function) {
bool result = false;
switch (function) {
case FUNC_EVERY_SECOND:
Cse7761EverySecond();
break;
case FUNC_INIT:
Cse7761SnsInit();
break;
case FUNC_PRE_INIT:
Cse7761DrvInit();
break;
}
return result;
}
#endif // USE_CSE7761
#endif // USE_ENERGY_SENSOR

View File

@ -822,8 +822,12 @@ uint8_t Serial_peek() {
return meter_ss[num-1]->peek();
}
uint8_t sml_logindex;
char log_data[128];
#ifndef SML_DUMP_SIZE
#define SML_DUMP_SIZE 128
#endif
uint16_t sml_logindex;
char log_data[SML_DUMP_SIZE];
#define SML_EBUS_SKIP_SYNC_DUMPS
@ -884,8 +888,8 @@ void Dump2log(void) {
char c = SML_SREAD&0x7f;
if (c == '\n' || c == '\r') {
if (sml_logindex > 2) {
AddLogData(LOG_LEVEL_INFO, log_data);
log_data[sml_logindex] = 0;
AddLogData(LOG_LEVEL_INFO, log_data);
log_data[0] = ':';
log_data[1] = ' ';
sml_logindex = 2;
@ -903,6 +907,7 @@ void Dump2log(void) {
while (SML_SAVAILABLE) {
c = SML_SREAD;
if (c == VBUS_SYNC) {
log_data[sml_logindex] = 0;
AddLogData(LOG_LEVEL_INFO, log_data);
log_data[0] = ':';
log_data[1] = ' ';
@ -922,6 +927,7 @@ void Dump2log(void) {
p = SML_SPEAK;
if (p != EBUS_SYNC && sml_logindex > 5) {
// new packet, plot last one
log_data[sml_logindex] = 0;
AddLogData(LOG_LEVEL_INFO, log_data);
strcpy(&log_data[0], ": aa ");
sml_logindex = 5;
@ -939,6 +945,7 @@ void Dump2log(void) {
while (SML_SAVAILABLE) {
c = SML_SREAD;
if (c == SML_SYNC) {
log_data[sml_logindex] = 0;
AddLogData(LOG_LEVEL_INFO, log_data);
log_data[0] = ':';
log_data[1] = ' ';
@ -962,6 +969,7 @@ void Dump2log(void) {
}
}
if (sml_logindex > 2) {
log_data[sml_logindex] = 0;
AddLogData(LOG_LEVEL_INFO, log_data);
}
}
@ -1472,6 +1480,7 @@ void SML_Decode(uint8_t index) {
double fac = CharToDouble((char*)mp);
meter_vars[vindex] /= fac;
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
dvalid[vindex] = 1;
// get sfac
} else if (*mp=='d') {
// calc deltas d ind 10 (eg every 10 secs)
@ -1489,7 +1498,16 @@ void SML_Decode(uint8_t index) {
dtimes[dindex] = millis();
double vdiff = meter_vars[ind - 1] - dvalues[dindex];
dvalues[dindex] = meter_vars[ind - 1];
meter_vars[vindex] = (double)360000.0 * vdiff / ((double)dtime / 10000.0);
double dres = (double)360000.0 * vdiff / ((double)dtime / 10000.0);
#ifdef USE_SML_MEDIAN_FILTER
if (meter_desc_p[mindex].flag & 16) {
meter_vars[vindex] = sml_median(&sml_mf[vindex], dres);
} else {
meter_vars[vindex] = dres;
}
#else
meter_vars[vindex] = dres;
#endif
mp=strchr(mp,'@');
if (mp) {
@ -1499,6 +1517,7 @@ void SML_Decode(uint8_t index) {
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
}
}
dvalid[vindex] = 1;
dindex++;
}
} else if (*mp == 'h') {
@ -1731,6 +1750,7 @@ void SML_Decode(uint8_t index) {
}
if (found) {
// matches, get value
dvalid[vindex] = 1;
mp++;
#ifdef ED300L
g_mindex=mindex;
@ -1838,7 +1858,6 @@ void SML_Decode(uint8_t index) {
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
}
}
dvalid[vindex] = 1;
//AddLog(LOG_LEVEL_INFO, PSTR("set valid in line %d"), vindex);
}
nextsect: