Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: ICE-Application/src/ModbusMaster/ModbusMaster.cpp
- Revision:
- 2:02cb20446785
- Parent:
- 1:b2e90cda7a5a
--- a/ICE-Application/src/ModbusMaster/ModbusMaster.cpp Tue Jan 24 19:06:45 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,802 +0,0 @@ -/****************************************************************************** - * - * File: ModbusMaster.cpp - * Desciption: source for the ICE Modbus Master - * - *****************************************************************************/ -#include "global.h" -#include <stdio.h> -#include "BLEDataHandler.h" -#include "ModbusMaster.h" -#include "ModbusMasterApi.h" -#include "CloudDataHandler.h" -#include "LoggerApi.h" -#include "mod.h" -#include "cJSON.h" -#include "rtc.h" -#include "rtos.h" -#include "mbed.h" -#include "v7_execute.h" -#include "utilities.h" - -DigitalOut dout1(PB_0); -DigitalOut dout2(PB_1); -DigitalIn flow_switch(PC_12); -DigitalIn dinp2(PC_11); - -/***************************************************************************** - * Function: ModbusMaster - * Description: entry point for the Modbus Master - * - * @param (IN) args (user-defined arguments) - * @return none - *****************************************************************************/ -//std::map<std::string,VirtualCommand> VirtualCommandMap; - -std::map<std::string, VirtualCommand> VirtualCommandMap; -std::map<std::string, ExecuteJavaScript> ExecuteJavaScriptMap; -std::map<std::string, HoldingRegister> HoldingRegisterMap; - -void LoadModbusConfigFile( char *fileName ); -void UpdateSimulatedInput( std::map<std::string, ModbusRegister>::iterator &modMap ); -void UpdateVirtualRegister( std::map<std::string, ModbusRegister>::iterator &modMap ); -void ReadModbusRegister( std::map<std::string, ModbusRegister>::iterator &modMap ); -void ExecuteRegisterCommand( std::string ioString, std::string Command ); -void ExecuteRegisterOperation( std::map<std::string, VirtualCommand>::iterator &cmdMap ); -void UpdateOutputRegister( std::map<std::string, ModbusRegister>::iterator &modMap ); - -char ModbusMasterScratchBuf[MAX_FILE_SIZE]; -void ModbusMaster(void const *args) -{ - printf("%s ModbusMaster has started...", __func__); - bool SignaledMain = false; - std::map<std::string, ModbusRegister>::iterator modMap; - - mod_init(); - DigitalOut mod_power(PA_8); - mod_power = 0; // provide power to the modbus - -#ifdef EXECUTE_SCRIPT - v7_Create_Engine(); -#endif - -#ifdef LOAD_PERSISTENT_CONFIGURATIONS - std::vector<std::string>::iterator file; - std::vector<std::string> file_list; - file_list = GLOBAL_mdot->listUserFiles(); - for(file = file_list.begin(); file != file_list.end(); ++file) { -// printf("%s:%d: filename:%s\r\n", __func__, __LINE__, file->c_str() ); - LoadModbusConfigFile( (char *)file->c_str() ); - } -#endif - - while ( true ) { - for (modMap = ModbusRegisterMap.begin(); modMap != ModbusRegisterMap.end(); ++modMap) { - if( modMap->second.simulated == true ) { - UpdateSimulatedInput( modMap ); - continue; - } else if( modMap->second.node != 0 ) { - ReadModbusRegister( modMap ); - } else if( (modMap->second.node == 0) && (modMap->second.regType == REG_TYPE_INPUT) ) { -// printf("processing PIN input=%s, reg=%d, value=%d",modMap->first.c_str(), ModbusRegisterMap[modMap->first].reg, (bool)RegisterValueMap[modMap->first].float_value); - if( ModbusRegisterMap[modMap->first].reg == 1 ) { - // digital input - RegisterValueMap[modMap->first].float_value = (float)flow_switch.read(); - } else { - RegisterValueMap[modMap->first].float_value = (float)dinp2.read(); - } - } else if( modMap->second.regType == REG_TYPE_VINPUT ) { - UpdateVirtualRegister( modMap ); - } - } - - // now that all of the modbus registers are updated we can execute the register commands. -#ifdef EXECUTE_SCRIPT - std::map<std::string, ExecuteJavaScript>::iterator jsMap; - for (jsMap = ExecuteJavaScriptMap.begin(); jsMap != ExecuteJavaScriptMap.end(); ++jsMap) { -// printf("%s:%d: %s\r\n", __func__, __LINE__, Util_getHeapData().c_str()); - v7_Execute_Script( jsMap->second.script, jsMap->second.argv ); - } -#else - for (modMap = ModbusRegisterMap.begin(); modMap != ModbusRegisterMap.end(); ++modMap) { - ExecuteRegisterCommand( modMap->first, modMap->second.cmd ); - } -#endif - - // now that all of the inputs and virtuals have been updated, go through the outputs. - for (modMap = ModbusRegisterMap.begin(); modMap != ModbusRegisterMap.end(); ++modMap) { - if( modMap->second.regType == REG_TYPE_OUTPUT ) { - UpdateOutputRegister( modMap ); - } - } - - osEvent evt = ModbusMasterMailBox.get(50); - if (evt.status == osEventMail) { - ModbusMasterReq_t *mail = (ModbusMasterReq_t*)evt.value.p; - if( mail->action == ACTION_EXEC_CMD ) { - printf("Mail Received: Action: %d, Executing Command: %s\r\n", mail->action, mail->msg); - ModbusMasterExecCmd( mail->replyThread, mail->msg ); - } else { - printf("Mail Received: Action: %d, New Input File: %s\r\n", mail->action, mail->msg); - LoadModbusConfigFile( mail->msg ); - } - ModbusMasterMailBox.free(mail); - } - if( SignaledMain == false ) { - SignaledMain = true; - osSignalSet(mainThreadId, sig_output_continue); - } - Thread::wait(5000); - } -} - -bool ReadModbus_32bit_float( float *float_value, int order, unsigned char *rd_buf ) -{ - MR_REGISTER_32_BIT_FLOAT value; - - switch( order ) { - case BigEndian: - value.b.lo_lo = rd_buf[3]; - value.b.lo_hi = rd_buf[2]; - value.b.hi_lo = rd_buf[1]; - value.b.hi_hi = rd_buf[0]; - break; - case BigEndianReverseWord: - value.b.lo_lo = rd_buf[1]; - value.b.lo_hi = rd_buf[0]; - value.b.hi_lo = rd_buf[3]; - value.b.hi_hi = rd_buf[2]; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } -// printf("0x%x 0x%x 0x%x 0x%x (%2.4f)\r\n", value.b.hi_hi, value.b.hi_lo, value.b.lo_hi, value.b.lo_lo, value.f); - *float_value = value.f; - return true; -} - -bool WriteModbus_32bit_float( float float_value, int order, unsigned char *xmt_buf ) -{ - MR_REGISTER_32_BIT_FLOAT value; - - value.f = float_value; - - switch( order ) { - case BigEndian: - xmt_buf[3] = value.b.lo_lo; - xmt_buf[2] = value.b.lo_hi; - xmt_buf[1] = value.b.hi_lo; - xmt_buf[0] = value.b.hi_hi; - break; - case BigEndianReverseWord: - xmt_buf[1] = value.b.lo_lo; - xmt_buf[0] = value.b.lo_hi; - xmt_buf[3] = value.b.hi_lo; - xmt_buf[2] = value.b.hi_hi; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x (%2.4f)\r\n",__func__,__LINE__, value.b.hi_hi, value.b.hi_lo, value.b.lo_hi, value.b.lo_lo, value.f); - return true; -} - -bool WriteModbus_Multiple( std::vector<uint16_t> XmtData, int order, unsigned char *xmt_buf ) -{ - MR_REGISTER_32_BIT_FLOAT value; - -// std::vector<uint16_t>::iterator iter; -// for (iter = XmtData.begin(); iter != XmtData.end(); ++iter) { -// log_event << "{\"t\":"<< "\"" << iter->c_str() << "\"," << "\"v\":"<< "\"" << ModbusRegisterMap[*iter].float_value<< "\"},"; -// } - - switch( order ) { - case BigEndian: - xmt_buf[3] = value.b.lo_lo; - xmt_buf[2] = value.b.lo_hi; - xmt_buf[1] = value.b.hi_lo; - xmt_buf[0] = value.b.hi_hi; - break; - case BigEndianReverseWord: - xmt_buf[1] = value.b.lo_lo; - xmt_buf[0] = value.b.lo_hi; - xmt_buf[3] = value.b.hi_lo; - xmt_buf[2] = value.b.hi_hi; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x (%2.4f)\r\n",__func__,__LINE__, value.b.hi_hi, value.b.hi_lo, value.b.lo_hi, value.b.lo_lo, value.f); - return true; -} - -bool ReadModbus_32bit_int( int32_t *int32_value, int order, unsigned char *rd_buf ) -{ - MR_REGISTER_32BIT_INT value; - - switch( order ) { - case BigEndian: - value.b.lo_lo = rd_buf[3]; - value.b.lo_hi = rd_buf[2]; - value.b.hi_lo = rd_buf[1]; - value.b.hi_hi = rd_buf[0]; - break; - case BigEndianReverseWord: - value.b.lo_lo = rd_buf[1]; - value.b.lo_hi = rd_buf[0]; - value.b.hi_lo = rd_buf[3]; - value.b.hi_hi = rd_buf[2]; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } -// printf("0x%x 0x%x 0x%x 0x%x (%d)\r\n", value.b.hi_hi, value.b.hi_lo, value.b.lo_hi, value.b.lo_lo, value.i); - *int32_value = value.i; - return true; -} - -bool WriteModbus_32bit_int( int32_t int32_value, int order, unsigned char *xmt_buf ) -{ - MR_REGISTER_32BIT_INT value; - - value.i = int32_value; - - switch( order ) { - case BigEndian: - xmt_buf[3] = value.b.lo_lo; - xmt_buf[2] = value.b.lo_hi; - xmt_buf[1] = value.b.hi_lo; - xmt_buf[0] = value.b.hi_hi; - break; - case BigEndianReverseWord: - xmt_buf[1] = value.b.lo_lo; - xmt_buf[0] = value.b.lo_hi; - xmt_buf[3] = value.b.hi_lo; - xmt_buf[2] = value.b.hi_hi; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x (%d)\r\n", __func__, __LINE__, value.b.hi_hi, value.b.hi_lo, value.b.lo_hi, value.b.lo_lo, value.i); - return true; -} - -bool WriteModbus_16bit_int( int16_t int16_value, int order, unsigned char *xmt_buf ) -{ - MR_REGISTER_16BIT_INT value; - - value.w = int16_value; - - switch( order ) { - case BigEndian: - case BigEndianReverseWord: - xmt_buf[1] = value.b.lo; - xmt_buf[0] = value.b.hi; - break; - default: - printf("%s:%d: order not supported\r\n",__func__,__LINE__); - return false; - } - printf("%s:%d: 0x%x 0x%x (%d)\r\n", __func__,__LINE__, value.b.hi, value.b.lo, value.w); - return true; -} - -void ModbusMasterExecCmd( ThreadName_t replyTo, char *cmd ) -{ - bool status; - int ret; - int node, func, sreg, nreg, dtype, order; - float value; - unsigned char rd_buf[16]; - std::vector<uint16_t> XmtData; - - printf("%s:%d: command=%s\r\n", __func__, __LINE__, cmd ); - - cJSON * root = cJSON_Parse(cmd); - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - if ( cJSON_HasObjectItem(root, "holding") ) { - - std::string key = cJSON_GetObjectItem(root,"holding")->valuestring; - node = HoldingRegisterMap[key].node; - sreg = HoldingRegisterMap[key].sreg; - nreg = HoldingRegisterMap[key].nreg; - order = HoldingRegisterMap[key].order; - func = MODBUS_WRITE_MULTIPLE_HOLDING; - dtype = TYPE_MULTI_BYTE; - printf("%s:%d: HOLDING REGISTER COMMAND, tag=%s, node=%d, sreg=%d, nreg=%d, order=%d, func=%d\r\n", __func__,__LINE__, key.c_str(), node, sreg, nreg, order, func); - cJSON *data = cJSON_GetObjectItem(root, "data"); - for ( int i = 0; i < cJSON_GetArraySize(data); ++i ) { - cJSON *item = cJSON_GetArrayItem(data, i); - uint16_t item_value = atoi(cJSON_GetObjectItem(item, "v")->valuestring); - XmtData.push_back(item_value); - printf("Pushing data: %d\r\n",item_value); - } - } else { - node = atoi(cJSON_GetObjectItem(root,"node")->valuestring); - func = atoi(cJSON_GetObjectItem(root,"func")->valuestring); - sreg = atoi(cJSON_GetObjectItem(root,"sreg")->valuestring); - nreg = atoi(cJSON_GetObjectItem(root,"nreg")->valuestring); - dtype = atoi(cJSON_GetObjectItem(root,"dtype")->valuestring); - order = atoi(cJSON_GetObjectItem(root,"order")->valuestring); - value = atof(cJSON_GetObjectItem(root,"value")->valuestring); - if( dtype == TYPE_MULTI_BYTE ) { - if ( cJSON_HasObjectItem(root, "data") ) { - cJSON *data = cJSON_GetObjectItem(root, "data"); - for ( int i = 0; i < cJSON_GetArraySize(data); ++i ) { - cJSON *item = cJSON_GetArrayItem(data, i); - uint16_t item_value = atoi(cJSON_GetObjectItem(item, "v")->valuestring); - XmtData.push_back(item_value); - printf("Pushing data: %d\r\n",item_value); - } - } else { - printf("NO DATA FOR WRITE MULTIPLE HOLDING REGISTERS\r\n"); - ReplyToHandler( replyTo, id, DATA_ARRAY_MISSING, 0 ); - return; - } - } - } - cJSON_Delete(root); - - switch( func ) { - case MOD_FUNC_GET_HREG: // read holding register - case MOD_FUNC_GET_IREG: // read input register - ret = mod_read(node, func, sreg, nreg, rd_buf); - if( ret != MOD_ERROR_NONE ) { - ReplyToHandler( replyTo, id, ret, 0 ); - printf("CMD: %s:%d: %s failed, errflag=%d\r\n", __func__, __LINE__, id.c_str(), ret ); - break; - } - switch( dtype ) { - case TYPE_32BIT_FLOAT: { - float float_value; - status = ReadModbus_32bit_float( &float_value, order, rd_buf ); - if( status == true ) { - printf("CMD: %s:%d: %s value=%2.4f\r\n", __func__, __LINE__, id.c_str(), float_value ); - ret = SUCCESS; - } else { - printf("CMD: %s:%d: %s failed\r\n", __func__, __LINE__, id.c_str() ); - ret = ORDER_NOT_SUPPORTED; - } - ReplyToHandler( replyTo, id, ret, float_value ); - break; - } - case TYPE_32BIT_INT: - case TYPE_32BIT_UINT: { - int32_t int32_value; - status = ReadModbus_32bit_int( &int32_value, order, rd_buf ); - if( status == true ) { - printf("CMD: %s:%d: %s value=%d\r\n", __func__, __LINE__, id.c_str(), int32_value ); - ret = SUCCESS; - } else { - printf("CMD: %s:%d: %s failed\r\n", __func__, __LINE__, id.c_str() ); - ret = ORDER_NOT_SUPPORTED; - } - ReplyToHandler( replyTo, id, ret, (float)int32_value ); - break; - } - case TYPE_16BIT_INT: - case TYPE_16BIT_UINT: - break; - default: - break; - } - break; - case MOD_FUNC_SET_HREG: // write holding register - case MOD_FUNC_SET_HREGS: // write multiple registers (only supports 2 right now) - case MOD_FUNC_SET_COIL: { // write coil - unsigned char xmt_buf[10]; - switch( dtype ) { - case TYPE_32BIT_FLOAT: { - status = WriteModbus_32bit_float( value, order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: %s failed\r\n", __func__, __LINE__, id.c_str() ); - return; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1], xmt_buf[2], xmt_buf[3]); - break; - } - case TYPE_32BIT_INT: - case TYPE_32BIT_UINT: { - status = WriteModbus_32bit_int( (int32_t)value, order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: %s failed\r\n", __func__, __LINE__, id.c_str() ); - return; - } - break; - } - case TYPE_16BIT_INT: - case TYPE_16BIT_UINT: - status = WriteModbus_16bit_int( (int16_t)value, order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: %s failed\r\n", __func__, __LINE__, id.c_str() ); - return; - } - printf("%s:%d: 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1]); - break; - case TYPE_MULTI_BYTE : - printf("CMD: %s:%d: WRITE MULTI-BYTE NOT IMPLEMENTED\r\n", __func__, __LINE__ ); - ReplyToHandler( replyTo, id, UNKNOWN_OPERATION, 0 ); - return; - //break; - default: - printf("CMD: %s:%d: %s NOT IMPLEMENTED\r\n", __func__, __LINE__, id.c_str() ); - return; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1], xmt_buf[2], xmt_buf[3]); - ret = mod_write(node, func, sreg, nreg, xmt_buf); - if( ret != MOD_ERROR_NONE ) { - printf("CMD: %s:%d: %s failed, errflag=%d\r\n", __func__, __LINE__, id.c_str(), ret ); - } else { - printf("CMD: %s:%d: %s wrote to modbus func=%d reg=%d value=%2.4f, errflag=%d\r\n", __func__, __LINE__, id.c_str(), func, sreg, value, ret ); - } - ReplyToHandler( replyTo, id, ret, 0 ); - break; - } - default: - printf("CMD: %s:%d: %s failed, errflag=%d\r\n", __func__, __LINE__, id.c_str(), ret ); - ReplyToHandler( replyTo, id, UNKNOWN_OPERATION, 0 ); - break; - } -} - -void LoadModbusConfigFile( char *fileName ) -{ - bool status; - RegisterType_t regType; - -// printf("%s:%d: Loading Config file: %s\r\n", __func__, __LINE__, fileName); - - if( (strncmp( fileName, "cmd_", (strlen("cmd_")-1)) == 0) ) { - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d\r\n", __LINE__, status); - return; - } - - cJSON * root = cJSON_Parse(ModbusMasterScratchBuf); - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - VirtualCommandMap[id].Constant = atof(cJSON_GetObjectItem(root,"Constant")->valuestring); - VirtualCommandMap[id].Operator = cJSON_GetObjectItem(root,"Operator")->valuestring; - VirtualCommandMap[id].Operand = cJSON_GetObjectItem(root,"Operand")->valuestring; - printf("Loaded command file: id=%s, Operand=%s, Operator=%s, Constant=%.4f\r\n", id.c_str(), VirtualCommandMap[id].Operand.c_str(), VirtualCommandMap[id].Operator.c_str(), VirtualCommandMap[id].Constant); - cJSON_Delete(root); - return; - } - - if( (strncmp( fileName, "vreg_", (strlen("vreg_")-1)) == 0) ) { - printf("Loading Virtual Register File: %s\r\n", fileName); - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d\r\n", __LINE__, status); - return; - } - - cJSON * root = cJSON_Parse(ModbusMasterScratchBuf); - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - RegisterValueMap[id].float_value = atof(cJSON_GetObjectItem(root,"value")->valuestring); - RegisterValueMap[id].errflag = 0; - printf("Loaded Virtual Register file: id=%s, value=%.4f\r\n", id.c_str(), RegisterValueMap[id].float_value); - cJSON_Delete(root); - return; - } - -#ifdef EXECUTE_SCRIPT - if( (strncmp( fileName, "js_", (strlen("js_")-1)) == 0) ) { - printf("Loading JavaScript file: %s\r\n", fileName); - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d\r\n", __LINE__, status); - return; - } - v7_Load_Script( (const char *)ModbusMasterScratchBuf ); -// printf("Loaded function: %s\r\n", ModbusMasterScratchBuf); - return; - } - - if( (strncmp( fileName, "exe_js_", (strlen("exe_js_")-1)) == 0) ) { - printf("Loading JavaScript Execution file: %s\r\n", fileName); - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d\r\n", __LINE__, status); - return; - } - cJSON * root = cJSON_Parse(ModbusMasterScratchBuf); - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - ExecuteJavaScriptMap[id].script = cJSON_GetObjectItem(root, "script")->valuestring; - cJSON *args = cJSON_GetObjectItem(root, "args"); - printf("%s:%d: Number of array items: %d\r\n", __func__, __LINE__, cJSON_GetArraySize(args) ); - for ( int i = 0; i < cJSON_GetArraySize(args); ++i ) { - cJSON *item = cJSON_GetArrayItem(args, i); - ExecuteJavaScriptMap[id].argv[i] = cJSON_GetObjectItem(item, "arg")->valuestring; -// printf("Pushing tag data %s\r\n", cJSON_GetObjectItem(item, "arg")->valuestring); - } - printf("Loaded JavaScript Execute File: id=%s, script=%s, argv0=%s, argv0=%s, argv0=%s, argv0=%s\r\n", id.c_str(), ExecuteJavaScriptMap[id].script.c_str(), ExecuteJavaScriptMap[id].argv[0].c_str(),ExecuteJavaScriptMap[id].argv[1].c_str(),ExecuteJavaScriptMap[id].argv[2].c_str(),ExecuteJavaScriptMap[id].argv[3].c_str() ); - cJSON_Delete(root); - return; - } -#endif - - if( (strncmp( fileName, "hold", (strlen("hold")-1)) == 0) ) { - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d\r\n", __LINE__, status); - return; - } - - cJSON * root = cJSON_Parse(ModbusMasterScratchBuf); - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - HoldingRegisterMap[id].node = atoi(cJSON_GetObjectItem(root,"node")->valuestring); - HoldingRegisterMap[id].sreg = atoi(cJSON_GetObjectItem(root,"sreg")->valuestring); - HoldingRegisterMap[id].nreg = atoi(cJSON_GetObjectItem(root,"nreg")->valuestring); - HoldingRegisterMap[id].order = atoi(cJSON_GetObjectItem(root,"order")->valuestring); - printf("Loaded holding register: id=%s, node=%d, sreg=%d, nreg=%d, order=%d\r\n", id.c_str(), HoldingRegisterMap[id].node, HoldingRegisterMap[id].sreg, HoldingRegisterMap[id].nreg, HoldingRegisterMap[id].order); - cJSON_Delete(root); - return; - } - - regType = REG_TYPE_NONE; - - if( (strncmp( fileName, "input", (strlen("input")-1)) == 0) ) { - regType = REG_TYPE_INPUT; - } else if( (strncmp( fileName, "output", (strlen("output")-1)) == 0) ) { - regType = REG_TYPE_OUTPUT; - } else if( (strncmp( fileName, "vinput", (strlen("vinput")-1)) == 0) ) { - regType = REG_TYPE_VINPUT; - } else if( (strncmp( fileName, "voutput", (strlen("voutput")-1)) == 0) ) { - regType = REG_TYPE_VOUTPUT; - } - - if( regType != REG_TYPE_NONE ) { - status = GLOBAL_mdot->readUserFile(fileName, ModbusMasterScratchBuf, MAX_FILE_SIZE); - if( status != true ) { - printf("(%d)read file failed, status=%d", __LINE__, status); - return; - } else { -// printf("(%s:%d)loading File: %s\r\n", __func__, __LINE__, fileName ); -// printf("%s:%d:Loaded:%s\r\n", __func__, __LINE__, ModbusMasterScratchBuf ); - } - - cJSON * root = cJSON_Parse(ModbusMasterScratchBuf); - if( !cJSON_HasObjectItem(root,"id") ) - { - printf("%s:%d: INVALID JSON STRING\r\n", __func__,__LINE__); - return; - } - std::string id = cJSON_GetObjectItem(root,"id")->valuestring; - ModbusRegisterMap[id].min = atof(cJSON_GetObjectItem(root,"min")->valuestring); - ModbusRegisterMap[id].max = atof(cJSON_GetObjectItem(root,"max")->valuestring); - ModbusRegisterMap[id].node = atoi(cJSON_GetObjectItem(root,"node")->valuestring); - ModbusRegisterMap[id].reg = atoi(cJSON_GetObjectItem(root,"reg")->valuestring); - ModbusRegisterMap[id].rtype = atoi(cJSON_GetObjectItem(root,"rtype")->valuestring); - ModbusRegisterMap[id].type = atoi(cJSON_GetObjectItem(root,"type")->valuestring); - ModbusRegisterMap[id].size = atoi(cJSON_GetObjectItem(root,"size")->valuestring); - ModbusRegisterMap[id].order = atoi(cJSON_GetObjectItem(root,"order")->valuestring); - ModbusRegisterMap[id].rfreq = atoi(cJSON_GetObjectItem(root,"rfreq")->valuestring); - ModbusRegisterMap[id].regType = regType; - ModbusRegisterMap[id].simulated = false; - RegisterValueMap[id].errflag = 0; - ModbusRegisterMap[id].cmd = cJSON_GetObjectItem(root,"cmd")->valuestring; - cJSON_Delete(root);; - } - return; -} - -void UpdateSimulatedInput( std::map<std::string, ModbusRegister>::iterator &modMap ) -{ - if ( SimulateInputMap[modMap->first].errflag ) { - RegisterValueMap[modMap->first].errflag = SimulateInputMap[modMap->first].errflag; - } else { - RegisterValueMap[modMap->first].errflag = 0; - } - // printf("\r\nsimulating input=%s, min=%2.4f, max=%2.4f, start_value=%2.4f, up_step=%2.4f, down_step=%2.4f moving_up=%d\r\n",modMap->first.c_str(), SimulateInputMap[modMap->first].min, SimulateInputMap[modMap->first].max, SimulateInputMap[modMap->first].start_value, SimulateInputMap[modMap->first].up_step, SimulateInputMap[modMap->first].down_step, SimulateInputMap[modMap->first].moving_up); - if( (SimulateInputMap[modMap->first].min == 0) && (SimulateInputMap[modMap->first].max == 0) ) { - RegisterValueMap[modMap->first].float_value = SimulateInputMap[modMap->first].start_value; -// printf("simulating input=%s, value=%2.4f\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value); - } else { - if( RegisterValueMap[modMap->first].float_value >= SimulateInputMap[modMap->first].max ) { - SimulateInputMap[modMap->first].moving_up = false; -// printf("simulating down input=%s, value=%2.4f - %2.4f\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value, SimulateInputMap[modMap->first].down_step); - RegisterValueMap[modMap->first].float_value = RegisterValueMap[modMap->first].float_value - SimulateInputMap[modMap->first].down_step; - } else if( RegisterValueMap[modMap->first].float_value <= SimulateInputMap[modMap->first].min ) { - SimulateInputMap[modMap->first].moving_up = true; -// printf("simulating up input=%s, value=%2.4f + %2.4f\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value, SimulateInputMap[modMap->first].up_step); - RegisterValueMap[modMap->first].float_value = RegisterValueMap[modMap->first].float_value + SimulateInputMap[modMap->first].up_step; - } else { - if( SimulateInputMap[modMap->first].moving_up == true ) { -// printf("continue simulate up input=%s, value=%2.4f + %2.4f\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value, SimulateInputMap[modMap->first].up_step); - RegisterValueMap[modMap->first].float_value = RegisterValueMap[modMap->first].float_value + SimulateInputMap[modMap->first].up_step; - } else { -// printf("continue simulate down input=%s, value=%2.4f - %2.4f\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value, SimulateInputMap[modMap->first].down_step); - RegisterValueMap[modMap->first].float_value = RegisterValueMap[modMap->first].float_value - SimulateInputMap[modMap->first].down_step; - } - } -// printf("simulating input=%s, value=%2.4f\r\n\r\n",modMap->first.c_str(), RegisterValueMap[modMap->first].float_value); - } -} - -void UpdateVirtualRegister( std::map<std::string, ModbusRegister>::iterator &modMap ) -{ -} - -void ReadModbusRegister( std::map<std::string, ModbusRegister>::iterator &modMap ) -{ - bool status; - unsigned char rd_buf[16]; - memset( rd_buf, 0, 16 ); -// printf("Processing Input: tag=%s, node=%d, reg=%d, size=%d, order=%d", modMap->first.c_str(), modMap->second.node, modMap->second.reg, modMap->second.size, modMap->second.order ); - int ret = mod_read(modMap->second.node, modMap->second.rtype, modMap->second.reg, modMap->second.size, rd_buf); - switch( modMap->second.type ) { - case TYPE_32BIT_FLOAT: - float float_value; - if( ret != MOD_ERROR_NONE ) { - RegisterValueMap[modMap->first].errflag = ret; - break; - } - status = ReadModbus_32bit_float( &float_value, modMap->second.order, rd_buf ); - if( status == true ) { - RegisterValueMap[modMap->first].float_value = float_value; - RegisterValueMap[modMap->first].errflag = 0; -// printf("Modbus Tag:%s value=%2.4f", modMap->first.c_str(), float_value ); - } else { - RegisterValueMap[modMap->first].errflag = 1000; -// printf("Modbus Read Failed, tag=%s", modMap->first.c_str() ); - } - break; - case TYPE_32BIT_INT: - int32_t int32_value; - if( ret != MOD_ERROR_NONE ) { - RegisterValueMap[modMap->first].errflag = ret; - break; - } - status = ReadModbus_32bit_int( &int32_value, modMap->second.order, rd_buf ); - if( status == true ) { - RegisterValueMap[modMap->first].float_value = int32_value; - RegisterValueMap[modMap->first].errflag = 0; - printf("Modbus Tag:%s value=%2.4f", modMap->first.c_str(), RegisterValueMap[modMap->first].float_value ); - } else { - RegisterValueMap[modMap->first].errflag = 1000; - printf("Modbus Read Failed, tag=%s", modMap->first.c_str() ); - } - break; - case TYPE_32BIT_UINT: - break; - case TYPE_16BIT_INT: - break; - case TYPE_16BIT_UINT: - break; - default: - break; - } -} - -void ExecuteRegisterCommand( std::string ioTag, std::string Command ) -{ - if( Command.size() == 0 ) { - return; - } -// printf("Executing Register Commnand: %s for %s\r\n",Command.c_str(), ioTag.c_str()); - float operandValue = 0; - float ioTagValue = RegisterValueMap[ioTag].float_value; - if( VirtualCommandMap[Command].Operand.size() != 0 ) { - operandValue = RegisterValueMap[VirtualCommandMap[Command].Operand].float_value; - } - float constantValue = VirtualCommandMap[Command].Constant; - - switch( VirtualCommandMap[Command].Operator.c_str()[0] ) { - case '=': - if( VirtualCommandMap[Command].Operand.size() == 0 ) { - RegisterValueMap[ioTag].float_value = constantValue; - } else { - RegisterValueMap[ioTag].float_value = operandValue; - } -// printf("Setting tag=%s, equal to (value=%2.4f)\r\n", ioTag.c_str(), ModbusRegisterMap[ioTag].float_value ); - break; - case '*': { - if( VirtualCommandMap[Command].Operand.size() == 0 ) { - RegisterValueMap[ioTag].float_value = ioTagValue * constantValue; -// printf("Setting tag=%s, equal to (%2.4f*%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, constantValue, ModbusRegisterMap[ioTag].float_value ); - } else { - RegisterValueMap[ioTag].float_value = ioTagValue * operandValue; -// printf("Setting tag=%s, equal to (%2.4f*%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, operandValue, ModbusRegisterMap[ioTag].float_value ); - } - break; - } - case '/': { - if( VirtualCommandMap[Command].Operand.size() == 0 ) { - // constant operation - RegisterValueMap[ioTag].float_value = ioTagValue / constantValue; -// printf("Setting tag=%s, equal to (%2.4f/%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, constantValue, ModbusRegisterMap[ioTag].float_value ); - } else if( operandValue != 0 ) { - RegisterValueMap[ioTag].float_value = ioTagValue / operandValue; -// printf("Setting tag=%s, equal to (%2.4f/%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, operandValue, ModbusRegisterMap[ioTag].float_value ); - } else { -// printf("NOT DOING DIVIDE BY ZERO\r\n"); - } - break; - } - case '+': { - if( VirtualCommandMap[Command].Operand.size() == 0 ) { - RegisterValueMap[ioTag].float_value = ioTagValue + constantValue; -// printf("Setting tag=%s, equal to (%2.4f+%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, constantValue, ModbusRegisterMap[ioTag].float_value ); - } else { - RegisterValueMap[ioTag].float_value = ioTagValue + operandValue; -// printf("Setting tag=%s, equal to (%2.4f+%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, operandValue, ModbusRegisterMap[ioTag].float_value ); - } - break; - } - case '-': { - if( VirtualCommandMap[Command].Operand.size() == 0 ) { - RegisterValueMap[ioTag].float_value = ioTagValue - constantValue; -// printf("Setting tag=%s, equal to (%2.4f-%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, constantValue, ModbusRegisterMap[ioTag].float_value ); - } else { - RegisterValueMap[ioTag].float_value = ioTagValue - operandValue; -// printf("Setting tag=%s, equal to (%2.4f-%2.4f) = %2.4f\r\n", ioTag.c_str(), ioTagValue, operandValue, ModbusRegisterMap[ioTag].float_value ); - } - break; - } - default: - printf("OPERATION NOT SUPPORTED: %s\r\n", VirtualCommandMap[Command].Operator.c_str()); - break; - } -} - -void UpdateOutputRegister( std::map<std::string, ModbusRegister>::iterator &modMap ) -{ - bool status; - int ret; - - if( modMap->second.node == 0) { - if( ModbusRegisterMap[modMap->first].reg == 1 ) { - dout1 = (bool)((int)RegisterValueMap[modMap->first].float_value&0x1); - } else { - dout2 = (bool)((int)RegisterValueMap[modMap->first].float_value&0x1); - } - } else { - unsigned char xmt_buf[10]; - - switch( ModbusRegisterMap[modMap->first].type ) { - case TYPE_32BIT_FLOAT: { - status = WriteModbus_32bit_float( RegisterValueMap[modMap->first].float_value, ModbusRegisterMap[modMap->first].order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: failed\r\n", __func__, __LINE__); - return; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1], xmt_buf[2], xmt_buf[3]); - break; - } - case TYPE_32BIT_INT: - case TYPE_32BIT_UINT: { - status = WriteModbus_32bit_int( ((int32_t)RegisterValueMap[modMap->first].float_value&0x1), ModbusRegisterMap[modMap->first].order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: failed\r\n", __func__, __LINE__ ); - return; - } - break; - } - case TYPE_16BIT_INT: - case TYPE_16BIT_UINT: - status = WriteModbus_16bit_int( ((int16_t)RegisterValueMap[modMap->first].float_value&0x1), ModbusRegisterMap[modMap->first].order, xmt_buf ); - if( status != true ) { - printf("CMD: %s:%d: failed\r\n", __func__, __LINE__ ); - return; - } - printf("%s:%d: 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1]); - break; - default: - printf("CMD: %s:%d: NOT IMPLEMENTED\r\n", __func__, __LINE__ ); - return; - } - printf("%s:%d: 0x%x 0x%x 0x%x 0x%x\r\n", __func__,__LINE__, xmt_buf[0], xmt_buf[1], xmt_buf[2], xmt_buf[3]); - ret = mod_write(ModbusRegisterMap[modMap->first].node, ModbusRegisterMap[modMap->first].rtype, ModbusRegisterMap[modMap->first].reg, ModbusRegisterMap[modMap->first].size, xmt_buf); - if( ret != MOD_ERROR_NONE ) { - printf("CMD: %s:%d: failed, errflag=%d\r\n", __func__, __LINE__, ret ); - } else { - printf("CMD: %s:%d: wrote to modbus func=%d reg=%d value=%2.4f, errflag=%d\r\n", __func__, __LINE__, ModbusRegisterMap[modMap->first].rtype, ModbusRegisterMap[modMap->first].reg, RegisterValueMap[modMap->first].float_value, ret ); - } - } -}