mirror of https://github.com/arendst/Tasmota.git
GPIO Viewer update from 1.0.7 to 1.5.0
This commit is contained in:
parent
1e7bbfcc00
commit
af9d4cadd8
|
@ -0,0 +1,25 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
// compressed by tools/unishox/compress-html-uncompressed.py
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
const size_t HTTP_GV_PAGE_SIZE = 465;
|
||||
const char HTTP_GV_PAGE_COMPRESSED[] PROGMEM = "\x3D\x0F\xE1\x10\x98\x1D\x19\x0C\x64\x85\x50\xD0\x8F\xC3\xD0\x55\x0D\x09\x05\x7C"
|
||||
"\x3C\x7C\x3E\xDF\x1F\x67\xE1\xE8\x29\xD8\x87\xE1\xE9\x5B\x41\x33\xF0\xFA\xF2\x3A"
|
||||
"\xD1\x0F\x10\xC2\xD2\xC4\x46\x7A\xC7\xDF\xCF\x43\xB0\x10\x6A\x1E\x83\x5D\x5A\x0C"
|
||||
"\x55\xFF\xCE\x8F\x87\xD9\x0B\x2A\x2B\x23\x07\x59\xCF\x9F\x67\xE1\xE8\x43\xAF\xCD"
|
||||
"\x0A\xFB\x30\x7C\x3E\xCF\xAF\x1F\x67\xE1\xE8\x16\xF1\xA2\xFB\x08\xF8\x7D\xE8\x79"
|
||||
"\xC7\xD8\x21\x57\x31\x66\x7A\x1E\x71\xD3\x43\xC3\xEC\x10\xB2\x6E\xB1\xAC\xF8\x7D"
|
||||
"\x99\xEB\x1F\x19\x9F\xA3\xED\x07\x9D\x4F\xA8\xF8\x7D\x8F\xE8\x94\x28\xF8\x23\x33"
|
||||
"\xD0\xD9\xD6\x3F\xA2\x50\xA3\xA9\x6F\x6D\x6D\x84\x75\xF8\x3B\x09\x9F\x0E\x43\xA3"
|
||||
"\x3E\xCF\xC3\xD0\xBC\x1F\xF4\x65\x2A\x2B\x32\x18\xCF\x87\xD8\xDC\x10\x58\x4C\xFB"
|
||||
"\x41\xFF\x3D\xEC\xFE\x8F\x6F\x2F\x7C\x33\xE1\xF6\x43\xC4\x30\xB4\xB0\x10\x78\x25"
|
||||
"\x23\x31\x6C\xE8\x6B\xF1\xF6\x7E\x1E\x87\x60\x20\xE2\xC0\x8F\xC0\x47\xA8\xC8\x27"
|
||||
"\xE1\x4D\xD0\x24\xE3\xE0\x83\xC0\xD5\xFB\xCE\xBC\x76\x0D\xBD\xE3\xA0\x7E\xF1\xF6"
|
||||
"\x7E\x1E\x87\x60\x20\xF1\x1C\x3B\x04\x32\x3F\x0F\x41\x34\xCD\x68\x87\xC3\xEE\xC6"
|
||||
"\x0C\x3E\xCF\xC3\xD0\xEC\x13\x4C\xC1\x0F\x79\x3F\x07\xF7\x84\xC1\xF3\xA0\xF0\xCD"
|
||||
"\xC3\xF7\xE7\x55\xBC\x3D\xE4\x7C\x47\xB7\x46\x1E\x67\xD9\xF5\xE3\xEC\xEA\x19\x9F"
|
||||
"\xA3\xCC\xFB\x3E\x84\x3E\xCE\xA3\x1F\x6C\xBC\x68\xE8\x31\x45\xFB\x1A\x79\x9F\x67"
|
||||
"\xD0\x88\x8D\x08\x71\xF6\x7B\x8F\x2A\x01\x8B\xC0\x49\xD8\x08\x3A\x49\xD8\x2A\x2B"
|
||||
"\x86\x84\x7E\x1B";
|
||||
|
||||
#define HTTP_GV_PAGE Decompress(HTTP_GV_PAGE_COMPRESSED,HTTP_GV_PAGE_SIZE).c_str()
|
|
@ -0,0 +1,24 @@
|
|||
const char HTTP_GV_PAGE[] PROGMEM =
|
||||
"<!DOCTYPE html>"
|
||||
"<html lang='en'>"
|
||||
"<head>"
|
||||
"<title>%s - GPIO Viewer</title>" // SettingsTextEscaped(SET_DEVICENAME).c_str()
|
||||
"<meta charset='UTF-8'>"
|
||||
"<base href='%s'>" // GV_BASE_URL
|
||||
"<link rel='icon' href='favicon.ico'>"
|
||||
"<meta name='viewport' content='width=device-width, initial-scale=1.0'>"
|
||||
"<script type='module' crossorigin src='GPIOViewerVue.js'>"
|
||||
"</script>"
|
||||
"<link rel='stylesheet' crossorigin href='assets/main.css'>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<div id='app'></div>"
|
||||
"<script>"
|
||||
"window.gpio_settings = {"
|
||||
"ip:'%s'," // WiFi.localIP().toString().c_str()
|
||||
"port:'%d'," // GV_PORT
|
||||
"freeSketchRam:'%d KB'" // ESP_getFreeSketchSpace() / 1024
|
||||
"};"
|
||||
"</script>"
|
||||
"</body>"
|
||||
"</html>";
|
|
@ -470,8 +470,7 @@
|
|||
#define USE_ENHANCED_GUI_WIFI_SCAN // Enable Wi-Fi scan output with BSSID (+0k5 code)
|
||||
// #define USE_WEBSEND_RESPONSE // Enable command WebSend response message (+1k code)
|
||||
// #define USE_WEBGETCONFIG // Enable restoring config from external webserver (+0k6)
|
||||
// #define USE_GPIO_VIEWER // Enable GPIO Viewer to see realtime GPIO states (+4k code)
|
||||
// #define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer/assets/"
|
||||
// #define USE_GPIO_VIEWER // Enable GPIO Viewer to see realtime GPIO states (+6k code)
|
||||
// #define GV_SAMPLING_INTERVAL 100 // [GvSampling] milliseconds - Use Tasmota Scheduler (100) or Ticker (20..99,101..1000)
|
||||
#define USE_EMULATION_HUE // Enable Hue Bridge emulation for Alexa (+14k code, +2k mem common)
|
||||
#define USE_EMULATION_WEMO // Enable Belkin WeMo emulation for Alexa (+6k code, +2k mem common)
|
||||
|
|
|
@ -501,6 +501,10 @@ uint32_t ESP_getFreeSketchSpace(void) {
|
|||
return ESP.getFreeSketchSpace();
|
||||
}
|
||||
|
||||
uint32_t ESP_getHeapSize(void) {
|
||||
return ESP.getHeapSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap(void) {
|
||||
// ESP_getFreeHeap() returns also IRAM which we don't use
|
||||
return heap_caps_get_free_size(MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
|
@ -558,6 +562,18 @@ uint8_t* FlashDirectAccess(void) {
|
|||
return data;
|
||||
}
|
||||
|
||||
uint32_t ESP_getPsramSize(void) {
|
||||
return ESP.getPsramSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreePsram(void) {
|
||||
return ESP.getFreePsram();
|
||||
}
|
||||
|
||||
uint32_t ESP_getMaxAllocPsram(void) {
|
||||
return ESP.getMaxAllocPsram();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#if ESP_IDF_VERSION_MAJOR >= 5
|
||||
// bool IRAM_ATTR __attribute__((pure)) esp_psram_is_initialized(void)
|
||||
|
@ -948,6 +964,18 @@ String GetCodeCores(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipCores(void) {
|
||||
return ESP.getChipCores();
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipRevision(void) {
|
||||
return ESP.getChipRevision();
|
||||
}
|
||||
|
||||
String ESP_getEfuseMac(void) {
|
||||
return String(ESP.getEfuseMac());
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* High entropy hardware random generator
|
||||
* Thanks to DigitalAlchemist
|
||||
|
|
|
@ -85,6 +85,10 @@ uint32_t ESP_getSketchSize(void) {
|
|||
return ESP.getSketchSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getHeapSize(void) {
|
||||
return 32768; // Using default heap (No PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED)
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreeHeap(void) {
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
|
@ -98,6 +102,10 @@ float ESP_getFreeHeap1024(void) {
|
|||
}
|
||||
*/
|
||||
|
||||
uint32_t ESP_getMaxAllocHeap(void) {
|
||||
return ESP.getFreeHeap();
|
||||
}
|
||||
|
||||
uint32_t ESP_getFlashChipId(void) {
|
||||
return ESP.getFlashChipId();
|
||||
}
|
||||
|
@ -110,6 +118,18 @@ uint32_t ESP_getFlashChipSize(void) {
|
|||
return ESP.getFlashChipSize();
|
||||
}
|
||||
|
||||
uint32_t ESP_getPsramSize(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ESP_getFreePsram(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ESP_getMaxAllocPsram(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ESP_Restart(void) {
|
||||
// ESP.restart(); // This results in exception 3 on restarts on core 2.3.0
|
||||
ESP.reset();
|
||||
|
@ -197,6 +217,48 @@ String GetCodeCores(void) {
|
|||
return F("");
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipCores(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t ESP_getChipRevision(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
String ESP_getEfuseMac(void) {
|
||||
uint32_t mac0 = *(uint32_t*)(0x3FF00050);
|
||||
uint32_t mac1 = *(uint32_t*)(0x3FF00054);
|
||||
uint32_t mac3 = *(uint32_t*)(0x3FF0005C);
|
||||
|
||||
uint32_t mach = 0;
|
||||
uint32_t macl = 0;
|
||||
if (mac3 != 0) {
|
||||
mach = ((mac3 >> 16) & 0xFF) << 16;
|
||||
mach |= ((mac3 >> 8) & 0xFF) << 8;
|
||||
mach |= mac3 & 0xFF;
|
||||
}
|
||||
else if (((mac1 >> 16) & 0xFF) == 0) {
|
||||
mach = 0x18FE34;
|
||||
}
|
||||
else if (((mac1 >> 16) & 0xFF) == 1) {
|
||||
mach = 0xACD074;
|
||||
}
|
||||
String macStr = "";
|
||||
if (mach > 0) {
|
||||
macl = ((mac1 >> 8) & 0xFF) << 16;
|
||||
macl |= (mac1 & 0xFF) << 8;
|
||||
macl |= (mac0 >> 24) & 0xFF;
|
||||
|
||||
uint64_t maca = ((uint64_t)mach << 24) | macl;
|
||||
// Need uint64ToString with base 10 as ESP8266 WStrings does not support uint64_t
|
||||
while (maca > 0) {
|
||||
macStr = String((uint32_t)(maca % 10), 10) + macStr;
|
||||
maca /= 10;
|
||||
}
|
||||
}
|
||||
return String(macStr);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* High entropy hardware random generator
|
||||
* Thanks to DigitalAlchemist
|
||||
|
|
|
@ -17,6 +17,15 @@
|
|||
|
||||
#define XDRV_121 121
|
||||
|
||||
//#define GV_INPUT_DETECTION // Report type of digital input
|
||||
|
||||
#define GV_USE_ESPINFO // Provide ESP info
|
||||
#ifdef ESP32
|
||||
#ifndef GV_USE_ESPINFO
|
||||
#define GV_USE_ESPINFO // Provide ESP info
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GV_PORT
|
||||
#define GV_PORT 5557 // SSE webserver port
|
||||
#endif
|
||||
|
@ -27,29 +36,15 @@
|
|||
#define GV_KEEP_ALIVE 1000 // milliseconds - If no activity after this do a heap size event anyway
|
||||
|
||||
#ifndef GV_BASE_URL
|
||||
#define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer/assets/"
|
||||
#define GV_BASE_URL "https://thelastoutpostworkshop.github.io/microcontroller_devkit/gpio_viewer_1_5/"
|
||||
#endif
|
||||
/*
|
||||
#ifdef ESP8266
|
||||
#ifndef GV_BASE_URL
|
||||
#undef GV_BASE_URL // Fix compiler warning
|
||||
#define GV_BASE_URL "https://ota.tasmota.com/tasmota/gpio_viewer/assets/"
|
||||
#endif
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
#ifndef GV_BASE_URL
|
||||
#undef GV_BASE_URL // Fix compiler warning
|
||||
#define GV_BASE_URL "https://ota.tasmota.com/tasmota32/gpio_viewer/assets/"
|
||||
#endif
|
||||
#endif // ESP32
|
||||
*/
|
||||
|
||||
const char *GVRelease = "1.0.7";
|
||||
const char *GVRelease = "1.5.0";
|
||||
|
||||
#ifdef USE_UNISHOX_COMPRESSION
|
||||
#include "./html_compressed/HTTP_GV_PAGE.h"
|
||||
#include "./html_compressed/HTTP_GV_PAGE_150.h"
|
||||
#else
|
||||
#include "./html_uncompressed/HTTP_GV_PAGE.h"
|
||||
#include "./html_uncompressed/HTTP_GV_PAGE_150.h"
|
||||
#endif
|
||||
|
||||
const char HTTP_GV_EVENT[] PROGMEM =
|
||||
|
@ -62,7 +57,12 @@ const char HTTP_GV_EVENT[] PROGMEM =
|
|||
enum GVPinTypes {
|
||||
GV_DigitalPin = 0,
|
||||
GV_PWMPin = 1,
|
||||
GV_AnalogPin = 2
|
||||
GV_AnalogPin = 2,
|
||||
#ifdef GV_INPUT_DETECTION
|
||||
GV_InputPin = 3,
|
||||
GV_InputPullUp = 4,
|
||||
GV_InputPullDn = 5
|
||||
#endif // GV_INPUT_DETECTION
|
||||
};
|
||||
|
||||
struct {
|
||||
|
@ -78,6 +78,26 @@ struct {
|
|||
bool sse_ready;
|
||||
} GV;
|
||||
|
||||
#ifdef GV_INPUT_DETECTION
|
||||
|
||||
int GetPinMode(uint8_t pin) {
|
||||
#ifdef ESP8266
|
||||
if (pin > MAX_GPIO_PIN -2) { return -1; } // Skip GPIO16 and Analog0
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (pin > MAX_GPIO_PIN) { return -1; }
|
||||
#endif // ESP32
|
||||
|
||||
uint32_t bit = digitalPinToBitMask(pin);
|
||||
uint32_t port = digitalPinToPort(pin);
|
||||
volatile uint32_t *reg = portModeRegister(port);
|
||||
if (*reg & bit) { return OUTPUT; } // ESP8266 = 0x01, ESP32 = 0x03
|
||||
volatile uint32_t *out = portOutputRegister(port);
|
||||
return ((*out & bit) ? INPUT_PULLUP : INPUT); // ESP8266 = 0x02 : 0x00, ESP32 = 0x05 : x01
|
||||
}
|
||||
|
||||
#endif // GV_INPUT_DETECTION
|
||||
|
||||
void GVStop(void) {
|
||||
GV.sse_ready = false;
|
||||
GV.ticker.detach();
|
||||
|
@ -100,6 +120,9 @@ void GVBegin(void) {
|
|||
GV.WebServer->on("/", GVHandleRoot);
|
||||
GV.WebServer->on("/release", GVHandleRelease);
|
||||
GV.WebServer->on("/free_psram", GVHandleFreePSRam);
|
||||
GV.WebServer->on("/sampling", GVHandleSampling);
|
||||
GV.WebServer->on("/espinfo", GVHandleEspInfo);
|
||||
GV.WebServer->on("/partition", GVHandlePartition);
|
||||
GV.WebServer->on("/events", GVHandleEvents);
|
||||
GV.WebServer->begin();
|
||||
|
||||
|
@ -112,24 +135,21 @@ void GVHandleRoot(void) {
|
|||
char* content = ext_snprintf_malloc_P(HTTP_GV_PAGE,
|
||||
SettingsTextEscaped(SET_DEVICENAME).c_str(),
|
||||
GV_BASE_URL,
|
||||
GV_PORT,
|
||||
WiFi.localIP().toString().c_str(),
|
||||
WiFi.localIP().toString().c_str(), GV_PORT,
|
||||
GV.sampling,
|
||||
#ifdef ESP32
|
||||
ESP.getPsramSize() / 1024,
|
||||
#else
|
||||
0,
|
||||
#endif // ESP32
|
||||
GV_PORT,
|
||||
ESP_getFreeSketchSpace() / 1024);
|
||||
if (content == nullptr) { return; } // Avoid crash
|
||||
GV.WebServer->send_P(200, "text/html", content);
|
||||
free(content);
|
||||
}
|
||||
|
||||
void GVWebserverSendJson(String &jsonResponse) {
|
||||
GV.WebServer->send(200, "application/json", jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandleRelease(void) {
|
||||
String jsonResponse = "{\"release\":\"" + String(GVRelease) + "\"}";
|
||||
GV.WebServer->send(200, "application/json", jsonResponse);
|
||||
GVWebserverSendJson(jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandleFreePSRam(void) {
|
||||
|
@ -140,7 +160,85 @@ void GVHandleFreePSRam(void) {
|
|||
} else
|
||||
#endif
|
||||
jsonResponse += "No PSRAM\"}";
|
||||
GV.WebServer->send(200, "application/json", jsonResponse);
|
||||
GVWebserverSendJson(jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandleSampling(void) {
|
||||
String jsonResponse = "{\"sampling\": \"" + String(GV.sampling) + "\"}";
|
||||
GVWebserverSendJson(jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandleEspInfo(void) {
|
||||
#ifdef GV_USE_ESPINFO
|
||||
const FlashMode_t flashMode = ESP.getFlashChipMode(); // enum
|
||||
|
||||
String jsonResponse = "{\"chip_model\":\"" + GetDeviceHardware();
|
||||
jsonResponse += "\",\"cores_count\":\"" + String(ESP_getChipCores());
|
||||
jsonResponse += "\",\"chip_revision\":\"" + String(ESP_getChipRevision());
|
||||
jsonResponse += "\",\"cpu_frequency\":\"" + String(ESP.getCpuFreqMHz());
|
||||
jsonResponse += "\",\"cycle_count\":" + String(ESP.getCycleCount());
|
||||
jsonResponse += ",\"mac\":\"" + ESP_getEfuseMac();
|
||||
jsonResponse += "\",\"flash_mode\":" + String(flashMode);
|
||||
#ifdef ESP8266
|
||||
jsonResponse += ",\"flash_chip_size\":" + String(ESP.getFlashChipRealSize());
|
||||
#else
|
||||
jsonResponse += ",\"flash_chip_size\":" + String(ESP.getFlashChipSize());
|
||||
#endif
|
||||
jsonResponse += ",\"flash_chip_speed\":" + String(ESP.getFlashChipSpeed());
|
||||
jsonResponse += ",\"heap_size\":" + String(ESP_getHeapSize());
|
||||
jsonResponse += ",\"heap_max_alloc\":" + String(ESP_getMaxAllocHeap());
|
||||
jsonResponse += ",\"psram_size\":" + String(ESP_getPsramSize());
|
||||
jsonResponse += ",\"free_psram\":" + String(ESP_getFreePsram());
|
||||
jsonResponse += ",\"psram_max_alloc\":" + String(ESP_getMaxAllocPsram());
|
||||
jsonResponse += ",\"free_heap\":" + String(ESP_getFreeHeap());
|
||||
jsonResponse += ",\"up_time\":\"" + String(millis());
|
||||
jsonResponse += "\",\"sketch_size\":" + String(ESP_getSketchSize());
|
||||
jsonResponse += ",\"free_sketch\":" + String(ESP_getFreeSketchSpace());
|
||||
jsonResponse += "}";
|
||||
#else
|
||||
String jsonResponse = "{\"chip_model\":\"" + GetDeviceHardware() + "\"}";
|
||||
#endif // GV_USE_ESPINFO
|
||||
GVWebserverSendJson(jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandlePartition(void) {
|
||||
String jsonResponse = "["; // Start of JSON array
|
||||
#ifdef ESP32
|
||||
bool firstEntry = true; // Used to format the JSON array correctly
|
||||
|
||||
esp_partition_iterator_t iter = esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
// esp_partition_iterator_t iter = esp_partition_find(ESP_PARTITION_TYPE_ANY, ESP_PARTITION_SUBTYPE_ANY, NULL);
|
||||
|
||||
// Loop through partitions
|
||||
while (iter != NULL) {
|
||||
const esp_partition_t *partition = esp_partition_get(iter);
|
||||
|
||||
// Add comma before the next entry if it's not the first
|
||||
if (!firstEntry)
|
||||
{
|
||||
jsonResponse += ",";
|
||||
}
|
||||
firstEntry = false;
|
||||
|
||||
// Append partition information in JSON format
|
||||
jsonResponse += "{";
|
||||
jsonResponse += "\"label\":\"" + String(partition->label) + "\",";
|
||||
jsonResponse += "\"type\":" + String(partition->type) + ",";
|
||||
jsonResponse += "\"subtype\":" + String(partition->subtype) + ",";
|
||||
jsonResponse += "\"address\":\"0x" + String(partition->address, HEX) + "\",";
|
||||
jsonResponse += "\"size\":" + String(partition->size);
|
||||
jsonResponse += "}";
|
||||
|
||||
// Move to next partition
|
||||
iter = esp_partition_next(iter);
|
||||
}
|
||||
|
||||
// Clean up the iterator
|
||||
esp_partition_iterator_release(iter);
|
||||
#endif // ESP32
|
||||
|
||||
jsonResponse += "]"; // End of JSON array
|
||||
GVWebserverSendJson(jsonResponse);
|
||||
}
|
||||
|
||||
void GVHandleEvents(void) {
|
||||
|
@ -240,7 +338,6 @@ void GVMonitorTask(void) {
|
|||
|
||||
else {
|
||||
// Read digital GPIO
|
||||
pintype = GV_DigitalPin;
|
||||
int value = digitalRead(pin);
|
||||
originalValue = value;
|
||||
if (value == 1) {
|
||||
|
@ -248,6 +345,12 @@ void GVMonitorTask(void) {
|
|||
// } else {
|
||||
// currentState = 0;
|
||||
}
|
||||
#ifdef GV_INPUT_DETECTION
|
||||
int pin_mode = GetPinMode(pin);
|
||||
pintype = (INPUT == pin_mode) ? GV_InputPin : (INPUT_PULLUP == pin_mode) ? GV_InputPullUp : GV_DigitalPin;
|
||||
#else
|
||||
pintype = GV_DigitalPin;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (originalValue != GV.lastPinStates[pin]) {
|
||||
|
|
Loading…
Reference in New Issue