Driver refactoring & core fixes

CAN fixes and extension
stm32 timer
This commit is contained in:
2025-04-26 16:29:09 +03:00
parent c9714ef982
commit 5aec014767
28 changed files with 326 additions and 69 deletions

View File

@@ -12,6 +12,8 @@
-DENABLE_HWSERIAL1
-DdebugSerialPort=Serial1
-D TIMER_INT
#-DFLASH_BASE_ADDRESS
#-DFLASH_DATA_SECTOR

View File

@@ -17,7 +17,7 @@
-D THERMOSTAT_CHECK_PERIOD=5000
-D ULTRASONIC
-D TIMER_INT
-DENABLE_HWSERIAL1
-DdebugSerialPort=Serial1

View File

@@ -19,8 +19,8 @@ public:
protected:
virtual int publishTopic(const char* topic, long value, const char* subtopic = NULL);
virtual int publishTopic(const char* topic, float value, const char* subtopic = NULL );
virtual int publishTopic(const char* topic, const char * value, const char* subtopic = NULL);
//friend Input;
int publishTopic(const char* topic, long value, const char* subtopic = NULL);
int publishTopic(const char* topic, float value, const char* subtopic = NULL );
int publishTopic(const char* topic, const char * value, const char* subtopic = NULL);
};

View File

@@ -1,5 +1,3 @@
#include "item.h"
#include "abstractout.h"
#include "itemCmd.h"

View File

@@ -7,7 +7,9 @@ class Item;
class chPersistent {};
class abstractOut : public abstractCh{
public:
abstractOut(Item * _item):abstractCh(){item=_item;};
//abstractOut(Item * _item):abstractCh(){item=_item;};
abstractOut():item(NULL){};
virtual void link(Item * _item){item=_item;};
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) =0;
virtual int isActive();
virtual bool isAllowed(itemCmd cmd){return true;};
@@ -17,8 +19,10 @@ public:
virtual int Status() override;
virtual void setStatus(uint8_t status) override;
int Setup() override;
Item * getItem() {return item;}
protected:
int pubAction(bool state);
Item * item;
};

View File

@@ -522,16 +522,14 @@ else //Requests
if ((id.payloadType == payloadType::itemCommand) && (len ==8))
{
Item it(id.itemId,id.subItemId);
if (it.isValid())
{
itemCmd ic;
ic.cmd = packet->cmd;
ic.param = packet->param;
//debugSerial<<F("CAN: itemCmd: ");
if (!it.isValid()) return false;
itemCmd ic;
ic.cmd = packet->cmd;
ic.param = packet->param;
//debugSerial<<F("CAN: itemCmd: ");
//ic.debugOut();
return it.Ctrl(ic,it.getSubItemStrById(id.subItemId));
}
return false;
return it.Ctrl(ic,it.getSubItemStrById(id.subItemId));
}
else if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
{
@@ -749,7 +747,17 @@ bool canDriver::sendCommand(aJsonObject * can, itemCmd cmd, bool status)
int suffix=txt2subItem(sfx->valuestring);
if (suffix) cmd.setSuffix(suffix);
}
if (subItemObj && subItemObj->type==aJson_Int && subItemObj->valueint>=0 && subItemObj->valueint<63) subItem=subItemObj->valueint;
if (subItemObj)
switch (subItemObj->type)
{
case aJson_Int:
if (subItemObj->valueint>=0 && subItemObj->valueint<SUBITEM_IS_COMMAND) subItem=subItemObj->valueint;
break;
case aJson_String:
int suffix=txt2cmd(subItemObj->valuestring);
if (suffix) subItem = suffix | SUBITEM_IS_COMMAND;
}
if (dev && it && dev->type == aJson_Int && it->type == aJson_Int)
return sendCommand(dev->valueint, it->valueint, cmd, status,subItem);

View File

@@ -1,5 +1,6 @@
#pragma once
#define NO_SUBITEM 63
#define SUBITEM_IS_COMMAND 0x20
#ifdef CANDRV
#if defined(ARDUINO_ARCH_STM32)

View File

@@ -9,11 +9,13 @@
class colorChannel : public abstractOut {
public:
colorChannel(Item * _item):abstractOut(_item) {
colorChannel():iaddr(0),numArgs(0) {};
void link (Item * _item) {
abstractOut::link(_item);
iaddr = item->getArg(); //Once retrieve and store base address
if (iaddr<0) iaddr=-iaddr;
numArgs = item->getArgCount(); // and how many addresses is configured
};
};
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized=false) override;
//int getDefaultStorageType()override;
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) =0;

