mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-09-12 17:45:49 +00:00
Fixes: #4902 Also fixes issues with PulseCount when using formula as this needs to continue on the restored values from RTC at boot.
216 lines
6.5 KiB
Arduino
216 lines
6.5 KiB
Arduino
#include "_Plugin_Helper.h"
|
|
|
|
#ifdef USES_P059
|
|
|
|
// #######################################################################################################
|
|
// #################################### Plugin 059: Rotary Encoder #######################################
|
|
// #######################################################################################################
|
|
|
|
// ESPEasy Plugin to process the quadrature encoder interface signals (e.g. rotary encoder)
|
|
// written by Jochen Krapf (jk@nerd2nerd.org)
|
|
|
|
// Connection:
|
|
// Use 1st and 2nd GPIO for encoders A and B signal.
|
|
// Optional use 3rd GPIO for encoders I signal to reset counter to 0 at first trigger.
|
|
// If counter runs in wrong direction, change A and B GPIOs in settings page
|
|
|
|
// Note: Up to 4 encoders can be used simultaneously
|
|
|
|
|
|
# define PLUGIN_059
|
|
# define PLUGIN_ID_059 59
|
|
# define PLUGIN_NAME_059 "Switch Input - Rotary Encoder"
|
|
# define PLUGIN_VALUENAME1_059 "Counter"
|
|
|
|
# include <QEIx4.h>
|
|
|
|
std::map<unsigned int, std::shared_ptr<QEIx4> > P_059_sensordefs;
|
|
|
|
boolean Plugin_059(uint8_t function, struct EventStruct *event, String& string)
|
|
{
|
|
boolean success = false;
|
|
|
|
switch (function)
|
|
{
|
|
case PLUGIN_DEVICE_ADD:
|
|
{
|
|
Device[++deviceCount].Number = PLUGIN_ID_059;
|
|
Device[deviceCount].Type = DEVICE_TYPE_TRIPLE;
|
|
Device[deviceCount].Ports = 0;
|
|
Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_SWITCH;
|
|
Device[deviceCount].PullUpOption = false;
|
|
Device[deviceCount].InverseLogicOption = false;
|
|
Device[deviceCount].FormulaOption = false;
|
|
Device[deviceCount].ValueCount = 1;
|
|
Device[deviceCount].SendDataOption = true;
|
|
Device[deviceCount].TimerOption = true;
|
|
Device[deviceCount].TimerOptional = true;
|
|
Device[deviceCount].GlobalSyncOption = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICENAME:
|
|
{
|
|
string = F(PLUGIN_NAME_059);
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICEVALUENAMES:
|
|
{
|
|
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_059));
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_GET_DEVICEGPIONAMES:
|
|
{
|
|
event->String1 = formatGpioName_input(F("A (CLK)"));
|
|
event->String2 = formatGpioName_input(F("B (DT)"));
|
|
event->String3 = formatGpioName_input_optional(F("I (Z)"));
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_LOAD:
|
|
{
|
|
// default values
|
|
if ((PCONFIG_LONG(0) == 0) && (PCONFIG_LONG(1) == 0)) {
|
|
PCONFIG_LONG(1) = 100;
|
|
}
|
|
|
|
{
|
|
const __FlashStringHelper *options[3] = { F("1"), F("2"), F("4") };
|
|
int optionValues[3] = { 1, 2, 4 };
|
|
addFormSelector(F("Mode"), F("mode"), 3, options, optionValues, PCONFIG(0));
|
|
addUnit(F("pulses per cycle"));
|
|
}
|
|
|
|
addFormNumericBox(F("Limit min."), F("limitmin"), PCONFIG_LONG(0));
|
|
addFormNumericBox(F("Limit max."), F("limitmax"), PCONFIG_LONG(1));
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WEBFORM_SAVE:
|
|
{
|
|
PCONFIG(0) = getFormItemInt(F("mode"));
|
|
|
|
PCONFIG_LONG(0) = getFormItemInt(F("limitmin"));
|
|
PCONFIG_LONG(1) = getFormItemInt(F("limitmax"));
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_INIT:
|
|
{
|
|
portStatusStruct newStatus;
|
|
|
|
// create sensor instance and add to std::map
|
|
P_059_sensordefs.erase(event->TaskIndex);
|
|
P_059_sensordefs[event->TaskIndex] = std::shared_ptr<QEIx4>(new QEIx4);
|
|
|
|
P_059_sensordefs[event->TaskIndex]->begin(CONFIG_PIN1, CONFIG_PIN2, CONFIG_PIN3, PCONFIG(0));
|
|
P_059_sensordefs[event->TaskIndex]->setLimit(PCONFIG_LONG(0), PCONFIG_LONG(1));
|
|
P_059_sensordefs[event->TaskIndex]->setIndexTrigger(true);
|
|
|
|
ExtraTaskSettings.TaskDeviceValueDecimals[event->BaseVarIndex] = 0;
|
|
|
|
String log = F("QEI : GPIO: ");
|
|
|
|
for (uint8_t i = 0; i < 3; i++)
|
|
{
|
|
int pin = PIN(i);
|
|
|
|
if (pin >= 0)
|
|
{
|
|
// pinMode(pin, (Settings.TaskDevicePin1PullUp[event->TaskIndex]) ? INPUT_PULLUP : INPUT);
|
|
constexpr pluginID_t P059_PLUGIN_ID{PLUGIN_ID_059};
|
|
|
|
const uint32_t key = createKey(P059_PLUGIN_ID, pin);
|
|
|
|
// WARNING: operator [] creates an entry in the map if key does not exist
|
|
newStatus = globalMapPortStatus[key];
|
|
newStatus.task++; // add this GPIO/port as a task
|
|
newStatus.mode = PIN_MODE_INPUT;
|
|
newStatus.state = 0;
|
|
savePortStatus(key, newStatus);
|
|
|
|
// setPinState(PLUGIN_ID_059, pin, PIN_MODE_INPUT, 0);
|
|
}
|
|
log += pin;
|
|
log += ' ';
|
|
}
|
|
addLogMove(LOG_LEVEL_INFO, log);
|
|
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_EXIT:
|
|
{
|
|
P_059_sensordefs.erase(event->TaskIndex);
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_TEN_PER_SECOND:
|
|
{
|
|
if (P_059_sensordefs.count(event->TaskIndex) != 0)
|
|
{
|
|
if (P_059_sensordefs[event->TaskIndex]->hasChanged())
|
|
{
|
|
long c = P_059_sensordefs[event->TaskIndex]->read();
|
|
UserVar.setFloat(event->TaskIndex, 0, c);
|
|
event->sensorType = Sensor_VType::SENSOR_TYPE_SWITCH;
|
|
|
|
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
|
String log = F("QEI : ");
|
|
log += c;
|
|
addLogMove(LOG_LEVEL_INFO, log);
|
|
}
|
|
|
|
sendData(event);
|
|
}
|
|
}
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_READ:
|
|
{
|
|
if (P_059_sensordefs.count(event->TaskIndex) != 0)
|
|
{
|
|
UserVar.setFloat(event->TaskIndex, 0, P_059_sensordefs[event->TaskIndex]->read());
|
|
}
|
|
success = true;
|
|
break;
|
|
}
|
|
|
|
case PLUGIN_WRITE:
|
|
{
|
|
if (P_059_sensordefs.count(event->TaskIndex) != 0)
|
|
{
|
|
String command = parseString(string, 1);
|
|
|
|
if (equals(command, F("encwrite")))
|
|
{
|
|
if (event->Par1 >= 0)
|
|
{
|
|
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
|
|
String log = F("QEI : ");
|
|
log += string;
|
|
addLogMove(LOG_LEVEL_INFO, log);
|
|
}
|
|
P_059_sensordefs[event->TaskIndex]->write(event->Par1);
|
|
Scheduler.schedule_task_device_timer(event->TaskIndex, millis());
|
|
}
|
|
success = true; // Command is handled.
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
#endif // USES_P059
|