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.
Functions.cpp
00001 #include <string> 00002 #include "main.h" 00003 #include "Functions.h" 00004 #include "Definitions.h" 00005 #include "Boolean.h" 00006 #include "NextionLCD.h" 00007 #include "mbed_debug.h" 00008 #include "mbed.h" 00009 #include "Languages.h" 00010 #include "Ser25lcxxx.h" 00011 #include "NVM.h" 00012 #include "Watchdog.h" 00013 #include "NextionPages.h" 00014 #include "Controls.h" 00015 #include "Threads.h" 00016 #include "ISR.h" 00017 #include "FastPWM.h" 00018 00019 /////////////////////////////////////////////////////////////////////////////// 00020 // MBED OBJECTS 00021 /////////////////////////////////////////////////////////////////////////////// 00022 extern NextionLCD lcd;//Tx, Rx, Nextion Port 00023 00024 Thread thread; 00025 volatile uint16_t loopTime = 0; 00026 volatile bool loopTimeFlag = false; 00027 volatile bool readFlag = false; 00028 00029 /////////////////////////////////////////////////////////////////////////////// 00030 // VARIABLES 00031 /////////////////////////////////////////////////////////////////////////////// 00032 bool incFlag = false; 00033 bool decFlag = false; 00034 bool okFlag = false; 00035 bool manFlag = false; 00036 00037 uint8_t pumpType = QDOS_30; 00038 uint8_t calState = ZERO; 00039 00040 /////////////////////////////////////////////////////////////////////////////// 00041 // THREADS 00042 /////////////////////////////////////////////////////////////////////////////// 00043 void loopTime_thread(){ 00044 00045 while(1){ 00046 #ifdef LOOP_TIME 00047 if(readFlag){ 00048 pc.printf("\r\n\r\n Loop Time \t= %d us",loopTime); 00049 readFlag = false; 00050 loopTimeFlag = true; 00051 } 00052 #endif 00053 } 00054 } 00055 00056 void loopTimeMeasure(void){ 00057 00058 #ifdef LOOP_TIME 00059 if(!loopTimeFlag){ 00060 //wait_us(20);//add a known time to verify the accuracy of the loop timer 00061 tSec.stop(); 00062 loopTime = tSec.read_us(); 00063 //run_stat_out_oc = 1; 00064 readFlag = true; 00065 } 00066 else{ 00067 tSec.reset(); 00068 tSec.start(); 00069 loopTimeFlag = false; 00070 //run_stat_out_oc = 0; 00071 } 00072 #endif 00073 } 00074 00075 /////////////////////////////////////////////////////////////////////////////// 00076 // ARRAYS 00077 /////////////////////////////////////////////////////////////////////////////// 00078 char buffer[20]; 00079 00080 const uint8_t uOutPut1_ID[7] = { 00081 OUT1_GENERAL_ALARM, 00082 OUT1_RUN_STATUS, 00083 OUT1_MANUAL_MODE, 00084 OUT1_ANALOGUE_MODE, 00085 OUT1_CONTACT_MODE, 00086 OUT1_FLUID_LEVEL, 00087 OUT1_LEAK_DETECT 00088 }; 00089 00090 const uint8_t uOutPut2_ID[7] = { 00091 OUT2_GENERAL_ALARM, 00092 OUT2_RUN_STATUS, 00093 OUT2_MANUAL_MODE, 00094 OUT2_ANALOGUE_MODE, 00095 OUT2_CONTACT_MODE, 00096 OUT2_FLUID_LEVEL, 00097 OUT2_LEAK_DETECT 00098 }; 00099 00100 const uint8_t uFlowUnitID[10] = { 00101 PERCENT, 00102 GPD, 00103 GPH, 00104 ML_HR, 00105 ML_MIN, 00106 L_DAY, 00107 L_HR, 00108 L_MIN, 00109 OZ_MIN, 00110 RPM 00111 }; 00112 00113 const string menuStringArray[3][10] = {//[Group][Item], 2 groups, 10 items in each group i.e menuItems[1][6]= "Leak Detect" 00114 "%\0", //0x10 00115 "gpd\0", //0x11 00116 "gph\0", //0x12 00117 "ml/hr\0", //0x13 00118 "ml/min\0", //0x14 00119 "l/day\0", //0x15 00120 "l/hr\0", //0x16 00121 "l/min\0", //0x17 00122 "oz/min\0", //0x18 00123 "RPM\0", //0x19 00124 00125 "General Alarm\0", 00126 "Run Status\0", 00127 "Manual Mode\0", 00128 "Analogue Mode\0", 00129 "Contact Mode\0", 00130 "Fluid Level\0", 00131 "Leak Detect\0", 00132 "A1\0", 00133 "B1\0", 00134 "C1\0", 00135 00136 "General Alarm\0", 00137 "Run Status\0", 00138 "Manual Mode\0", 00139 "Analogue Mode\0", 00140 "Contact Mode\0", 00141 "Fluid Level\0", 00142 "Leak Detect\0", 00143 "A2\0", 00144 "B2\0", 00145 "C2\0" 00146 }; 00147 00148 const float fMaxFlowUnits[5][10] = { 00149 00150 //QDOS 30 00151 100.0,//% 00152 190.2,//gpd 00153 7.925,//gph 00154 30.00,//l/hr 00155 500.0,//ml/min 00156 720.0,//l/day 00157 30.00,//l/hr 00158 0.500,//l/min 00159 17.6,//oz 00160 125.0,//rpm 00161 00162 //VDOS 20 00163 100.0, 00164 131.06, 00165 5.46, 00166 20670.00, 00167 344.50, 00168 496.08, 00169 20.67, 00170 0.34, 00171 12.15, 00172 65.0, 00173 00174 //VDOS 30 00175 100.0, 00176 191.56, 00177 7.98, 00178 30210.00, 00179 503.50, 00180 725.04, 00181 30.21, 00182 0.50, 00183 17.76, 00184 95.00, 00185 00186 //VDOS 60 00187 100.0, 00188 380.83, 00189 15.87, 00190 60060.00, 00191 1001.00, 00192 1441.44, 00193 60.06, 00194 1.00, 00195 35.31, 00196 110.00, 00197 00198 //VDOS 120 00199 100.0, 00200 765.62, 00201 31.90, 00202 120744.00, 00203 2012.40, 00204 2897.86, 00205 120.74, 00206 2.01, 00207 70.98, 00208 129.00 00209 }; 00210 00211 const float fMinFlowUnits[5][10] = { 00212 00213 //QDOS 30 00214 0.1,//% 00215 0.1,//gpd 00216 0.001,//gph 00217 1.0,//ml/hr 00218 0.1,//ml/min 00219 0.1,//l/day 00220 0.01,//l/hr 00221 0.001,//l/min 00222 0.1,//oz 00223 0.1,//rpm 00224 00225 //VDOS 20 00226 0.2, 00227 0.26, 00228 0.01, 00229 41.34, 00230 0.87, 00231 0.99, 00232 0.04, 00233 0.00, 00234 0.02, 00235 5.0, 00236 00237 //VDOS 30 00238 0.2, 00239 0.38, 00240 0.02, 00241 60.42, 00242 1.01, 00243 1.45, 00244 0.06, 00245 0.00, 00246 0.04, 00247 5.0, 00248 00249 //VDOS 60 00250 0.2, 00251 0.76, 00252 0.03, 00253 120.12, 00254 2.0, 00255 2.88, 00256 0.16, 00257 0.00, 00258 0.07, 00259 5.0, 00260 00261 //VDOS 120 00262 0.2, 00263 1.53, 00264 0.06, 00265 241.49, 00266 4.02, 00267 5.80, 00268 0.24, 00269 0.00, 00270 0.14, 00271 5.0 00272 }; 00273 00274 00275 /////////////////////////////////////////////////////////////////////////////// 00276 // FUNCTIONS 00277 /////////////////////////////////////////////////////////////////////////////// 00278 void sysInit(void){ 00279 00280 wait(0.250);//settle time 00281 00282 pc.baud(MED_BAUD);//Debug Port 00283 usart6.baud(MED_BAUD);//Motor Controller Port 00284 00285 led1=ON; 00286 led2=ON; 00287 led3=ON; 00288 wait(2.00); 00289 led1=OFF; 00290 led2=OFF; 00291 led3=OFF; 00292 00293 nexInit(MED_BAUD); 00294 reset(); 00295 00296 //4-20mA Control Outputs 00297 alarmOut1 = OFF; 00298 alarmOut2 = OFF; 00299 00300 initNVM();//Initialise the NVM memory 00301 loadNVM(&nvm,0);//loads EEPROM content to nvm data structure 00302 00303 nvm.pumpOnOff = PUMP_OFF; 00304 writeNVMByte(PUMP_ON_OFF,nvm.pumpOnOff); 00305 00306 nvm.speedLimit = 125.0; 00307 writeNVMfloat(NVM_SPEED_LIMIT,nvm.speedLimit); 00308 00309 #ifdef DEBUG_NVM 00310 00311 pc.printf("\r\n\r\n HARDWARE \t\t= %s", HARDWARE.c_str()); 00312 pc.printf("\r\n\r\n SOFTWARE \t\t= %s",SOFTWARE.c_str()); 00313 pc.printf("\r\n\r\n AUTHOR \t\t= %s",AUTHOR.c_str()); 00314 pc.printf("\r\n\r\n DATE \t\t\t= %s",__DATE__); 00315 pc.printf("\r\n\r\n TIME \t\t\t= %s",__TIME__); 00316 pc.printf("\r\n\r\n ADC Samples \t\t= %d", ADC_SAMPLES); 00317 pc.printf("\r\n\r\n SPI Freq \t\t= %d(Hz)", SPI_FREQ); 00318 pc.printf("\r\n\r\n Watchdog \t\t= %.1f(Seconds)", WDT); 00319 pc.printf("\r\n\r\n Flow Unit\t\t= 0x%X", nvm.flowUnits); 00320 pc.printf("\r\n\r\n Run Mode\t\t= 0x%X", nvm.runMode); 00321 pc.printf("\r\n\r\n Auto Restart\t\t= 0x%X", nvm.autoRestart); 00322 pc.printf("\r\n\r\n Pump Head\t\t= 0x%X", nvm.pumpHeadStatus); 00323 pc.printf("\r\n\r\n Alarm\t\t\t= 0x%X", nvm.alarm); 00324 pc.printf("\r\n\r\n Head Side\t\t= 0x%X", nvm.headSide); 00325 pc.printf("\r\n\r\n Pump On/Off\t\t= 0x%X", nvm.pumpOnOff); 00326 pc.printf("\r\n\r\n Speed Limit Val\t= %.2f", nvm.speedLimit); 00327 pc.printf("\r\n\r\n Flow Unit Val\t\t= %.2f", nvm.flowUnitVal); 00328 pc.printf("\r\n\r\n Analogue Cal mA Low\t= %.2f(mA)", nvm.mA_low); 00329 pc.printf("\r\n\r\n Analogue Cal mA High\t= %.2f(mA)", nvm.mA_high); 00330 pc.printf("\r\n\r\n Analogue Cal Flow Low\t= %.2f(%%)", nvm.flow_low); 00331 pc.printf("\r\n\r\n Analogue Cal Flow High\t= %.2f(%%)", nvm.flow_high); 00332 pc.printf("\r\n\r\n ADC min V\t\t= %.2f(V)", nvm.adc_min_v); 00333 pc.printf("\r\n\r\n ADC max V\t\t= %.2f(V)", nvm.adc_max_v); 00334 pc.printf("\r\n\r\n DAC V low factor\t= %f", nvm.dac_v_low); 00335 pc.printf("\r\n\r\n DAC V high factor\t= %f", nvm.dac_v_high); 00336 pc.printf("\r\n\r\n DAC V low \t\t= %.2f(V)", nvm.dac_v_low*VDD); 00337 pc.printf("\r\n\r\n DAC V high \t\t= %.2f(V)", nvm.dac_v_high*VDD); 00338 pc.printf("\r\n\r\n Remote Stop Pump Input = 0x%X", nvm.rmtStopPump); 00339 pc.printf("\r\n\r\n Output 1\t\t= 0x%X", nvm.outPut1); 00340 pc.printf("\r\n\r\n Output 1 Logic \t= 0x%X", nvm.outPut1Logic); 00341 pc.printf("\r\n\r\n Output 2\t\t= 0x%X", nvm.outPut2); 00342 pc.printf("\r\n\r\n Output 2 Logic \t= 0x%X", nvm.outPut2Logic); 00343 pc.printf("\r\n\r\n 4-20mA Output\t\t= 0x%X", nvm._4_20mAoutPut); 00344 00345 usart6.printf("\r\n\r\n Motor Controller Active"); 00346 00347 #endif 00348 00349 //pumpType = VDOS_120; 00350 pumpType = QDOS_30; 00351 00352 //tachoIn.rise(&isr1); 00353 00354 motor(MOTOR_RPM_MIN, CW, BRAKE_OFF, MOTOR_DISABLE, 100); 00355 00356 anaOut_mA(I_3MA);//analogue output forced to 3mA 00357 00358 wd.Configure(WDT); // sets the timeout 00359 00360 thread.start(callback(loopTime_thread)); 00361 } 00362 00363 void nexInit(uint32_t baud){ 00364 00365 /* Set the baudrate which is for debug and communicate with Nextion screen. */ 00366 00367 nexPwrCont = ON;//Nextion power is on 00368 wait(0.25); 00369 lcd.nexSetBaud(baud);//Set Nextion baud 00370 lcd.nexSetBckLite(100);//program backlight to be off at power up 00371 } 00372 00373 float motorRPM(void){ 00374 static float rpm = 0.1; 00375 //static float flowUnits = 0.1; 00376 00377 rpm = mapF(nvm.flowUnitVal, minScale, maxScale, 0, fMaxFlowUnits[pumpType][9]); 00378 00379 //flowUnits = mapF(rpm,0.1,125.0,minScale,maxScale); 00380 00381 //return(flowUnits); 00382 return(rpm); 00383 } 00384 00385 float incDecControl(float *val, float precision, float min, float max, float speedLimit){ 00386 00387 static bool incMode = false; 00388 static bool decMode = false; 00389 static float speed = SLOW_SPEED; 00390 00391 if(motorRPM() < speedLimit){ 00392 00393 if(*val < max){ 00394 if((tPush.read() > START_DELAY)&&(incMode)){//INC button pressed > 0.5 seconds, speed set to fast update 00395 00396 if(tSpeed.read() > speed){//fast and then slow after 4 seconds 00397 tSpeed.reset(); 00398 00399 if(tPush.read() > DELAY_LONG){//INC button pressed > 4 seconds, now set speed to slow update 00400 tPush.stop(); 00401 speed = FAST_SPEED; 00402 } 00403 *val+=flowUnitPrec(precision-1); 00404 } 00405 } 00406 else//INC button released 00407 if(incFlag){ 00408 incFlag = false; 00409 incMode = true; 00410 decMode = false; 00411 speed = SLOW_SPEED; 00412 *val+=flowUnitPrec(precision);//Inc 0.1 00413 } 00414 if(*val > max) 00415 *val = max; 00416 } 00417 } 00418 else 00419 if(motorRPM() > speedLimit) 00420 *val-=0.1; 00421 00422 if(*val > min){ 00423 00424 if((tPush.read() > START_DELAY)&&(decMode)){ 00425 00426 if(tSpeed.read() > speed){//fast and then slow after 4 seconds 00427 tSpeed.reset(); 00428 00429 if(tPush.read() > DELAY_LONG){//INC button pressed > 4 seconds, now set speed to slow update 00430 tPush.stop(); 00431 speed = FAST_SPEED; 00432 } 00433 *val-=flowUnitPrec(precision-1); 00434 } 00435 } 00436 else 00437 if(decFlag){ 00438 decFlag = false; 00439 decMode = true; 00440 incMode = false; 00441 speed = SLOW_SPEED; 00442 *val-=flowUnitPrec(precision);//Dec 0.1 00443 } 00444 if(*val < min)//catch fix 00445 *val = min; 00446 00447 } 00448 return(mapF(*val, 0.0, max, 0.0, 100.0));//return percentage multiplier 00449 } 00450 00451 long mapI(long x, long in_min, long in_max, long out_min, long out_max){ 00452 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 00453 } 00454 00455 float mapF(float in, float inMin, float inMax, float outMin, float outMax) { 00456 // check it's within the range 00457 if (inMin<inMax) { 00458 if (in <= inMin) 00459 return outMin; 00460 if (in >= inMax) 00461 return outMax; 00462 } else { // cope with input range being backwards. 00463 if (in >= inMin) 00464 return outMin; 00465 if (in <= inMax) 00466 return outMax; 00467 } 00468 // calculate how far into the range we are 00469 float scale = (in-inMin)/(inMax-inMin); 00470 // calculate the output. 00471 return outMin + scale*(outMax-outMin); 00472 } 00473 00474 void diags(void){ 00475 pc.printf("////////////////////////////////////////////////////////////////////////////////\r\n"); 00476 pc.printf("//Neptune Diagnostics\r\n"); 00477 pc.printf("////////////////////////////////////////////////////////////////////////////////\r\n"); 00478 } 00479 00480 uint8_t decodeByteNVM(uint8_t nvmByte, uint8_t *prec){ 00481 /* 00482 Decode Byte from NVM 00483 00484 Function decodes nvm byte and displays and:- 00485 * Displays the approriate string for the passed nvm byte 00486 * Sets the flow unit precision when nvm byte is a flow unit 00487 * Sets the min and max scale when nvm bytes is a flow unit 00488 */ 00489 uint8_t list = 0; 00490 uint8_t i = ZERO; 00491 bool error = false; 00492 00493 switch(nvmByte){ 00494 00495 case OUT1_GENERAL_ALARM: 00496 case OUT1_RUN_STATUS: 00497 case OUT1_MANUAL_MODE: 00498 case OUT1_ANALOGUE_MODE: 00499 case OUT1_CONTACT_MODE: 00500 case OUT1_FLUID_LEVEL: 00501 case OUT1_LEAK_DETECT: list = OUTPUT1_LIST; break; 00502 00503 case OUT2_GENERAL_ALARM: 00504 case OUT2_RUN_STATUS: 00505 case OUT2_MANUAL_MODE: 00506 case OUT2_ANALOGUE_MODE: 00507 case OUT2_CONTACT_MODE: 00508 case OUT2_FLUID_LEVEL: 00509 case OUT2_LEAK_DETECT: list = OUTPUT2_LIST; break; 00510 00511 case PERCENT: 00512 case GPD: 00513 case ML_MIN: 00514 case L_DAY: 00515 case OZ_MIN: 00516 case RPM: *prec = 1; break; 00517 00518 case ML_HR: 00519 case L_HR: *prec = 2; break; 00520 00521 case GPH: 00522 case L_MIN: *prec = 3; break; 00523 00524 default: pc.printf("Error flowUnitsNVM : Last case %d", nvmByte); 00525 error = true; 00526 } 00527 00528 if(!error){ 00529 i = ReadListIndexNVM(nvmByte); 00530 00531 minScale = fMinFlowUnits[pumpType][i]; 00532 maxScale = fMaxFlowUnits[pumpType][i];//float, max flow unit range 00533 00534 lcd.nexSendFloat("p1right",maxScale, 2);//page 1 right text box 00535 lcd.nexSendTxt("units", menuStringArray[list][i]); 00536 } 00537 00538 return(i); 00539 } 00540 00541 uint8_t ReadListIndexNVM(uint8_t nvm){ 00542 /* 00543 return the list item index 00544 */ 00545 return(0x0f&nvm); 00546 } 00547 00548 float flowUnitPrec(int8_t precision){ 00549 /* 00550 precision = number of decimal places, 1, 2 & 3 00551 returns a float used to Inc/Dec flow units 00552 00553 100.0, 00554 139.6, 00555 5.815, 00556 22.01, 00557 366.9, 00558 528.2, 00559 22.01, 00560 0.367, 00561 12.9, 00562 55.0, 00563 */ 00564 00565 float precisionVal; 00566 00567 switch(precision){ 00568 case -1: precisionVal = 10; break; 00569 case 0: precisionVal = 1; break; 00570 case 1: precisionVal = 0.1; break; 00571 case 2: precisionVal = 0.01; break; 00572 case 3: precisionVal = 0.001; break; 00573 default:pc.printf("Error incDec : Last case %d",precision); 00574 } 00575 return(precisionVal); 00576 } 00577 00578 float low_pass_filterF(float x) { 00579 00580 //https://www.eevblog.com/forum/beginners/averaging-or-smoothing-adc-values/ 00581 00582 static float samples[ADC_SAMPLES]; 00583 static int i = ZERO; 00584 static float total = ZERO; 00585 00586 /* Update the moving average */ 00587 total += x - samples[i]; 00588 samples[i] = x; 00589 00590 /* Update the index */ 00591 i = (i==(ADC_SAMPLES-1) ? 0 : i+1); 00592 00593 return total/ADC_SAMPLES; 00594 } 00595 00596 uint8_t runModeNVM(uint8_t settingIndex){ 00597 uint8_t task; 00598 /* 00599 Converts EEPROM setting to state machine case setting 00600 00601 */ 00602 switch(settingIndex) 00603 { 00604 case MANUAL: task = MANUAL_SET; break; 00605 case ANALOGUE: task = ANALOGUE_SET; break; 00606 case CONTACT: task = CONTACT_SET; break; 00607 case FLUID_REC: task = FLUIDREC_SET; break; 00608 case FLOW_CAL: task = FLOW_CAL_SET; break; 00609 default: pc.printf("Error runModeNVM : Last case %d",settingIndex); 00610 } 00611 return(task); 00612 } 00613 00614 void dbgStates(uint8_t state){ 00615 00616 #ifdef DEBUG_STATES 00617 00618 static uint8_t lastState = INITIALISE; 00619 00620 if(state != lastState){ 00621 switch(state){ 00622 case INITIALISE: pc.printf("\r\nSTATE = INITIALISE"); break; 00623 case START: pc.printf("\r\nSTATE = START"); break; 00624 case STOP: pc.printf("\r\nSTATE = STOP"); break; 00625 case STOP_SCRN: pc.printf("\r\nSTATE = STOP_SCRN"); break; 00626 case RUNNING: pc.printf("\r\nSTATE = RUNNING"); break; 00627 case ANALOGUE_SET: pc.printf("\r\nSTATE = ANALOGUE_SET"); break; 00628 case DOSE: pc.printf("\r\nSTATE = DOSE"); break; 00629 case MANUAL_SET: pc.printf("\r\nSTATE = MANUAL_SET"); break; 00630 case PROFIBUS: pc.printf("\r\nSTATE = PROFIBUS"); break; 00631 case STALL: pc.printf("\r\nSTATE = STALL"); break; 00632 case DEBUG: pc.printf("\r\nSTATE = DEBUG"); break; 00633 case DIAGS: pc.printf("\r\nSTATE = DIAGS"); break; 00634 case ALARM: pc.printf("\r\nSTATE = ALARM"); break; 00635 case FAULT: pc.printf("\r\nSTATE = FAULT"); break; 00636 case READ_KEYS: pc.printf("\r\nSTATE = READ_KEYS"); break; 00637 case MANUAL_MODE: pc.printf("\r\nSTATE = MANUAL_MODE"); break; 00638 case ANALOGUE_MODE: pc.printf("\r\nSTATE = ANALOGUE_MODE"); break; 00639 case PROFIBUS_MODE: pc.printf("\r\nSTATE = PROFIBUS_MODE"); break; 00640 case CONTACT_SET: pc.printf("\r\nSTATE = CONTACT_SET"); break; 00641 case FLUIDREC_SET: pc.printf("\r\nSTATE = FLUIDREC_SET"); break; 00642 case READ_NVM: pc.printf("\r\nSTATE = READ_NVM"); break; 00643 case RESET_VARS: pc.printf("\r\nSTATE = RESET_VARS"); break; 00644 case ANA_CAL: pc.printf("\r\nSTATE = ANA_CAL"); break; 00645 case REMOTE_IN: pc.printf("\r\nSTATE = REMOTE_IN"); break; 00646 00647 default: pc.printf("\r\nSTATE = UNDEFINED"); 00648 } 00649 00650 lastState = state; 00651 } 00652 00653 #endif 00654 } 00655 00656 uint8_t touchBtn(uint8_t nexPage, uint8_t nexBtn, uint8_t nexPushPop){ 00657 /* 00658 Function returns true if the button matches input parameters 00659 */ 00660 00661 uint8_t state = false; 00662 00663 if((page == nexPage)&&(id == nexBtn)&&(pushPop == nexPushPop)) 00664 state = true; 00665 00666 return(state); 00667 } 00668 00669 uint8_t anaCal(void){ 00670 00671 char* buffer; 00672 float tmp; 00673 bool drawCompleted = false; 00674 uint8_t task = ANA_CAL; 00675 00676 switch(calState){ 00677 00678 case CAL1_SCRN: 00679 if(scrnUpdate){ 00680 scrnUpdate = false; 00681 00682 lcd.nexSendTxt("title","4-20mA Calibration 1/4"); 00683 lcd.nexSendTxt("info2","signal"); 00684 lcd.nexSendTxt("sigName","Signal High"); 00685 lcd.nexSendTxt("t1","mA"); 00686 00687 if(manFlag){ 00688 lcd.nexSendTxt("info1","Enter HIGH"); 00689 lcd.nexSendTxt("info2","signal"); 00690 lcd.nexSendTxt("info3","using +/- keys"); 00691 } 00692 else 00693 { 00694 lcd.nexSendTxt("info1","Apply HIGH"); 00695 lcd.nexSendTxt("info2","signal"); 00696 } 00697 00698 lcd.nexSendTxt("info4","then press OK"); 00699 lcd.nexSendTxt("info5",""); 00700 } 00701 00702 if(manFlag) 00703 incDecControl(&nvm.mA_high, 2, LOW_CAL_MIN, HIGH_CAL_MAX, nvm.speedLimit);//2 decimal places for mA 00704 else 00705 nvm.mA_high = anaIn_mA(); 00706 00707 lcd.nexSendFloat("anaVal", nvm.mA_high, 2); 00708 tmp = nvm.mA_high;//make a copy of the data to be 00709 00710 drawCompleted = drawCalGraph(X1,Y1,mapF(nvm.mA_high, I_0MA, I_21MA,X1,X2),Y2,DRAW);//wait for graph to complete 00711 00712 if(okFlag && drawCompleted){ 00713 drawCompleted = okFlag = false; 00714 scrnUpdate = true; 00715 calState++; 00716 00717 if(writeNVMfloat(NVM_ANA_MA_CAL_HIGH, nvm.mA_high)) 00718 lcd.nexSendTxt("info5","Data Varified"); 00719 else 00720 { 00721 lcd.nexSendTxt("info5","Varify Failed"); 00722 while(1); 00723 } 00724 00725 wait(1.0); 00726 lcd.nexSendTxt("info5",""); 00727 } 00728 break; 00729 00730 case CAL2_SCRN: 00731 if(scrnUpdate){ 00732 scrnUpdate = false; 00733 00734 lcd.nexSendTxt("title","4-20mA Calibration 2/4"); 00735 lcd.nexSendTxt("info1","Enter MAX"); 00736 lcd.nexSendTxt("info2","flow signal"); 00737 lcd.nexSendTxt("info3","using +/- keys"); 00738 lcd.nexSendTxt("info4","then press OK"); 00739 lcd.nexSendTxt("flowName","Flow High"); 00740 lcd.nexSendTxt("t0","%"); 00741 drawCalGraph(X1,Y1,mapF(nvm.mA_high, I_0MA, I_21MA,X1,X2),Y2,ERASE);//mA high, now erase the line read for next cal screen 00742 } 00743 00744 incDecControl(&nvm.flow_high, 1, 0.0, 100.0, nvm.speedLimit);//2 decimal places for mA 00745 lcd.nexSendFloat("flowVal", nvm.flow_high, 1); 00746 drawCompleted = drawCalGraph(X1,Y1,mapF(nvm.mA_high, I_0MA, I_21MA,X1,X2),mapF(nvm.flow_high, 0.0, 100.0,Y1,Y2),DRAW);//%, draw the line 00747 00748 if(okFlag && drawCompleted){ 00749 drawCompleted = okFlag = false; 00750 scrnUpdate = true; 00751 calState++; 00752 00753 if(writeNVMfloat(NVM_ANA_FLOW_CAL_HIGH, nvm.flow_high)) 00754 lcd.nexSendTxt("info5","Data Varified"); 00755 else 00756 { 00757 lcd.nexSendTxt("info5","Varify Failed"); 00758 while(1); 00759 } 00760 00761 wait(1.0); 00762 lcd.nexSendTxt("info5",""); 00763 } 00764 break; 00765 00766 case CAL3_SCRN: 00767 if(scrnUpdate){ 00768 scrnUpdate = false; 00769 00770 lcd.nexSendTxt("title","4-20mA Calibration 3/4"); 00771 lcd.nexSendTxt("info2","signal"); 00772 lcd.nexSendTxt("sigName","Signal Low"); 00773 00774 lcd.nexSendTxt("flowName","");//Clear these displays 00775 lcd.nexSendTxt("flowVal",""); 00776 lcd.nexSendTxt("t0",""); 00777 00778 if(manFlag){ 00779 lcd.nexSendTxt("info1","Enter LOW"); 00780 lcd.nexSendTxt("info2","signal"); 00781 lcd.nexSendTxt("info3","using +/- keys"); 00782 } 00783 else 00784 { 00785 lcd.nexSendTxt("info1","Apply LOW"); 00786 lcd.nexSendTxt("info2","signal"); 00787 } 00788 00789 lcd.nexSendTxt("info4","then press OK"); 00790 00791 drawCalGraph(X1,Y1,mapF(nvm.mA_high, I_0MA, I_21MA,X1,X2),mapF(nvm.flow_high, 0.0, 100.0,Y1,Y2),ERASE);//%, now erase the line read for next cal screen 00792 } 00793 00794 if(manFlag) 00795 incDecControl(&nvm.mA_low, 2, LOW_CAL_MIN, HIGH_CAL_MAX, nvm.speedLimit);//2 decimal places for mA 00796 else 00797 nvm.mA_low = anaIn_mA(); 00798 00799 lcd.nexSendFloat("anaVal", nvm.mA_low, 2); 00800 drawCompleted = drawCalGraph(X1,Y1,mapF(nvm.mA_low, I_0MA, I_21MA,X1,X2),Y2,DRAW);//mA low, draw the line 00801 00802 if(okFlag && drawCompleted){ 00803 drawCompleted = okFlag = false; 00804 scrnUpdate = true; 00805 calState++; 00806 00807 if(writeNVMfloat(NVM_ANA_MA_CAL_LOW, nvm.mA_low)) 00808 lcd.nexSendTxt("info5","Data Varified"); 00809 else 00810 { 00811 lcd.nexSendTxt("info5","Varify Failed"); 00812 while(1); 00813 } 00814 00815 wait(1.0); 00816 lcd.nexSendTxt("info5",""); 00817 } 00818 break; 00819 00820 case CAL4_SCRN: 00821 if(scrnUpdate){ 00822 scrnUpdate = false; 00823 00824 lcd.nexSendTxt("title","4-20mA Calibration 4/4"); 00825 lcd.nexSendTxt("info1","Enter MIN"); 00826 lcd.nexSendTxt("info2","flow signal"); 00827 lcd.nexSendTxt("info3","using +/- keys"); 00828 lcd.nexSendTxt("info4","then press OK"); 00829 lcd.nexSendTxt("flowName","Flow Low"); 00830 lcd.nexSendTxt("t0","%"); 00831 drawCalGraph(X1,Y1,mapF(nvm.mA_low, I_0MA, I_21MA,X1,X2),Y2,ERASE);//mA low, now erase the line read for next cal screen 00832 } 00833 00834 incDecControl(&nvm.flow_low, 1, 0.0, 100.0, nvm.speedLimit);//2 decimal places for mA 00835 lcd.nexSendFloat("flowVal", nvm.flow_low, 1); 00836 drawCompleted = drawCalGraph(X1,Y1,mapF(nvm.mA_low, I_0MA, I_21MA,X1,X2),mapF(nvm.flow_low, 0.0, 100.0,Y1,Y2),DRAW);//%, draw the line 00837 00838 if(okFlag && drawCompleted){ 00839 drawCompleted = okFlag = false; 00840 scrnUpdate = true; 00841 calState++; 00842 00843 if(writeNVMfloat(NVM_ANA_FLOW_CAL_LOW, nvm.flow_low)) 00844 lcd.nexSendTxt("info5","Data Varified"); 00845 else 00846 { 00847 lcd.nexSendTxt("info5","Varify Failed"); 00848 while(1); 00849 } 00850 00851 wait(1.0); 00852 lcd.nexSendTxt("info5",""); 00853 } 00854 break; 00855 00856 case COMPLETE_SCRN: 00857 if(scrnUpdate){ 00858 scrnUpdate = false; 00859 00860 calComplete = true; 00861 00862 lcd.nexChgPage(PAGE_18_ANA_CAL_MODE); 00863 //lcd.nexSendTxt("title","4 - 20mA Calibration completed"); 00864 //lcd.nexSendTxt("info2","Analogue = Starts in 4-20mA mode"); 00865 //lcd.nexSendTxt("info4","Manual = Starts in Manual mode"); 00866 //lcd.nexSendTxt("btnRight","Manual"); 00867 //lcd.nexSendTxt("btnLeft","Analogue"); 00868 00869 stopLED = 0;//turn off the stop LED 00870 drawCalGraph(X1,Y1,mapF(nvm.mA_low, I_0MA, I_21MA,X1,X2),mapF(nvm.flow_low, 0.0, 100.0,Y1,Y2),ERASE);//%, now erase the line read for next cal screen 00871 } 00872 break; 00873 00874 } 00875 00876 return(task); 00877 } 00878 00879 bool drawCalGraph(float x1, float y1, float x2, float y2,bool draw){ 00880 00881 static uint16_t cntr = ZERO; 00882 static float lastX1 = X1; 00883 static float lastY1 = Y1; 00884 static float lastX2 = X2; 00885 static float lastY2 = Y2; 00886 bool updated = false; 00887 00888 if(draw){ 00889 00890 if(cntr < DRAW_SPEED){ 00891 cntr++; 00892 updated = false; 00893 } 00894 else 00895 { 00896 cntr=ZERO; 00897 00898 stopLED = !stopLED; 00899 00900 lcd.nexDrawLine (lastX1, lastY1, lastX2, lastY2, WHITE);//Erase the previous red line calibration posotion 00901 wait(0.001); 00902 lcd.nexDrawLine (x1, y1, x2, y2, RED);//draw the new red line calibration position 00903 00904 lastX1 = x1; 00905 lastY1 = y1; 00906 lastX2 = x2; 00907 lastY2 = y2; 00908 updated = true; 00909 } 00910 } 00911 else 00912 lcd.nexDrawLine (x1, y1, x2, y2, WHITE);//erase the new red line calibration position 00913 00914 return(updated); 00915 } 00916 00917 uint8_t retLastStoredTask(uint8_t storedTask){ 00918 /* 00919 Returns to the last stored task 00920 */ 00921 00922 uint8_t task; 00923 00924 switch(storedTask){ 00925 case STOP_SCRN: task = STOP_SCRN;//refresh stop screen 00926 break; 00927 00928 case ANALOGUE_SET: task = ANALOGUE_SET;//refresh 00929 break; 00930 00931 case MANUAL_SET: task = MANUAL_SET;//refresh 00932 break; 00933 default:; 00934 } 00935 return(task); 00936 } 00937 00938 void flowUnitInc(uint8_t *fUx, uint8_t *fUy, uint8_t *fUz){ 00939 00940 if(*fUx > ZERO) 00941 *fUx-=1; 00942 else 00943 *fUx = P8_MENU_ITEMS; 00944 00945 if(*fUy > ZERO) 00946 *fUy-=1; 00947 else 00948 *fUy = P8_MENU_ITEMS; 00949 00950 if(*fUz > ZERO) 00951 *fUz-=1; 00952 else 00953 *fUz = P8_MENU_ITEMS; 00954 00955 lcd.nexSendTxt("top", menuStringArray[0][*fUx]); 00956 lcd.nexSendTxt("data", menuStringArray[0][*fUy]); 00957 lcd.nexSendTxt("bot", menuStringArray[0][*fUz]); 00958 00959 nvm.flowUnits = uFlowUnitID[*fUy]; 00960 } 00961 00962 void flowUnitDec(uint8_t *fUx, uint8_t *fUy, uint8_t *fUz){ 00963 00964 if(*fUx < P8_MENU_ITEMS) 00965 *fUx+=1; 00966 else 00967 *fUx = ZERO; 00968 00969 if(*fUy < P8_MENU_ITEMS) 00970 *fUy+=1; 00971 else 00972 *fUy = ZERO; 00973 00974 if(*fUz < P8_MENU_ITEMS) 00975 *fUz+=1; 00976 else 00977 *fUz = ZERO; 00978 00979 lcd.nexSendTxt("top", menuStringArray[0][*fUx]); 00980 lcd.nexSendTxt("data", menuStringArray[0][*fUy]); 00981 lcd.nexSendTxt("bot", menuStringArray[0][*fUz]); 00982 00983 nvm.flowUnits = uFlowUnitID[*fUy]; 00984 } 00985 00986 void dispList(uint8_t i[3], uint8_t incDec, uint8_t stringList, const string sArray[2][10], uint8_t maxListStrings){ 00987 00988 const uint8_t x=0,y=1,z=2; 00989 00990 if(incDec){ 00991 if(i[x] < maxListStrings) 00992 i[x]+=1; 00993 else 00994 i[x] = ZERO; 00995 00996 if(i[y] < maxListStrings) 00997 i[y]+=1; 00998 else 00999 i[y] = ZERO; 01000 01001 if(i[z] < maxListStrings) 01002 i[z]+=1; 01003 else 01004 i[z] = ZERO; 01005 }else{ 01006 if(i[x] > ZERO) 01007 i[x]-=1; 01008 else 01009 i[x] = maxListStrings; 01010 01011 if(i[y] > ZERO) 01012 i[y]-=1; 01013 else 01014 i[y] = maxListStrings; 01015 01016 if(i[z] > ZERO) 01017 i[z]-=1; 01018 else 01019 i[z] = maxListStrings; 01020 } 01021 01022 lcd.nexSetFontCol("data", RED); 01023 lcd.nexSendTxt("top", sArray[stringList][i[x]]); 01024 lcd.nexSendTxt("data", sArray[stringList][i[y]]); 01025 lcd.nexSendTxt("bot", sArray[stringList][i[z]]); 01026 } 01027 01028 01029 01030
Generated on Tue Jul 19 2022 00:58:42 by
1.7.2