Complex MBUS mapping, PID fix

This commit is contained in:
2022-12-04 03:19:07 +03:00
parent 2da04b45bf
commit a974290389
6 changed files with 99 additions and 33 deletions

View File

@@ -1451,6 +1451,8 @@ int Item::SendStatus(int sendFlags) {
case CMD_COOL:
case CMD_DRY:
case CMD_FAN:
case CMD_ENABLE:
case CMD_DISABLE:
strcpy_P(cmdstr, ON_P);
break;
case CMD_OFF:
@@ -1571,6 +1573,12 @@ int Item::SendStatus(int sendFlags) {
case CMD_FAN:
strcpy_P(cmdstr, FAN_ONLY_P);
break;
case CMD_ENABLE:
strcpy_P(cmdstr, ENABLE_P);
break;
case CMD_DISABLE:
strcpy_P(cmdstr, DISABLE_P);
break;
case CMD_ON:
case CMD_XON:
if (itemType == CH_THERMO) strcpy_P(cmdstr, AUTO_P);

View File

@@ -1242,10 +1242,10 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
case aJson_Array:
{
aJsonObject *i = cmdMapping->child;
//if first array element is not array - this is default mapping value
//if first array element is not array - this is default mapping value, no reverse mapping, skipping
if (i && i->type==aJson_Int)
{
matchedCmd = i;
//matchedCmd = i;
i=i->next;
}
@@ -1301,6 +1301,7 @@ if (valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMappi
int diff = ((b-a)/(d-c))/2;
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
}
if (valMapping && valMapping->type == aJson_NULL) return itemCmd();
return *this;
}

View File

@@ -231,10 +231,15 @@ return (result == node.ku8MBSuccess);
int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution, bool * submitParam)
{
aJsonObject * paramObj = store->parameters->child;
bool is8bit = false;
bool tmpSubmitParam;
if (!submitParam) submitParam=&tmpSubmitParam;
*submitParam=true;
//bool is8bit = false;
while (paramObj)
{
aJsonObject *regObj=NULL;
@@ -248,11 +253,14 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
{
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
aJsonObject *idObj = aJson.getObjectItem(paramObj, "id");
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
uint16_t data = node.getResponseBuffer(posInBuffer);
int8_t regType = PAR_I16;
uint32_t param =0;
itemCmd mappedParam;
bool executeWithoutCheck=false; //Afler recurrent check, all dublicatess and suppressing checked by recurrent
bool submitRecurrentOut = false; //false if recurrent check find duplicates
char buf[16];
//bool isSigned=false;
@@ -308,15 +316,47 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
{
mappedParam=mappedParam.doReverseMapping(mapObj);
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
}
if (!mappedParam.isCommand() && !mappedParam.isValue()) //Not mapped
{
aJsonObject *nextRegObj = NULL;
int registerType = 0;
nextRegObj = aJson.getObjectItem(paramObj, "nextreg");
if (nextRegObj) registerType=MODBUS_HOLDING_REG_TYPE;
else
{
nextRegObj = aJson.getObjectItem(paramObj, "nextir");
if (nextRegObj) registerType=MODBUS_INPUT_REG_TYPE;
}
if (registerType && (nextRegObj->type) ==aJson_Int && (nextRegObj->valueint>= registerFrom) && (nextRegObj->valueint<=registerTo))
{
debugSerial<<F("Recurrent searching nextreg")<<endl;
mappedParam = findRegister(nextRegObj->valueint,nextRegObj->valueint-registerFrom,registerType,registerFrom,registerTo,false,&submitRecurrentOut);
executeWithoutCheck=true;
}
else errorSerial<<F("nextreg out of range")<<endl;
}
else
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
} //mapping
if (doExecution && idObj && idObj->type==aJson_Int)
switch (idObj->valueint)
{
case S_CMD:
mappedParam.saveItem(item,SEND_COMMAND);
break;
case S_SET:
mappedParam.saveItem(item,SEND_PARAMETERS);
}
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
{
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name);
if (execObj)
{
bool submitParam=true;
//Retrive previous data
aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S");
if (lastMeasured)
@@ -324,7 +364,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
if (lastMeasured->type == aJson_Int)
{
if (lastMeasured->valueint == param)
submitParam=false; //supress repeating execution for same val
*submitParam=false; //supress repeating execution for same val
else lastMeasured->valueint=param;
}
}
@@ -332,32 +372,40 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
{
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
aJson.addNumberToObject(execObj, "@S", (long) param);
}
if (submitParam)
{
//#ifdef MB_SUPPRESS_OUT_EQ_IN
}
if (executeWithoutCheck)
{
if (doExecution && (submitRecurrentOut || *submitParam)) executeCommand(execObj, -1, mappedParam);
return mappedParam;
}
if (*submitParam)
{
// Compare with last submitted val (if @V NOT marked as NULL in config)
aJsonObject *settedValue = aJson.getObjectItem(execObj,"@V");
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
{
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
*submitParam=false;
}
else
{
executeCommand(execObj, -1, mappedParam);
if (doExecution) executeCommand(execObj, -1, mappedParam);
// if param updated by device and no new value queued to send - update @V to avoid "Ignored - equal with setted val"
if (settedValue && !(execObj->subtype & MB_NEED_SEND))
settedValue->valueint=param;
}
//#endif
}
}
}
if (!is8bit) return 1;
return mappedParam;
}
paramObj=paramObj->next;
}
return is8bit;
return itemCmd();
}
@@ -376,7 +424,7 @@ return is8bit;
//if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
if (readModbus(registerNum,regType,1))
{
findRegister(registerNum,0,regType);
findRegister(registerNum,0,regType,registerNum,registerNum);
// data = node.getResponseBuffer(j);
}
}
@@ -392,7 +440,7 @@ return is8bit;
{ debugSerial<<endl;
for(int i=registerFrom;i<=registerTo;i++)
{
findRegister(i,i-registerFrom,regType);
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
}
//data = node.getResponseBuffer(j);
}

