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.
Dependencies: NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed
Fork of ICE by
src/ConfigurationHandler/Controls/SetpointControl.cpp
- Committer:
- jmarkel44
- Date:
- 2016-10-06
- Revision:
- 194:5aa463e15d27
- Parent:
- 193:3acbcc2f6fcb
- Child:
- 195:21df85341cb3
File content as of revision 194:5aa463e15d27:
/****************************************************************************** * * File: SetpointControl.cpp * Desciption: ICE Setpoint Control class implementation * *****************************************************************************/ #include "SetpointControl.h" #include "mDot.h" #include "MbedJSONValue.h" #include "ModbusMasterApi.h" #include "global.h" #include <string> extern mDot *GLOBAL_mdot; // Method: load // Description: open the configuration file and assign data to the // setpoint control object // // @param controlFile -> name of the control file // @return true if data is assigned; false on error bool SetpointControl::load(string _controlFile) { MbedJSONValue json_value; // JSON parsing element controlFile = _controlFile; // open and read from the control file mDot::mdot_file file = GLOBAL_mdot->openUserFile(controlFile.c_str(), mDot::FM_RDONLY); if ( file.fd < 0 ) return false; // read the data into a buffer char dataBuf[MAX_FILE_SIZE]; int bytes_read = GLOBAL_mdot->readUserFile(file, (void *)dataBuf, sizeof(dataBuf)); if ( bytes_read != sizeof(dataBuf) ) { logError("%s: failed to read %d bytes from %s", __func__, sizeof(dataBuf), controlFile.c_str()); // caller should destroy the object return false; } // close the file GLOBAL_mdot->closeUserFile(file); // parse the json data parse(json_value, dataBuf); if ( !json_value.hasMember("id") || !json_value.hasMember("priority") || !json_value.hasMember("input") || !json_value.hasMember("output") || !json_value.hasMember("setpoint") || !json_value.hasMember("prodfact") || !json_value.hasMember("actingDir") || !json_value.hasMember("halert") || !json_value.hasMember("lalert") || !json_value.hasMember("hfs") || !json_value.hasMember("lfs") || !json_value.hasMember("tol") ) { logError("Setpoint Control file is missing expexted tags"); return false; } id = json_value ["id"].get<string>(); priority = atoi(json_value["priority"].get<string>().c_str()); input = json_value ["input"].get<string>(); output = json_value ["output"].get<string>(); setpoint = atof(json_value["setpoint"].get<string>().c_str()); productFactor = atof(json_value["prodfact"].get<string>().c_str()); actingDir = atoi(json_value["actingDir"].get<string>().c_str()); highAlert = atof(json_value["halert"].get<string>().c_str()); lowAlert = atof(json_value["lalert"].get<string>().c_str()); highFailsafe = atof(json_value["hfs"].get<string>().c_str()); lowFailsafe = atof(json_value["lfs"].get<string>().c_str()); tolerance = atof(json_value["tol"].get<string>().c_str()); return true; // object created successfully } // Method: start // Description: start the setpoint control // // @param none // @return none void SetpointControl::start(void) { // this is the initial state; what else needs to be done?? this->currentState = STATE_STARTUP; } // Method: update // Description: based on the state of the control, check for // under limit and over limit values, adjust the // state accordingly // // @param none // @return none void SetpointControl::update(void) { switch (this->currentState) { case STATE_INIT: // do nothing break; case STATE_STARTUP: if ( this->underLimit() ) { // start the feed right away this->startFeed(); this->currentState = STATE_CONTROL_ON; } else { this->currentState = STATE_CONTROL_OFF; this->stopFeed(); } break; case STATE_CONTROL_ON: if ( this->overLimit() ) { // stop the feed this->stopFeed(); this->currentState = STATE_CONTROL_OFF; } else { // do nothing } break; case STATE_CONTROL_OFF: if ( this->underLimit() ) { // start the feed this->startFeed(); this->currentState = STATE_CONTROL_ON; } else { // do nothing } break; //case STATE_CONTROL_DISABLED: //case STATE_CONTROL_PAUSED: default: break; } } // Method: overLimit // Description: (see @return) // // @param none // @return true if product is over the upper limit for normal mode // or under the limit for reverse mode; false otherwise bool SetpointControl::overLimit(void) { ModbusValue value; ModbusMasterReadRegister( input, &value ); float flimit; if ( !actingDir ) { flimit = setpoint + tolerance; return (value.value > flimit); } else { flimit = setpoint - tolerance; return (value.value < flimit); } } // Method: underLimit // Description: (see @return) // // @param none // @return true if product is under lower limit for normal mode or // over the upper limit for reverse mode; false otherwise bool SetpointControl::underLimit(void) { ModbusValue value; ModbusMasterReadRegister( input, &value ); float flimit; if ( !actingDir ) { flimit = setpoint - tolerance; return (value.value < flimit); } else { flimit = setpoint + tolerance; return (value.value > flimit); } } // Method: startFeed() // Description: send ON indication to Output Master for this control's // relay // // @param none // @return none void SetpointControl::startFeed(void) { logInfo("%s: %s attempting to start feed on relay %s\n", __func__, controlFile.c_str(), output.c_str()); OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); memset(output_mail, 0, sizeof(OutputControlMsg_t)); output_mail->action = ACTION_CONTROL_ON; output_mail->controlType = CONTROL_SETPOINT; strncpy(output_mail->input_tag, this->input.c_str(), sizeof(output_mail->input_tag)-1); strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1); output_mail->priority = this->priority; strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); OutputMasterMailBox.put(output_mail); } // Method: stopFeed // Description: send OFF indication to Output Master for this control's // relay // // @param none // @return none void SetpointControl::stopFeed(void) { logInfo("%s: %s attempting to stop feed on relay %s\n", __func__, controlFile.c_str(), output.c_str()); OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); memset(output_mail, 0, sizeof(OutputControlMsg_t)); output_mail->action = ACTION_CONTROL_OFF; output_mail->controlType = CONTROL_SETPOINT; strncpy(output_mail->input_tag, this->input.c_str(), sizeof(output_mail->input_tag)-1); strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1); output_mail->priority = this->priority; strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); OutputMasterMailBox.put(output_mail); } // Method: unregisterControl // Description: send OFF indication to Output Master for this control's // relay // // @param none // @return none void SetpointControl::unregisterControl(void) { logInfo("%s: %s attempting to unregister %s\n", __func__, controlFile.c_str()); OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); memset(output_mail, 0, sizeof(OutputControlMsg_t)); output_mail->action = ACTION_CONTROL_UNREGISTER; output_mail->controlType = CONTROL_MANUAL; output_mail->priority = this->priority; strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1); strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); OutputMasterMailBox.put(output_mail); } // Method: display // Description: display the control's information // // @param none // @return none void SetpointControl::display(void) { // NOTE: this mapping must be 1:1 with "State" enumeration in SetpointControl.h string mapper[] = { "INIT", "STARTUP", "CONTROL_OFF", "CONTROL_ON", "CONTROL_DISABLE", "CONTROL_PAUSE", "CONTROL_MAX" }; ModbusValue inputValue; ModbusMasterReadRegister(input, &inputValue); printf("\r controlFile : %s \n", controlFile.c_str()); printf("\r id : %s \n", id.c_str()); printf("\r priority : %d \n", priority); printf("\r input : %s \n", input.c_str()); printf("\r output : %s \n", output.c_str()); printf("\r setpoint : %0.2f\n", setpoint); printf("\r prodfact : %0.2f\n", productFactor); printf("\r actingDir : %s \n", (actingDir) ? "DIRECT" : "INDIRECT"); printf("\r halert : %0.2f\n", highAlert); printf("\r lalert : %0.2f\n", lowAlert); printf("\r hfs : %0.2f\n", highFailsafe); printf("\r lfs : %0.2f\n", lowFailsafe); printf("\r tol : %0.2f\n", tolerance); printf("\r\n"); printf("\r currentState : %s\n", mapper[currentState].c_str()); printf("\r high band : %0.2f\n", setpoint + tolerance); printf("\r current reading : %0.2f [0x%04x]\n", inputValue.value, inputValue.errflag ); printf("\r low band : %0.2f\n", setpoint - tolerance); printf("\r\n"); }