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
Diff: src/ConfigurationHandler/Controls/FailsafeControl.cpp
- Revision:
- 252:3c9863f951b7
- Parent:
- 250:1cd8ec63e9e9
- Child:
- 253:ae850c19cf81
--- a/src/ConfigurationHandler/Controls/FailsafeControl.cpp Fri Oct 21 11:44:40 2016 +0000 +++ b/src/ConfigurationHandler/Controls/FailsafeControl.cpp Fri Oct 21 18:16:42 2016 +0000 @@ -8,6 +8,7 @@ #include "cJSON.h" #include "mDot.h" #include "global.h" +#include "ModbusMasterApi.h" #include <string> #include <iostream> #include <iomanip> @@ -78,7 +79,7 @@ // // method: update -// description: update the faisafe control +// description: update the faisafe control using the FSM // // @param none // @return none @@ -90,16 +91,155 @@ // do nothing break; case STATE_START: + if ( this->aboveHighFailsafe() ) { + currentState = STATE_CONTROL_HFS_ON; + } else if ( this->belowLowFailsafe() ) { + currentState = STATE_CONTROL_LFS_ON; + } else { + currentState = STATE_CONTROL_OFF; + } + break; case STATE_CONTROL_OFF: + if ( this->aboveHighFailsafe() ) { + currentState = STATE_CONTROL_HFS_ON; + if ( hfs_data.dutyCycle ) { + this->startHfsTimer(); + // send an ON request to the output thread + sendMail(ACTION_CONTROL_ON); + } else { + // fixed off + sendMail(ACTION_CONTROL_OFF); + // fixed off + } + } else if ( this->belowLowFailsafe() ) { + currentState = STATE_CONTROL_LFS_ON; + } else { + // do nothing + } + break; case STATE_CONTROL_LFS_ON: + if ( !this->belowLowFailsafe() ) { + currentState = STATE_CONTROL_OFF; + } else { + // check the time interval + } + break; case STATE_CONTROL_LFS_OFF: + if ( !this->belowLowFailsafe() ) { + currentState = STATE_CONTROL_OFF; + } else { + + } + break; case STATE_CONTROL_HFS_ON: + // the control is in HFS with the output ON + if ( !this->aboveHighFailsafe() ) { + currentState = STATE_CONTROL_OFF; + // clear the timer + this->stopHfsTimer(); + } else if ( this->hfsTimerElapsed() ) { + // duty cyle + printf("\rInitial timer has expired\n"); + currentState = STATE_CONTROL_HFS_OFF; + } + break; case STATE_CONTROL_HFS_OFF: + // the control is in HFS with the output OFF + if ( !this->aboveHighFailsafe() ) { + currentState = STATE_CONTROL_OFF; + } else { + + } + break; default: break; } } +bool FailsafeControl::belowLowFailsafe(void) +{ + // read the modbus input + ModbusValue value; + ModbusMasterReadRegister(input, &value); +#if 0 + if ( value.errflag ) { + logError("%s: error reading %s:", __func__, input); + return false; + } +#endif + return ( value.value <= lfs_data.value ); +} + +bool FailsafeControl::aboveHighFailsafe(void) +{ + // read the modbus input + ModbusValue value; + ModbusMasterReadRegister(input, &value); + // TODO: check the error flag +#if 0 + if ( value.errflag ) { + logError("%s: error reading %s:", __func__, input); + return false; + } +#endif + return ( value.value >= hfs_data.value ); +} + +// +// method: startHfsTimer +// description: +void FailsafeControl::startHfsTimer(void) +{ + printf("%s invoked\n", __func__); + unsigned long currentTime = time(NULL); + unsigned long period = hfs_data.interval * 60; + + double totalOnTime = (double)period * ((double)hfs_data.dutyCycle/(double)100.0); + duty_timer.offTime = (unsigned long) totalOnTime; + duty_timer.expirationTime = currentTime + period; + + printf("\rnext off time = %lu\n", duty_timer.offTime); + printf("\rexpiration time = %lu\n", duty_timer.expirationTime); +} + +void FailsafeControl::stopHfsTimer(void) +{ + memset(&duty_timer, 0, sizeof(duty_timer)); +} + +bool FailsafeControl::hfsTimerElapsed(void) +{ + return ( duty_timer.offTime >= time(NULL) ); +} + +// +// method: sendMail +// description: send mail to the output task +// +// @param io_tag -> input/output tag +// @param action -> ON, OFF, UNREGISTER +// @return none +// +void FailsafeControl::sendMail(OutputAction action) +{ + logInfo("%s: failsafe control attempting to send action %d\n", + __func__, action); + + OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); + memset(output_mail, 0, sizeof(OutputControlMsg_t)); + + output_mail->action = action; + output_mail->controlType = CONTROL_FAILSAFE; + output_mail->priority = this->priority; + + 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); + strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); + + OutputMasterMailBox.put(output_mail); +} + + // // method: display // description: display the pertinents @@ -127,8 +267,10 @@ std::cout << left << setw(20) << setfill(' ') << input; std::cout << left << setw(20) << setfill(' ') << output; std::cout << left << setw(16) << setfill(' ') << mapper[currentState]; - std::cout << left << setw(12) << setfill(' ') << "lfs-> " << lfs_data.value << ":" << lfs_data.dutyCycle << ":" << lfs_data.interval; - std::cout << right << setw(12) << setfill(' ') << "hfs-> " << hfs_data.value << ":" << hfs_data.dutyCycle << ":" << hfs_data.interval; + std::cout << left << setw(12) << setfill(' ') << "lfs-> " + << lfs_data.value << ":" << lfs_data.dutyCycle << ":" << lfs_data.interval; + std::cout << right << setw(12) << setfill(' ') << "hfs-> " + << hfs_data.value << ":" << hfs_data.dutyCycle << ":" << hfs_data.interval; std::cout.flush(); -} +} \ No newline at end of file