View File

@@ -43,7 +43,7 @@ public:
protected:
mbPersistent * store;
bool getConfig();
int findRegister(int registerNum, int posInBuffer, int regType);
itemCmd findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution = true, bool * submitParam = NULL);
void pollModbus(aJsonObject * reg, int regType);
void initLine();
int sendModbus(char * paramName, int32_t value, uint8_t regType);

View File

@@ -172,15 +172,20 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
{
if(store->pid->Compute() )
{
int alarmVal;
if (store->alarmArmed && (alarmVal=getAlarmVal()>=0)) store->output=alarmVal;
float alarmVal;
if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal;
debugSerial<<F("PID ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
if (store->alarmArmed) debugSerial << F(" Alarm");
debugSerial<<endl;
if ((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) && !store->alarmArmed)
if (((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) || (item->getCmd() == CMD_ENABLE)) && !store->alarmArmed)
{
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
if (item->getCmd() == CMD_ENABLE)
{
executeCommand(oCmd,-1,itemCmd().Cmd(CMD_ON));
item->setCmd(CMD_VOID);
}
itemCmd value((float) (store->output));// * (100./255.)));
value.setSuffix(S_SET);
executeCommand(oCmd,-1,value);
@@ -198,16 +203,16 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
return 1;//store->pollingInterval;
};
int out_pid::getAlarmVal()
float out_pid::getAlarmVal()
{
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
if (!kPIDObj || kPIDObj->type != aJson_Array)
{
errorSerial<<F("Invalid PID param array.")<<endl;
return -1;
return -1.;
}
int outAlarm=0;
float outAlarm=0.;
double kP=0.;
bool alarmValDefined = false;
@@ -232,13 +237,14 @@ int out_pid::getAlarmVal()
if (param->type == aJson_Float) kP=param->valuefloat;
else if (param->type == aJson_Int) kP=param->valueint;
{
if (kP<0)
if (kP<0.)
{
if (!alarmValDefined) outAlarm = 0.;
}
else if (!alarmValDefined) outAlarm = 255.;
}
}
debugSerial<<F("Alarm value: ")<<outAlarm<< " ";
return outAlarm;
}
@@ -250,7 +256,7 @@ if (!item || !item->itemArg) return;
{
float outAlarm=getAlarmVal();
errorSerial<<item->itemArr->name<<F(" PID alarm. ")<<endl;
if (outAlarm>=0)
if (outAlarm>=0.)
{
errorSerial<<F("Set out to ")<<outAlarm<<endl;
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
@@ -337,18 +343,19 @@ case S_CMD:
case CMD_FAN:
case CMD_DRY:
executeCommand(oCmd,-1,value);
executeCommand(oCmd,-1,value);
return 1;
case CMD_ENABLE:
item->setCmd(CMD_ENABLE);
item->SendStatus(SEND_COMMAND);
//executeCommand(oCmd,-1,value);
item->SendStatus(SEND_COMMAND);
executeCommand(oCmd,-1,value);
return 1;
case CMD_DISABLE:
item->setCmd(CMD_DISABLE);
item->SendStatus(SEND_COMMAND);
//executeCommand(oCmd,-1,value);
executeCommand(oCmd,-1,value);
return 1;
/*
case CMD_OFF:
@@ -361,11 +368,11 @@ case S_CMD:
} */
default:
debugSerial<<F("Unknown cmd ")<<cmd.getCmd()<<endl;
debugSerial<<F("PID: Unknown cmd ")<<cmd.getCmd()<<endl;
} //switch cmd
}
default:
debugSerial<<F("Unknown suffix ")<<suffixCode<<endl;
debugSerial<<F("PID: Unknown suffix ")<<suffixCode<<endl;
} //switch suffix
return 0;

View File

@@ -112,6 +112,8 @@ const char HIGH_P[] PROGMEM = "HIGH";
const char MED_P[] PROGMEM = "MEDIUM";
const char LOW_P[] PROGMEM = "LOW";
const char ERROR_P[] PROGMEM = "ERR";
const char ENABLE_P[] PROGMEM = "ENABLE";
const char DISABLE_P[] PROGMEM = "DISABLE";
// SubTopics