View File

@@ -83,6 +83,7 @@ extern PubSubClient mqttClient;
extern int8_t ethernetIdleCount;
extern int8_t configLocked;
extern lan_status lanStatus;
driverFactory df;
int retrieveCode(char **psubItem);
@@ -172,7 +173,8 @@ void Item::Parse() {
if (cmdObj) itemExt = cmdObj->next;
itemType = replaceTypeToInt (itemTypeObj);
driver=df.getDriver(this);
/*
switch (itemType)
{
#ifndef PWM_DISABLE
@@ -265,14 +267,13 @@ void Item::Parse() {
break;
#endif
default: ;
}
} */
// debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl;
}
}
boolean Item::Setup()
{
if (driver)
{
if (driver->Status()) driver->Stop();
@@ -287,7 +288,7 @@ else return false;
}
void Item::Stop()
{
{
if (driver)
{
driver->Stop();
@@ -299,7 +300,7 @@ Item::~Item()
{
if (driver)
{
delete driver;
df.freeDriver (this);
}
}
@@ -356,7 +357,7 @@ uint16_t getCanNum(aJsonObject* verb)
char * Item::getSubItemStrById(uint8_t subItem)
{
if (subItem == NO_SUBITEM) return NULL;
if (subItem == NO_SUBITEM || (subItem | SUBITEM_IS_COMMAND)) return NULL;
if (!itemArg) return NULL;
aJsonObject * i = itemArg;
if (i->type == aJson_Array) i=i->child;
@@ -421,8 +422,16 @@ return NO_SUBITEM;
{
debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl;
Parse();
char * subItemStr = getSubItemStrById(subItem);
if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem));
if (subItem | SUBITEM_IS_COMMAND)
{
subItem &=~ SUBITEM_IS_COMMAND;
if (subItem<commandsNum) strncpy_P(defaultSubItem, commands_P[subItem], sizeof(defaultSubItem));
}
else
{
char * subItemStr = getSubItemStrById(subItem);
if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem));
}
return;
}
itemArr = itemArr->next;
@@ -899,8 +908,8 @@ bool Item::digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool aut
configLocked--;
return true; //Not execution, just activity check. If any channel is active - return true
}
}
}
}
break;
case aJson_Object:
case aJson_Array:
@@ -1091,6 +1100,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
long status2Send = 0;
uint8_t command2Set = 0;
itemCmd originalCmd = cmd;
int subitemCmd = subitem2cmd(subItem);
/// Common (GRP & NO GRP) commands
switch (cmd.getCmd())
@@ -1228,6 +1238,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
cmd.setSuffix(S_SET);
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
break;
case S_TEMP:
if (cmd.incrementTemp(step))
{
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
cmd.setSuffix(S_SET);
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
} //switch suffix
} //Case UP/DOWN
@@ -1273,18 +1290,19 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
if ((suffixCode!=S_CMD) || (cmd.getCmd() != CMD_XON) || !getFlag(FLAG_DISABLED))
{
digGroup(itemArg,&cmd,subItem,authorized);
if ((suffixCode==S_CMD) && cmd.isValue())
{
scheduleOppositeCommand(originalCmd,chActive,authorized);
scheduledOppositeCommand = true;
}
if (subItem) status2Send |= FLAG_SEND_IMMEDIATE;
if (subItem && !subitemCmd) status2Send |= FLAG_SEND_IMMEDIATE;
}
}
}
res=1;
if (subitemCmd) subItem = NULL;
// Post-processing of group command - converting HALT,REST,XON,XOFF to conventional ON/OFF for status
switch (cmd.getCmd()) {
@@ -1383,7 +1401,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
if (subItem)
{
//Check if subitem is some sort of command
int subitemCmd = subitem2cmd(subItem);
short prevCmd = getCmd();
if (!prevCmd && chActive) prevCmd=CMD_ON;
@@ -1657,6 +1675,8 @@ if ((!driver || driver->isAllowed(cmd))
case CMD_HALT:
case CMD_XOFF:
digitalWrite(iaddr, k = (inverse) ? HIGH : LOW);
default:
k = -1;
}
/*
if (inverse)
@@ -1780,7 +1800,6 @@ int Item::isActive() {
return -1;
}
int cmd = getCmd();
if (driver) {
short active = driver->isActive();
if (active >= 0)
@@ -1905,7 +1924,6 @@ switch (cause)
sendDelayedStatus();
}
}
if (driver && driver->Status())
{
return driver->Poll(cause);
@@ -2186,7 +2204,7 @@ int Item::SendStatus(long sendFlags, char * subItem) {
}
int Item::getChanType()
{
{
if (driver) return driver->getChanType();
return itemType;
}
@@ -2218,7 +2236,6 @@ int Item::checkRetry() {
{ // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
if (driver)
{
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
@@ -2721,5 +2738,158 @@ int Item::checkModbusDimmer(int data) {
} //if data changed
return 1;
}
#endif
Item * driverFactory::getItem(Item * item)
{
abstractOut * driver = findDriver(item);
if (driver) return driver->getItem();
return NULL;
}
abstractOut * driverFactory::findDriver(Item * item)
{
if (!item || !item->isValid()) return NULL;
uint8_t itemType = item->itemType;
if (itemType>CH_MAX) return NULL;
switch (itemType)
{
case CH_RGBW:
case CH_RGB:
case CH_RGBWW:
itemType = CH_DIMMER;
}
return drivers[itemType];
}
void driverFactory::freeDriver(Item * item)
{
if (item && item->driver)
{
abstractOut * driver = findDriver(item);
if (driver)
{
if (driver->getItem() == item)
item->driver->link(NULL);
else delete item->driver;
}
}
}
abstractOut * driverFactory::getDriver(Item * item)
{
if (!item || !item->isValid()) return NULL;
abstractOut * driver = findDriver(item);
if (driver)
{
if (driver->getItem()) driver = newDriver(item->itemType);
}
else
{
driver = newDriver(item->itemType);
if (driver) drivers[item->itemType]=driver;
}
if (driver) driver->link(item);
return driver;
}
abstractOut * driverFactory::newDriver(uint8_t itemType)
{
abstractOut * driver = NULL;
switch (itemType)
{
#ifndef PWM_DISABLE
case CH_PWM:
driver = new out_pwm ;
break;
#endif
#ifndef DMX_DISABLE
case CH_DIMMER:
driver = new out_dmx ;
break;
#endif
#ifndef SPILED_DISABLE
case CH_SPILED:
driver = new out_SPILed ;
break;
#endif
#ifndef AC_DISABLE
case CH_AC:
driver = new out_AC ;
break;
#endif
#ifndef MOTOR_DISABLE
case CH_MOTOR:
driver = new out_Motor ;
break;
#endif
#ifndef MBUS_DISABLE
case CH_MBUS:
driver = new out_Modbus ;
break;
#endif
#ifndef PID_DISABLE
case CH_PID:
driver = new out_pid ;
break;
#endif
#ifndef RELAY_DISABLE
case CH_RELAYX:
driver = new out_relay ;
break;
#endif
#ifndef MULTIVENT_DISABLE
case CH_MULTIVENT:
driver = new out_Multivent ;
break;
#endif
#ifdef UARTBRIDGE_ENABLE
case CH_UARTBRIDGE:
driver = new out_UARTbridge ;
// debugSerial<<F("AC driver created")<<endl;
break;
#endif
#ifdef ELEVATOR_ENABLE
case CH_ELEVATOR:
driver = new out_elevator ;
// debugSerial<<F("AC driver created")<<endl;
break;
#endif
#ifdef HUMIDIFIER_ENABLE
case CH_HUMIDIFIER:
driver = new out_humidifier ;
break;
#endif
#ifdef MERCURY_ENABLE
case CH_MERCURY:
driver = new out_Mercury ;
break;
#endif
#ifndef COUNTER_DISABLE
case CH_COUNTER:
driver = new out_counter ;
// debugSerial<<F("AC driver created")<<endl;
break;
#endif
default: ;
}
return driver;
}

View File

@@ -1,4 +1,4 @@
/* Copyright © 2017-2020 Andrey Klimov. All rights reserved.
/* Copyright © 2017-2025 Andrey Klimov. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ e-mail anklimov@gmail.com
#include "abstractout.h"
#include "itemCmd.h"
#define S_NOTFOUND 0
#define S_CMD 1
#define S_SET 2
@@ -67,6 +68,7 @@ const suffixstr suffix_P[] PROGMEM =
#define CH_COUNTER 20
#define CH_HUMIDIFIER 21
#define CH_MERCURY 22
#define CH_MAX 22
#define POLLING_SLOW 1
#define POLLING_FAST 2
@@ -169,6 +171,18 @@ class Item
int defaultSuffixCode;
};
class driverFactory {
public:
driverFactory(){memset(drivers,0,sizeof(drivers));};
Item * getItem(Item * item);
abstractOut * getDriver(Item * item);
abstractOut * findDriver(Item * item);
void freeDriver(Item * item);
abstractOut * newDriver(uint8_t itemType);
private:
abstractOut * drivers[CH_MAX+1];
};
typedef union
{
struct

View File

@@ -429,6 +429,23 @@ bool itemCmd::incrementS(long int dif)
}
bool itemCmd::incrementTemp(long int dif)
{int par=param.colorTemp;
switch (cmd.itemArgType)
{
case ST_HSV255:
par+=dif/TENS_BASE;
if (par>100) par=100;
if (par<1) par=1;
break;
default: return false;
}
param.colorTemp=par;
return true;
}
itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
{
@@ -1514,7 +1531,7 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
if (!Buffer || !bufLen) return NULL;
*Buffer=0;
char * argPtr=Buffer;
if (isCommand() && (sendFlags & FLAG_COMMAND))
if (isCommand() && (sendFlags & FLAG_COMMAND) && cmd.cmdCode<commandsNum)
{
int len;
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);

View File

@@ -261,6 +261,7 @@ public:
bool incrementPercents(long int, long int limit);
bool incrementH(long int);
bool incrementS(long int);
bool incrementTemp(long int dif);
long int getInt();
long int getTens();

View File

@@ -23,7 +23,7 @@ e-mail anklimov@gmail.com
#include "flashstream.h"
#include "config.h"
#if defined(__SAM3X8E__)
#if defined(TIMER_INT)
#include "TimerInterrupt_Generic.h"
#endif
@@ -2185,6 +2185,25 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
}
#endif
#if defined(ARDUINO_ARCH_STM32) && defined (TIMER_INT)
STM32Timer ITimer0(TIM1);
int16_t attachTimer(double microseconds, timerCallback callback, const char* TimerName)
{
if (timerNumber!=-1) return timerNumber;
// Interval in microsecs
if (ITimer0.attachInterruptInterval(microseconds, callback))
{
debugSerial.print(F("Starting ITimer0 OK"));
timerNumber = 0;
}
else
debugSerial.println(F("Can't set ITimer0. Select another freq. or timer"));
return timerNumber;
}
#endif
#if defined(__SAM3X8E__) && defined (PULSEPIN12)
#define MATURA_PULSE 100
#define MATURA_PERIOD 2500
@@ -3117,7 +3136,11 @@ configLocked++;
// Interval in microsecs
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
attachMaturaTimer();
#endif
#if defined(ARDUINO_ARCH_STM32) && defined (TIMER_INT)
// Interval in microsecs
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
#endif
configLocked--;
}

View File

@@ -35,7 +35,8 @@ public:
class out_AC : public abstractOut {
public:
out_AC(Item * _item):abstractOut(_item){store = (acPersistent *) item->getPersistent(); getConfig();};
out_AC():store(NULL){};
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (acPersistent *) item->getPersistent(); getConfig();} else store = NULL;};
void getConfig();
int Setup() override;
int Poll(short cause) override;

View File

@@ -8,8 +8,6 @@
class out_counter : public abstractOut {
public:
out_counter(Item * _item):abstractOut(_item){};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -9,14 +9,10 @@
class out_dmx : public colorChannel {
public:
out_dmx(Item * _item):colorChannel(_item){};
int Setup() override;
int Stop() override;
int getChanType() override;
// int Ctrl(itemCmd cmd, char* subItem=NULL) override;
// int PixelCtrl(itemCmd cmd) override;
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false) override;
protected:

View File

@@ -42,13 +42,15 @@ public:
class out_Mercury : public abstractOut {
public:
out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
//out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
out_Mercury():store(NULL){};
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mercuryPersistent *) item->getPersistent();} else store = NULL;};
int Setup() override;
int Poll(short cause) override;
int Stop() override;
int getChanType() override;
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
//int getDefaultStorageType(){return ST_INT32;};
protected:

View File

@@ -451,7 +451,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
{
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
executeWithoutCheck=true;
debugSerial<<"MBUSD: recurrent check res: "<<"SRO:"<<submitRecurrentOut<<endl;
traceSerial<<"MBUSD: recurrent check res: "<<"SRO:"<<submitRecurrentOut<<endl;
}
else
{

View File

@@ -31,8 +31,10 @@ public:
class out_Modbus : public abstractOut {
public:
//out_Modbus(Item * _item):abstractOut(_item){store = (mbPersistent *) item->getPersistent();};
out_Modbus():store(NULL){};
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mbPersistent *) item->getPersistent(); } else store = NULL;};
out_Modbus(Item * _item):abstractOut(_item){store = (mbPersistent *) item->getPersistent();};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -20,7 +20,9 @@ static int8_t motorQuote = MOTOR_QUOTE;
class out_Motor : public abstractOut {
public:
out_Motor(Item * _item):abstractOut(_item){getConfig();};
//out_Motor(Item * _item):abstractOut(_item){getConfig();};
//out_Motor(){};
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -12,7 +12,9 @@
class out_Multivent : public abstractOut {
public:
out_Multivent(Item * _item):abstractOut(_item){getConfig();};
//out_Multivent(Item * _item):abstractOut(_item){getConfig();};
//out_Multivent(){};
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -25,7 +25,10 @@ public:
class out_pid : public abstractOut {
public:
out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();};
//out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();};
out_pid():store(NULL){};
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (pidPersistent *) item->getPersistent();} else store = NULL;};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -10,7 +10,7 @@
class out_pwm : public colorChannel {
public:
out_pwm(Item * _item):colorChannel(_item){numChannels=0;};
// out_pwm():numChannels(0){};
int Setup() override;
int Stop() override;
@@ -19,7 +19,7 @@ public:
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override;
protected:
short numChannels;
//protected:
// short numChannels;
};
#endif

View File

@@ -8,8 +8,7 @@
class out_relay : public abstractOut {
public:
out_relay(Item * _item):abstractOut(_item){ getConfig();};
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
void getConfig();
void relay(bool state);
int Setup() override;

View File

@@ -15,7 +15,9 @@
class out_SPILed : public colorChannel {
public:
out_SPILed(Item * _item):colorChannel(_item){getConfig();};
//out_SPILed(Item * _item):colorChannel(_item){getConfig();};
//out_SPILed(){};
void link(Item * _item){colorChannel::link(_item);if (_item) getConfig();};
int Setup() override;
int Stop() override;
int getChanType() override;

View File

@@ -58,7 +58,12 @@ public:
class out_UARTbridge : public abstractOut {
public:
out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();};
// out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();};
out_UARTbridge():store(NULL){};
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (ubPersistent *) item->getPersistent();} else store = NULL;};
int Setup() override;
int Poll(short cause) override;
int Stop() override;

View File

@@ -130,7 +130,7 @@ long getIntFromStr(char **chan) {
// chan is pointer to pointer to string
// Function return first retrived number and move pointer to position next after ','
itemCmd getNumber(char **chan) {
itemCmd val(ST_TENS,CMD_VOID);
itemCmd val(ST_VOID,CMD_VOID); //WAS ST_TENS ?
if (chan && *chan && **chan)
{
//Skip non-numeric values
@@ -161,7 +161,7 @@ itemCmd getNumber(char **chan) {
if (isDigit(*(fractptr+i))) fractnumbers += constrain(*(fractptr+i)-'0',0,9);
}
}
if (!fractlen && !intlen) return val; //VOID
if (!fractlen) val.Int(atol(*chan));
else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9)
{
@@ -670,11 +670,15 @@ aJsonObject *can = NULL;
aJsonObject *icmd = NULL;
aJsonObject *ecmd = NULL;
char cmdType = 0;
//char * out = aJson.print(cmd);
//debugSerial<<"Exec:"<<out<<endl;
//free (out);
if (serialDebugLevel>=LOG_TRACE || udpDebugLevel>=LOG_TRACE)
{
char* out = aJson.print(cmd);
if (out)
{
debugSerial<<"Exec:"<<out<<endl;
free (out);
}
}
if (cmd) cmdType = cmd->type;
switch (cmdType)

View File

@@ -1010,7 +1010,8 @@ lib_deps =
https://github.com/anklimov/ModbusMaster
pazi88/STM32_CAN
ericksimoes/Ultrasonic
https://github.com/mathertel/RotaryEncoderv
https://github.com/mathertel/RotaryEncoder
;TimerInterrupt_Generic
monitor_speed = 115200