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/FailsafeControl.cpp@273:0373b2a15f8a, 2016-10-26 (annotated)
- Committer:
- jmarkel44
- Date:
- Wed Oct 26 19:29:50 2016 +0000
- Revision:
- 273:0373b2a15f8a
- Parent:
- 271:19948511cd3f
- Child:
- 274:e2caebc7c65e
added failsafes to the preloader
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| jmarkel44 | 250:1cd8ec63e9e9 | 1 | /****************************************************************************** |
| jmarkel44 | 250:1cd8ec63e9e9 | 2 | * |
| jmarkel44 | 250:1cd8ec63e9e9 | 3 | * File: CompositeControl.cpp |
| jmarkel44 | 250:1cd8ec63e9e9 | 4 | * Desciption: ICE Composite Control Class implementation |
| jmarkel44 | 250:1cd8ec63e9e9 | 5 | * |
| jmarkel44 | 250:1cd8ec63e9e9 | 6 | *****************************************************************************/ |
| jmarkel44 | 250:1cd8ec63e9e9 | 7 | #include "FailsafeControl.h" |
| jmarkel44 | 250:1cd8ec63e9e9 | 8 | #include "cJSON.h" |
| jmarkel44 | 250:1cd8ec63e9e9 | 9 | #include "mDot.h" |
| jmarkel44 | 250:1cd8ec63e9e9 | 10 | #include "global.h" |
| jmarkel44 | 252:3c9863f951b7 | 11 | #include "ModbusMasterApi.h" |
| jmarkel44 | 250:1cd8ec63e9e9 | 12 | #include <string> |
| jmarkel44 | 250:1cd8ec63e9e9 | 13 | #include <iostream> |
| jmarkel44 | 250:1cd8ec63e9e9 | 14 | #include <iomanip> |
| jmarkel44 | 250:1cd8ec63e9e9 | 15 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 16 | extern mDot *GLOBAL_mdot; |
| jmarkel44 | 250:1cd8ec63e9e9 | 17 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 18 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 19 | // method: load |
| jmarkel44 | 250:1cd8ec63e9e9 | 20 | // description: load a composite control |
| jmarkel44 | 250:1cd8ec63e9e9 | 21 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 22 | // @param none |
| jmarkel44 | 250:1cd8ec63e9e9 | 23 | // @return none |
| jmarkel44 | 250:1cd8ec63e9e9 | 24 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 25 | bool FailsafeControl::load(std::string _controlFile) |
| jmarkel44 | 250:1cd8ec63e9e9 | 26 | { |
| jmarkel44 | 250:1cd8ec63e9e9 | 27 | controlFile = _controlFile; |
| jmarkel44 | 250:1cd8ec63e9e9 | 28 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 29 | // open and read from the control file |
| jmarkel44 | 250:1cd8ec63e9e9 | 30 | mDot::mdot_file file = GLOBAL_mdot->openUserFile(controlFile.c_str(), mDot::FM_RDONLY); |
| jmarkel44 | 250:1cd8ec63e9e9 | 31 | if ( file.fd < 0 ) { |
| jmarkel44 | 250:1cd8ec63e9e9 | 32 | logError("%s: failed to open %s\n", __func__, controlFile.c_str()); |
| jmarkel44 | 250:1cd8ec63e9e9 | 33 | return false; |
| jmarkel44 | 250:1cd8ec63e9e9 | 34 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 35 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 36 | // read the data into a buffer |
| jmarkel44 | 250:1cd8ec63e9e9 | 37 | char dataBuf[MAX_FILE_SIZE]; |
| jmarkel44 | 250:1cd8ec63e9e9 | 38 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 39 | int bytes_read = GLOBAL_mdot->readUserFile(file, (void *)dataBuf, sizeof(dataBuf)); |
| jmarkel44 | 250:1cd8ec63e9e9 | 40 | if ( bytes_read != sizeof(dataBuf) ) { |
| jmarkel44 | 250:1cd8ec63e9e9 | 41 | logError("%s: failed to read %d bytes from %s", __func__, sizeof(dataBuf), controlFile.c_str()); |
| jmarkel44 | 250:1cd8ec63e9e9 | 42 | // caller should destroy the object |
| jmarkel44 | 250:1cd8ec63e9e9 | 43 | return false; |
| jmarkel44 | 250:1cd8ec63e9e9 | 44 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 45 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 46 | // close the file |
| jmarkel44 | 250:1cd8ec63e9e9 | 47 | GLOBAL_mdot->closeUserFile(file); |
| jmarkel44 | 250:1cd8ec63e9e9 | 48 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 49 | // parse the data |
| jmarkel44 | 250:1cd8ec63e9e9 | 50 | cJSON * root = cJSON_Parse(dataBuf); |
| jmarkel44 | 250:1cd8ec63e9e9 | 51 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 52 | id = cJSON_GetObjectItem(root, "id")->valuestring; |
| jmarkel44 | 250:1cd8ec63e9e9 | 53 | priority = atoi(cJSON_GetObjectItem(root, "priority")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 54 | input = cJSON_GetObjectItem(root, "input")->valuestring; |
| jmarkel44 | 250:1cd8ec63e9e9 | 55 | output = cJSON_GetObjectItem(root, "output")->valuestring; |
| jmarkel44 | 250:1cd8ec63e9e9 | 56 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 57 | hfs_data.value = atof(cJSON_GetObjectItem(root, "hfsValue")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 58 | hfs_data.dutyCycle = atoi(cJSON_GetObjectItem(root, "hfsDutyCycle")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 59 | hfs_data.interval = atoi(cJSON_GetObjectItem(root, "hfsInterval")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 60 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 61 | lfs_data.value = atof(cJSON_GetObjectItem(root, "lfsValue")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 62 | lfs_data.dutyCycle = atoi(cJSON_GetObjectItem(root, "lfsDutyCycle")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 63 | lfs_data.interval = atoi(cJSON_GetObjectItem(root, "lfsInterval")->valuestring); |
| jmarkel44 | 250:1cd8ec63e9e9 | 64 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 65 | return true; |
| jmarkel44 | 250:1cd8ec63e9e9 | 66 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 67 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 68 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 69 | // method: start |
| jmarkel44 | 250:1cd8ec63e9e9 | 70 | // description: start the failsafe control |
| jmarkel44 | 250:1cd8ec63e9e9 | 71 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 72 | // @param none |
| jmarkel44 | 250:1cd8ec63e9e9 | 73 | // @return none |
| jmarkel44 | 250:1cd8ec63e9e9 | 74 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 75 | void FailsafeControl::start(void) |
| jmarkel44 | 250:1cd8ec63e9e9 | 76 | { |
| jmarkel44 | 250:1cd8ec63e9e9 | 77 | currentState = STATE_START; |
| jmarkel44 | 250:1cd8ec63e9e9 | 78 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 79 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 80 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 81 | // method: update |
| jmarkel44 | 252:3c9863f951b7 | 82 | // description: update the faisafe control using the FSM |
| jmarkel44 | 250:1cd8ec63e9e9 | 83 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 84 | // @param none |
| jmarkel44 | 250:1cd8ec63e9e9 | 85 | // @return none |
| jmarkel44 | 250:1cd8ec63e9e9 | 86 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 87 | void FailsafeControl::update(void) |
| jmarkel44 | 250:1cd8ec63e9e9 | 88 | { |
| jmarkel44 | 260:fe726583ba1d | 89 | switch (this->currentState) { |
| jmarkel44 | 250:1cd8ec63e9e9 | 90 | case STATE_INIT: |
| jmarkel44 | 261:4e9a588c938e | 91 | // do nothing - control must be started |
| jmarkel44 | 250:1cd8ec63e9e9 | 92 | break; |
| jmarkel44 | 250:1cd8ec63e9e9 | 93 | case STATE_START: |
| jmarkel44 | 260:fe726583ba1d | 94 | // control has been started, do some checking |
| jmarkel44 | 269:97243a7f56ba | 95 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 96 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 97 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 98 | } else if ( this->aboveHighFailsafe() ) { |
| jmarkel44 | 262:696cd48bb04a | 99 | // start high failsafe duty cycle |
| jmarkel44 | 269:97243a7f56ba | 100 | this->currentState = STATE_CONTROL_ON_HFS; |
| jmarkel44 | 262:696cd48bb04a | 101 | sendMailToOutput(ACTION_CONTROL_ON); |
| jmarkel44 | 261:4e9a588c938e | 102 | this->startHfsDutyTimer(); |
| jmarkel44 | 262:696cd48bb04a | 103 | } else if ( this->belowLowFailsafe() ) { |
| jmarkel44 | 262:696cd48bb04a | 104 | // start low failsafe duty cycle |
| jmarkel44 | 269:97243a7f56ba | 105 | this->currentState = STATE_CONTROL_ON_LFS; |
| jmarkel44 | 262:696cd48bb04a | 106 | sendMailToOutput(ACTION_CONTROL_ON); |
| jmarkel44 | 262:696cd48bb04a | 107 | this->startLfsDutyTimer(); |
| jmarkel44 | 262:696cd48bb04a | 108 | } else { |
| jmarkel44 | 260:fe726583ba1d | 109 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 252:3c9863f951b7 | 110 | } |
| jmarkel44 | 252:3c9863f951b7 | 111 | break; |
| jmarkel44 | 250:1cd8ec63e9e9 | 112 | case STATE_CONTROL_OFF: |
| jmarkel44 | 260:fe726583ba1d | 113 | // control is acting normal, within bounds |
| jmarkel44 | 269:97243a7f56ba | 114 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 115 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 116 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 117 | } else if ( this->aboveHighFailsafe() ) { |
| jmarkel44 | 262:696cd48bb04a | 118 | // restart the high failsafe duty cycle |
| jmarkel44 | 269:97243a7f56ba | 119 | this->currentState = STATE_CONTROL_ON_HFS; |
| jmarkel44 | 262:696cd48bb04a | 120 | sendMailToOutput(ACTION_CONTROL_ON); |
| jmarkel44 | 262:696cd48bb04a | 121 | this->startHfsDutyTimer(); |
| jmarkel44 | 252:3c9863f951b7 | 122 | } else if ( this->belowLowFailsafe() ) { |
| jmarkel44 | 262:696cd48bb04a | 123 | // restart the low failsafe duty cycle |
| jmarkel44 | 269:97243a7f56ba | 124 | this->currentState = STATE_CONTROL_ON_LFS; |
| jmarkel44 | 262:696cd48bb04a | 125 | sendMailToOutput(ACTION_CONTROL_ON); |
| jmarkel44 | 262:696cd48bb04a | 126 | this->startLfsDutyTimer(); |
| jmarkel44 | 252:3c9863f951b7 | 127 | } else { |
| jmarkel44 | 252:3c9863f951b7 | 128 | // do nothing |
| jmarkel44 | 252:3c9863f951b7 | 129 | } |
| jmarkel44 | 252:3c9863f951b7 | 130 | break; |
| jmarkel44 | 269:97243a7f56ba | 131 | case STATE_CONTROL_ON_LFS: |
| jmarkel44 | 260:fe726583ba1d | 132 | // control is in low-failsafe with duty cycle ON |
| jmarkel44 | 269:97243a7f56ba | 133 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 134 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 135 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 136 | } else if ( !this->belowLowFailsafe() ) { |
| jmarkel44 | 260:fe726583ba1d | 137 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 262:696cd48bb04a | 138 | this->unregisterControl(); |
| jmarkel44 | 260:fe726583ba1d | 139 | } else if ( this->dutyOnExpired() ) { |
| jmarkel44 | 269:97243a7f56ba | 140 | this->currentState = STATE_CONTROL_OFF_LFS; |
| jmarkel44 | 262:696cd48bb04a | 141 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 252:3c9863f951b7 | 142 | } else { |
| jmarkel44 | 260:fe726583ba1d | 143 | // do nothing |
| jmarkel44 | 252:3c9863f951b7 | 144 | } |
| jmarkel44 | 252:3c9863f951b7 | 145 | break; |
| jmarkel44 | 269:97243a7f56ba | 146 | case STATE_CONTROL_OFF_LFS: |
| jmarkel44 | 260:fe726583ba1d | 147 | // control is in low-failsafe with duty cycle OFF |
| jmarkel44 | 269:97243a7f56ba | 148 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 149 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 150 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 151 | } else if ( !this->belowLowFailsafe() ) { |
| jmarkel44 | 260:fe726583ba1d | 152 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 262:696cd48bb04a | 153 | this->unregisterControl(); |
| jmarkel44 | 260:fe726583ba1d | 154 | } else if ( this->dutyOffExpired() ) { |
| jmarkel44 | 269:97243a7f56ba | 155 | this->currentState = STATE_CONTROL_ON_LFS; |
| jmarkel44 | 262:696cd48bb04a | 156 | this->startLfsDutyTimer(); |
| jmarkel44 | 252:3c9863f951b7 | 157 | } else { |
| jmarkel44 | 260:fe726583ba1d | 158 | // do nothing |
| jmarkel44 | 252:3c9863f951b7 | 159 | } |
| jmarkel44 | 252:3c9863f951b7 | 160 | break; |
| jmarkel44 | 269:97243a7f56ba | 161 | case STATE_CONTROL_ON_HFS: |
| jmarkel44 | 260:fe726583ba1d | 162 | // control is in high-failsafe with duty cycle ON |
| jmarkel44 | 269:97243a7f56ba | 163 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 164 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 165 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 166 | } else if ( !this->aboveHighFailsafe() ) { |
| jmarkel44 | 260:fe726583ba1d | 167 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 262:696cd48bb04a | 168 | this->unregisterControl(); |
| jmarkel44 | 260:fe726583ba1d | 169 | } else if ( this->dutyOnExpired() ) { |
| jmarkel44 | 269:97243a7f56ba | 170 | this->currentState = STATE_CONTROL_OFF_HFS; |
| jmarkel44 | 262:696cd48bb04a | 171 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 260:fe726583ba1d | 172 | } else { |
| jmarkel44 | 260:fe726583ba1d | 173 | // do nothing |
| jmarkel44 | 252:3c9863f951b7 | 174 | } |
| jmarkel44 | 252:3c9863f951b7 | 175 | break; |
| jmarkel44 | 269:97243a7f56ba | 176 | case STATE_CONTROL_OFF_HFS: |
| jmarkel44 | 260:fe726583ba1d | 177 | // control is in high-failsafe with cuty cycle OFF |
| jmarkel44 | 269:97243a7f56ba | 178 | if ( this->sensorError() ) { |
| jmarkel44 | 269:97243a7f56ba | 179 | this->currentState = STATE_CONTROL_SENSOR_ERROR; |
| jmarkel44 | 269:97243a7f56ba | 180 | sendMailToOutput(ACTION_CONTROL_OFF); |
| jmarkel44 | 269:97243a7f56ba | 181 | } else if ( !this->aboveHighFailsafe() ) { |
| jmarkel44 | 260:fe726583ba1d | 182 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 262:696cd48bb04a | 183 | this->unregisterControl(); |
| jmarkel44 | 260:fe726583ba1d | 184 | } else if ( this->dutyOffExpired() ) { |
| jmarkel44 | 269:97243a7f56ba | 185 | this->currentState = STATE_CONTROL_ON_LFS; |
| jmarkel44 | 262:696cd48bb04a | 186 | sendMailToOutput(ACTION_CONTROL_ON); |
| jmarkel44 | 262:696cd48bb04a | 187 | this->startLfsDutyTimer(); |
| jmarkel44 | 261:4e9a588c938e | 188 | } else { |
| jmarkel44 | 260:fe726583ba1d | 189 | // do nothing |
| jmarkel44 | 252:3c9863f951b7 | 190 | } |
| jmarkel44 | 252:3c9863f951b7 | 191 | break; |
| jmarkel44 | 269:97243a7f56ba | 192 | case STATE_CONTROL_SENSOR_ERROR: |
| jmarkel44 | 269:97243a7f56ba | 193 | if ( !this->sensorError() ) { |
| jmarkel44 | 273:0373b2a15f8a | 194 | printf("\rDEBUG: UNREGISTERING THE CONTROL!\n"); |
| jmarkel44 | 269:97243a7f56ba | 195 | this->currentState = STATE_CONTROL_OFF; |
| jmarkel44 | 273:0373b2a15f8a | 196 | this->unregisterControl(); |
| jmarkel44 | 269:97243a7f56ba | 197 | } else { |
| jmarkel44 | 269:97243a7f56ba | 198 | // do nothing |
| jmarkel44 | 269:97243a7f56ba | 199 | } |
| jmarkel44 | 269:97243a7f56ba | 200 | break; |
| jmarkel44 | 250:1cd8ec63e9e9 | 201 | default: |
| jmarkel44 | 250:1cd8ec63e9e9 | 202 | break; |
| jmarkel44 | 250:1cd8ec63e9e9 | 203 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 204 | } |
| jmarkel44 | 250:1cd8ec63e9e9 | 205 | |
| jmarkel44 | 252:3c9863f951b7 | 206 | bool FailsafeControl::belowLowFailsafe(void) |
| jmarkel44 | 252:3c9863f951b7 | 207 | { |
| jmarkel44 | 252:3c9863f951b7 | 208 | // read the modbus input |
| jmarkel44 | 252:3c9863f951b7 | 209 | ModbusValue value; |
| jmarkel44 | 252:3c9863f951b7 | 210 | ModbusMasterReadRegister(input, &value); |
| jmarkel44 | 252:3c9863f951b7 | 211 | #if 0 |
| jmarkel44 | 252:3c9863f951b7 | 212 | if ( value.errflag ) { |
| jmarkel44 | 252:3c9863f951b7 | 213 | logError("%s: error reading %s:", __func__, input); |
| jmarkel44 | 252:3c9863f951b7 | 214 | return false; |
| jmarkel44 | 252:3c9863f951b7 | 215 | } |
| jmarkel44 | 252:3c9863f951b7 | 216 | #endif |
| jmarkel44 | 252:3c9863f951b7 | 217 | return ( value.value <= lfs_data.value ); |
| jmarkel44 | 252:3c9863f951b7 | 218 | } |
| jmarkel44 | 252:3c9863f951b7 | 219 | |
| jmarkel44 | 252:3c9863f951b7 | 220 | bool FailsafeControl::aboveHighFailsafe(void) |
| jmarkel44 | 252:3c9863f951b7 | 221 | { |
| jmarkel44 | 252:3c9863f951b7 | 222 | // read the modbus input |
| jmarkel44 | 252:3c9863f951b7 | 223 | ModbusValue value; |
| jmarkel44 | 252:3c9863f951b7 | 224 | ModbusMasterReadRegister(input, &value); |
| jmarkel44 | 252:3c9863f951b7 | 225 | // TODO: check the error flag |
| jmarkel44 | 252:3c9863f951b7 | 226 | #if 0 |
| jmarkel44 | 252:3c9863f951b7 | 227 | if ( value.errflag ) { |
| jmarkel44 | 252:3c9863f951b7 | 228 | logError("%s: error reading %s:", __func__, input); |
| jmarkel44 | 252:3c9863f951b7 | 229 | return false; |
| jmarkel44 | 252:3c9863f951b7 | 230 | } |
| jmarkel44 | 252:3c9863f951b7 | 231 | #endif |
| jmarkel44 | 252:3c9863f951b7 | 232 | return ( value.value >= hfs_data.value ); |
| jmarkel44 | 252:3c9863f951b7 | 233 | } |
| jmarkel44 | 252:3c9863f951b7 | 234 | |
| jmarkel44 | 261:4e9a588c938e | 235 | // |
| jmarkel44 | 261:4e9a588c938e | 236 | // method: startHfsDutyTimer |
| jmarkel44 | 261:4e9a588c938e | 237 | // description: start the high failsafe duty timer |
| jmarkel44 | 261:4e9a588c938e | 238 | // |
| jmarkel44 | 261:4e9a588c938e | 239 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 240 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 241 | // |
| jmarkel44 | 261:4e9a588c938e | 242 | void FailsafeControl::startHfsDutyTimer(void) |
| jmarkel44 | 252:3c9863f951b7 | 243 | { |
| jmarkel44 | 261:4e9a588c938e | 244 | unsigned long currentTime = time(NULL); |
| jmarkel44 | 261:4e9a588c938e | 245 | unsigned long period = hfs_data.interval * 60; |
| jmarkel44 | 261:4e9a588c938e | 246 | |
| jmarkel44 | 261:4e9a588c938e | 247 | duty_timer.offTime = currentTime + ((double)period * ((double)hfs_data.dutyCycle/100.0)); |
| jmarkel44 | 261:4e9a588c938e | 248 | duty_timer.expirationTime = currentTime + period; |
| jmarkel44 | 262:696cd48bb04a | 249 | |
| jmarkel44 | 261:4e9a588c938e | 250 | printf("\r%s: currentTime = %lu\n", __func__, currentTime); |
| jmarkel44 | 261:4e9a588c938e | 251 | printf("\r%s: off Time = %lu\n", __func__, duty_timer.offTime); |
| jmarkel44 | 261:4e9a588c938e | 252 | printf("\r%s: expiration = %lu\n", __func__, duty_timer.expirationTime); |
| jmarkel44 | 261:4e9a588c938e | 253 | } |
| jmarkel44 | 261:4e9a588c938e | 254 | |
| jmarkel44 | 261:4e9a588c938e | 255 | // |
| jmarkel44 | 261:4e9a588c938e | 256 | // method: stopHfsDutyTimer |
| jmarkel44 | 261:4e9a588c938e | 257 | // description: stop the high failsafe duty timer |
| jmarkel44 | 261:4e9a588c938e | 258 | // |
| jmarkel44 | 261:4e9a588c938e | 259 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 260 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 261 | // |
| jmarkel44 | 261:4e9a588c938e | 262 | void FailsafeControl::stopHfsDutyTimer(void) |
| jmarkel44 | 261:4e9a588c938e | 263 | { |
| jmarkel44 | 261:4e9a588c938e | 264 | printf("\r%s invoked\n", __func__); |
| jmarkel44 | 261:4e9a588c938e | 265 | memset(&duty_timer, 0, sizeof(duty_timer)); |
| jmarkel44 | 252:3c9863f951b7 | 266 | } |
| jmarkel44 | 252:3c9863f951b7 | 267 | |
| jmarkel44 | 261:4e9a588c938e | 268 | // |
| jmarkel44 | 261:4e9a588c938e | 269 | // method: startLfsDutyTimer |
| jmarkel44 | 261:4e9a588c938e | 270 | // descrption: start the low failsafe duty-timer |
| jmarkel44 | 261:4e9a588c938e | 271 | // |
| jmarkel44 | 261:4e9a588c938e | 272 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 273 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 274 | // |
| jmarkel44 | 261:4e9a588c938e | 275 | void FailsafeControl::startLfsDutyTimer(void) |
| jmarkel44 | 261:4e9a588c938e | 276 | { |
| jmarkel44 | 261:4e9a588c938e | 277 | unsigned long currentTime = time(NULL); |
| jmarkel44 | 261:4e9a588c938e | 278 | unsigned long period = lfs_data.interval * 60; |
| jmarkel44 | 261:4e9a588c938e | 279 | |
| jmarkel44 | 261:4e9a588c938e | 280 | duty_timer.offTime = (double)period * ((double)lfs_data.dutyCycle/100.0); |
| jmarkel44 | 261:4e9a588c938e | 281 | duty_timer.expirationTime = currentTime + period; |
| jmarkel44 | 261:4e9a588c938e | 282 | } |
| jmarkel44 | 261:4e9a588c938e | 283 | |
| jmarkel44 | 261:4e9a588c938e | 284 | // |
| jmarkel44 | 261:4e9a588c938e | 285 | // method: stopLfsDutyTimer |
| jmarkel44 | 261:4e9a588c938e | 286 | // description: stop the low failsafe duty-timer |
| jmarkel44 | 261:4e9a588c938e | 287 | // |
| jmarkel44 | 261:4e9a588c938e | 288 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 289 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 290 | // |
| jmarkel44 | 261:4e9a588c938e | 291 | void FailsafeControl::stopLfsDutyTimer(void) |
| jmarkel44 | 252:3c9863f951b7 | 292 | { |
| jmarkel44 | 262:696cd48bb04a | 293 | printf("\r%s invoked\n", __func__); |
| jmarkel44 | 262:696cd48bb04a | 294 | memset(&duty_timer, 0, sizeof(duty_timer)); |
| jmarkel44 | 261:4e9a588c938e | 295 | } |
| jmarkel44 | 261:4e9a588c938e | 296 | |
| jmarkel44 | 261:4e9a588c938e | 297 | // |
| jmarkel44 | 261:4e9a588c938e | 298 | // method: dutyOnExpired |
| jmarkel44 | 261:4e9a588c938e | 299 | // description: returns true if ON cycle has expired; false otherwise |
| jmarkel44 | 261:4e9a588c938e | 300 | // |
| jmarkel44 | 261:4e9a588c938e | 301 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 302 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 303 | // |
| jmarkel44 | 261:4e9a588c938e | 304 | bool FailsafeControl::dutyOnExpired(void) |
| jmarkel44 | 261:4e9a588c938e | 305 | { |
| jmarkel44 | 261:4e9a588c938e | 306 | return (duty_timer.offTime < time(NULL)); |
| jmarkel44 | 261:4e9a588c938e | 307 | } |
| jmarkel44 | 261:4e9a588c938e | 308 | |
| jmarkel44 | 261:4e9a588c938e | 309 | // |
| jmarkel44 | 261:4e9a588c938e | 310 | // method: dutyOffExpired |
| jmarkel44 | 261:4e9a588c938e | 311 | // description: returns true if OFF cycle has expired; false otherwise |
| jmarkel44 | 261:4e9a588c938e | 312 | // |
| jmarkel44 | 261:4e9a588c938e | 313 | // @param none |
| jmarkel44 | 261:4e9a588c938e | 314 | // @return none |
| jmarkel44 | 261:4e9a588c938e | 315 | // |
| jmarkel44 | 261:4e9a588c938e | 316 | bool FailsafeControl::dutyOffExpired(void) |
| jmarkel44 | 261:4e9a588c938e | 317 | { |
| jmarkel44 | 262:696cd48bb04a | 318 | return (duty_timer.expirationTime < time(NULL)); |
| jmarkel44 | 252:3c9863f951b7 | 319 | } |
| jmarkel44 | 252:3c9863f951b7 | 320 | |
| jmarkel44 | 252:3c9863f951b7 | 321 | // |
| jmarkel44 | 260:fe726583ba1d | 322 | // method: sendMailToOutput |
| jmarkel44 | 252:3c9863f951b7 | 323 | // description: send mail to the output task |
| jmarkel44 | 252:3c9863f951b7 | 324 | // |
| jmarkel44 | 252:3c9863f951b7 | 325 | // @param io_tag -> input/output tag |
| jmarkel44 | 252:3c9863f951b7 | 326 | // @param action -> ON, OFF, UNREGISTER |
| jmarkel44 | 252:3c9863f951b7 | 327 | // @return none |
| jmarkel44 | 252:3c9863f951b7 | 328 | // |
| jmarkel44 | 260:fe726583ba1d | 329 | void FailsafeControl::sendMailToOutput(OutputAction action) |
| jmarkel44 | 252:3c9863f951b7 | 330 | { |
| jmarkel44 | 252:3c9863f951b7 | 331 | logInfo("%s: failsafe control attempting to send action %d\n", |
| jmarkel44 | 252:3c9863f951b7 | 332 | __func__, action); |
| jmarkel44 | 252:3c9863f951b7 | 333 | |
| jmarkel44 | 252:3c9863f951b7 | 334 | OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); |
| jmarkel44 | 252:3c9863f951b7 | 335 | memset(output_mail, 0, sizeof(OutputControlMsg_t)); |
| jmarkel44 | 252:3c9863f951b7 | 336 | |
| jmarkel44 | 252:3c9863f951b7 | 337 | output_mail->action = action; |
| jmarkel44 | 252:3c9863f951b7 | 338 | output_mail->controlType = CONTROL_FAILSAFE; |
| jmarkel44 | 252:3c9863f951b7 | 339 | output_mail->priority = this->priority; |
| jmarkel44 | 252:3c9863f951b7 | 340 | |
| jmarkel44 | 252:3c9863f951b7 | 341 | strncpy(output_mail->input_tag, this->input.c_str(), sizeof(output_mail->input_tag)-1); |
| jmarkel44 | 252:3c9863f951b7 | 342 | strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1); |
| jmarkel44 | 252:3c9863f951b7 | 343 | strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); |
| jmarkel44 | 252:3c9863f951b7 | 344 | |
| jmarkel44 | 252:3c9863f951b7 | 345 | OutputMasterMailBox.put(output_mail); |
| jmarkel44 | 252:3c9863f951b7 | 346 | } |
| jmarkel44 | 252:3c9863f951b7 | 347 | |
| jmarkel44 | 269:97243a7f56ba | 348 | // |
| jmarkel44 | 269:97243a7f56ba | 349 | // method: sensorError |
| jmarkel44 | 269:97243a7f56ba | 350 | // description: return true if a sensor's error flag it set |
| jmarkel44 | 269:97243a7f56ba | 351 | // |
| jmarkel44 | 269:97243a7f56ba | 352 | // @param[in] none |
| jmarkel44 | 269:97243a7f56ba | 353 | // @param[out] none |
| jmarkel44 | 269:97243a7f56ba | 354 | // @return true if sensor error |
| jmarkel44 | 269:97243a7f56ba | 355 | // |
| jmarkel44 | 269:97243a7f56ba | 356 | bool FailsafeControl::sensorError(void) |
| jmarkel44 | 269:97243a7f56ba | 357 | { |
| jmarkel44 | 269:97243a7f56ba | 358 | ModbusValue value; |
| jmarkel44 | 269:97243a7f56ba | 359 | ModbusMasterReadRegister(input, &value); |
| jmarkel44 | 273:0373b2a15f8a | 360 | |
| jmarkel44 | 269:97243a7f56ba | 361 | if ( value.errflag ) { |
| jmarkel44 | 269:97243a7f56ba | 362 | logInfo("%s: %s is in error\n", __func__, input.c_str()); |
| jmarkel44 | 269:97243a7f56ba | 363 | return true; |
| jmarkel44 | 269:97243a7f56ba | 364 | } |
| jmarkel44 | 269:97243a7f56ba | 365 | return false; |
| jmarkel44 | 269:97243a7f56ba | 366 | } |
| jmarkel44 | 269:97243a7f56ba | 367 | |
| jmarkel44 | 252:3c9863f951b7 | 368 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 369 | // |
| jmarkel44 | 260:fe726583ba1d | 370 | // method: unregisterControl |
| jmarkel44 | 260:fe726583ba1d | 371 | // description: unregister this control with the output task |
| jmarkel44 | 260:fe726583ba1d | 372 | // |
| jmarkel44 | 260:fe726583ba1d | 373 | // @param none |
| jmarkel44 | 260:fe726583ba1d | 374 | // @return none |
| jmarkel44 | 260:fe726583ba1d | 375 | // |
| jmarkel44 | 260:fe726583ba1d | 376 | void FailsafeControl::unregisterControl(void) |
| jmarkel44 | 260:fe726583ba1d | 377 | { |
| jmarkel44 | 260:fe726583ba1d | 378 | logInfo("%s: %s attempting to unregister %s\n", |
| jmarkel44 | 260:fe726583ba1d | 379 | __func__, controlFile.c_str()); |
| jmarkel44 | 260:fe726583ba1d | 380 | |
| jmarkel44 | 260:fe726583ba1d | 381 | OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc(); |
| jmarkel44 | 260:fe726583ba1d | 382 | memset(output_mail, 0, sizeof(OutputControlMsg_t)); |
| jmarkel44 | 260:fe726583ba1d | 383 | |
| jmarkel44 | 260:fe726583ba1d | 384 | output_mail->action = ACTION_CONTROL_UNREGISTER; |
| jmarkel44 | 260:fe726583ba1d | 385 | output_mail->controlType = CONTROL_FAILSAFE; |
| jmarkel44 | 260:fe726583ba1d | 386 | output_mail->priority = this->priority; |
| jmarkel44 | 260:fe726583ba1d | 387 | strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1); |
| jmarkel44 | 260:fe726583ba1d | 388 | strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1); |
| jmarkel44 | 260:fe726583ba1d | 389 | |
| jmarkel44 | 260:fe726583ba1d | 390 | OutputMasterMailBox.put(output_mail); |
| jmarkel44 | 260:fe726583ba1d | 391 | } |
| jmarkel44 | 260:fe726583ba1d | 392 | |
| jmarkel44 | 260:fe726583ba1d | 393 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 394 | // method: display |
| jmarkel44 | 250:1cd8ec63e9e9 | 395 | // description: display the pertinents |
| jmarkel44 | 250:1cd8ec63e9e9 | 396 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 397 | // @param none |
| jmarkel44 | 250:1cd8ec63e9e9 | 398 | // @return none |
| jmarkel44 | 250:1cd8ec63e9e9 | 399 | // |
| jmarkel44 | 250:1cd8ec63e9e9 | 400 | void FailsafeControl::display(void) |
| jmarkel44 | 250:1cd8ec63e9e9 | 401 | { |
| jmarkel44 | 250:1cd8ec63e9e9 | 402 | const char *mapper[] = { "INIT", |
| jmarkel44 | 250:1cd8ec63e9e9 | 403 | "START", |
| jmarkel44 | 269:97243a7f56ba | 404 | "OFF", |
| jmarkel44 | 269:97243a7f56ba | 405 | "ON_LFS", |
| jmarkel44 | 269:97243a7f56ba | 406 | "OFF_LFS", |
| jmarkel44 | 269:97243a7f56ba | 407 | "ON_HFS", |
| jmarkel44 | 269:97243a7f56ba | 408 | "OFF_HFS", |
| jmarkel44 | 269:97243a7f56ba | 409 | "SENSOR_ERR", |
| jmarkel44 | 250:1cd8ec63e9e9 | 410 | "invalid" |
| jmarkel44 | 250:1cd8ec63e9e9 | 411 | }; |
| jmarkel44 | 250:1cd8ec63e9e9 | 412 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 413 | printf("\r\n"); |
| jmarkel44 | 250:1cd8ec63e9e9 | 414 | std::cout << left << setw(10) << setfill(' ') << "failsafe: "; |
| jmarkel44 | 253:ae850c19cf81 | 415 | std::cout << left << setw(40) << setfill(' ') << controlFile; |
| jmarkel44 | 250:1cd8ec63e9e9 | 416 | std::cout << left << setw(20) << setfill(' ') << id; |
| jmarkel44 | 250:1cd8ec63e9e9 | 417 | std::cout << left << setw(6) << setfill(' ') << priority; |
| jmarkel44 | 250:1cd8ec63e9e9 | 418 | std::cout << left << setw(20) << setfill(' ') << input; |
| jmarkel44 | 250:1cd8ec63e9e9 | 419 | std::cout << left << setw(20) << setfill(' ') << output; |
| jmarkel44 | 250:1cd8ec63e9e9 | 420 | std::cout << left << setw(16) << setfill(' ') << mapper[currentState]; |
| jmarkel44 | 252:3c9863f951b7 | 421 | std::cout << left << setw(12) << setfill(' ') << "lfs-> " |
| jmarkel44 | 252:3c9863f951b7 | 422 | << lfs_data.value << ":" << lfs_data.dutyCycle << ":" << lfs_data.interval; |
| jmarkel44 | 252:3c9863f951b7 | 423 | std::cout << right << setw(12) << setfill(' ') << "hfs-> " |
| jmarkel44 | 252:3c9863f951b7 | 424 | << hfs_data.value << ":" << hfs_data.dutyCycle << ":" << hfs_data.interval; |
| jmarkel44 | 250:1cd8ec63e9e9 | 425 | |
| jmarkel44 | 250:1cd8ec63e9e9 | 426 | std::cout.flush(); |
| jmarkel44 | 252:3c9863f951b7 | 427 | } |
