// V505 Change P48 min value to allow for negative numbers // C506 ADD Lidar v979 // 506 add parm 16 lock circuit // 507 set parm 24 to 1 to use NC interlock on spare 1 // 997 add wifi // 984 add slave adjust for current balancing // 980 add log file stuff // 979 add LiDar // 508 ..979 release // 509 ..add wdt chip test // v510 fix multi sensor *10 bug added long and short wdt test // v511 fixed tone function, was causing reset. added serial command I to read unused inputs // v512 add parm 69 to monitor rtc // v514 add BOOT button to show motor status // v515 add exit button check for pgm screen exit // v550 multi door .. in process // v516 fix access code question // v517 add parm[15] as bug screen channel // v518 add remote bug screen // v519 add LIDAR test mode // v520 kill lidar test screen timeout // v521 add ioExpander relays to run Somfy bug screen // v522 ad ioExpander relay test TR 00x // v523 add WAITING FOR COMMAND recovery/ 2 motor feature // v524 SSID and PASS update // v525 parm 29 splash screen timeout to blank screen 0 = off // v526 turn on fault engine // v527 fix BOOTBUTTON OTA // fix low batt error on startup // v528 Fixed FTP name for OTA // Added serial number for label printer // Fixed high voltage reading on start up // v529 Updated code to use parms.write instead of parm[xx] = xx // Fixed check sum error. change bte to uint8_t // v530 Fixed LidarTimer in 485 file. Stopped reseting timer after seeing obstruction bit // v531 Changed default value of parm[18] to 1253 // Added display information for bug screen // v532 Moved no display fault restore to 602 to prevent spamming of fault // Extended condition to run 'wifiService()' in absence of a display, originally only active in the logo screen. // v533 Added serial check for \n or \r // Increased Parm 69 for rtc // Removed NTP code added check for BOOGYTIME // Bug fix - added etime to at_QtempData when pushing to cloud // v534 Added extra Clarity screens/functions // v535 Fixed parm 1 and 76 limits // v536 New motor error // Added parms for motor timeouts // v537 Added Clarity text for older display versions // v538 Bug fix - Changed motor timeout to parm 31 // Added function to use previous parms from an SD card when upgrading //**********************************************************************************************/ #include //V111 //Removed #SD Include //Added FileLib.h & HTTPSHandler.h #include "FS.h" #include "SD.h" #include "SPI_ADI.h" #include "HTTPSHandler.h" #include "Timers_ADI.h" #include "FileLib.h" #include "IO_ADI.h" #include "Parms_ADI.h" #include "RF_Keys.h" #include bool VB = 0; // verbose mode #define HEARTBEATLED 33 #define myVersion 117 // 525 //974 // 507 //delivered 505 protoype at Renlita #ifndef ADI_ESP32_DEV #error Incorrect platform definition #endif #define myCHAN parm[15] #define BALANCEDEADBAND 300 // v984 bool obstructionIsSensed = 0; bool lastObstructionPin = 0; bool onesecond; int addrcase; int wiFiOK = 0; int logicCase = 0; int forwardCase = 0; int DOOROPEN = 0; int DOORCLOSE = 0; int DOORSTOP = 0; int DOORTOGGLE = 0; int cDOOROPEN = 0; int cDOORCLOSE = 0; int cDOORSTOP = 0; bool LASTDIRECTION = 0; int lastCase = -1; // float voltageNow; // float currentNow; char tmpstr[80]; int runLogic = 0; // start it later int runCAN = 1; int doorState = 0; int lastDoorState = 1; float voltageNow; int displayServiceCounter = 0; unsigned long displayMillis; int lastBootPin; //Added Lines & Cert For HTTPS Connection const char *HTTPS_HOST = "appdig.com"; const char *BIN_SOURCE = "/EVOG2Test/EVOTEST.bin"; const char *UPLOAD_PARMS_DEST = "/EVOG2Test/upload.php"; const char *AUTH_HEADER = "X-Authorization: Basic YXBwZGlnOnB3ZA =="; const char *UPDATE_BIN = "/Update.bin"; const char *serverCert = "-----BEGIN CERTIFICATE-----\n" "MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\n" "TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n" "cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\n" "WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\n" "ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\n" "MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\n" "h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\n" "0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\n" "A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\n" "T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\n" "B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\n" "B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\n" "KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\n" "OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\n" "jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\n" "qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\n" "rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\n" "HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\n" "hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\n" "ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\n" "3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\n" "NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\n" "ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\n" "TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\n" "jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\n" "oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\n" "4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\n" "mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\n" "emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\n" "-----END CERTIFICATE-----\n"; HTTPSHandler https(serverCert); uint16_t faultNum, faultData, faultAB; int16_t lastDisplayedGraphic = -1; //V111 //Added File LibClass For Parms SD/SPIFF FileLibClass fileLibSPIFFS(FL_SPIFFS); // Instance for SPIFFS FileLibClass fileLibSD(FL_SD); ParmsLibClass parms(fileLibSPIFFS); void setup() { Serial.begin(115200); delay(500); Serial.println("Serial Initialized"); pinMode(HEARTBEATLED, OUTPUT); // heartbeat LED digitalWrite(HEARTBEATLED, HIGH); delay(2000); init_timers(); initFaults(); // v525 spiInit(); oled_init(); //Init SPIFFS AND SD & Validate They Work Serial.print("Version:"); Serial.println(myVersion); // Initialize SPIFFS if (!fileLibSPIFFS.begin()) { Serial.println("Failed to initialize SPIFFS"); } else { Serial.println("SPIFFS initialized"); } fileLibSD.setVerbose(1); if (!fileLibSD.begin()) { Serial.println("SD FAILED TO MOUNT"); } else { Serial.println("SD Card initialized"); } // delay(1000); // Serial.println(rtcGetTime()); // print_time(); parms.write(33, 0); // always turn off exercise // parm[16] = 0; parms.setVerbose(1); parms.loadFromFS(); parms.setVerbose(0); if(parms.read(14) != myVersion) //New Version parms.write(14,myVersion); initIO(); serviceIO(); serviceIO(); serviceIO(); voltageNow = io_array[BATT_V]; init485(); if (runCAN) motorInit(); delay(1000); initRF(); displayText("RF Init OK"); delay(1000); // sprintf(tmpstr, "Ver: %d-%d %d", myVersion, parm[1], parm[64]); // displayText(tmpstr); // Serial.println(tmpstr); ShowSerialScreen(); delay(3000); displayText("Setup Finished"); initWiFi(); // esp_task_wdt_init(10, true); //enable panic so ESP32 restarts 10 seconds // esp_task_wdt_add(NULL); //add current thread to WDT watch SD_LogWrite("Power Up"); qualifyFault(0, 0); // push startup } void loop() { // Heartbeat onesecond = 0; if (Timers[HEARTBEAT] == 0) digitalWrite(HEARTBEATLED, 1); if (Timers[HEARTBEAT] == 2) digitalWrite(HEARTBEATLED, 0); if (Timers[HEARTBEAT] == 3) digitalWrite(HEARTBEATLED, 1); if (Timers[HEARTBEAT] == 4) digitalWrite(HEARTBEATLED, 0); if (Timers[HEARTBEAT] >= 9) { Timers[HEARTBEAT] = 0; onesecond = 1; if (isDoorIdle() == 0) displayVoltage(); } if (onehundredmstick != 0) { onehundredmstick = 0; timer_update(); } /* if (onesecond) { Serial.println(); //uint8_t ip = readMCP23S08(IOEXP_CS, 9); for (int ip = 0; ip < 8; ip++) Serial.printf(" %X", io_array[ip]); Serial.println(); } */ // if(onesecond) Serial.printf("\n ADDR = %d\n",io_array[ADDRBUTTON]); // if(onesecond) Serial.printf(" Pin17 = %d\n",digitalRead(17)); // setting address /* switch (addrcase) { case 0: if (io_array[ADDRBUTTON] > 10) // addrcase++; break; case 1: if (io_array[ADDRBUTTON] == 0) //released it { showAddrScreen(); addrcase++; Timers[BOOTPINTIMER] = 0; } break; case 2: if (Timers[BOOTPINTIMER] > 200) ESP.restart(); if (digitalRead(0) == 0) //BOOT pressed, save and leave { SD_ParmWrite(); ESP.restart(); } if (io_array[ADDRBUTTON] > 10) { if (++parm[1] > 4) parm[1] = 0; addrcase++; } break; case 3: if (io_array[ADDRBUTTON] == 0) //released it { addrcase = 1; } break; } */ if (digitalRead(0) == 0) { if (Timers[BOOTPINTIMER] == -1) Timers[BOOTPINTIMER] = 0; if (onesecond) { sprintf(tmpstr, "Boot button: %d\n", Timers[BOOTPINTIMER]); displayText(String(tmpstr)); } if (Timers[BOOTPINTIMER] > 200) { if (io_array[3] == 0) // Address Setup Button parms.factoryReset(); else beginOTA(); Timers[BOOTPINTIMER] = -1; } } else { Timers[BOOTPINTIMER] = -1; } if (lastBootPin == 1) // transition if (digitalRead(0) == 0) { displayVoltage(); } lastBootPin = digitalRead(0); if (lastObstructionPin == 0) { if (digitalRead(OBSTRUCTIONPIN) == 1) { obstructionCounter++; } } lastObstructionPin = digitalRead(OBSTRUCTIONPIN); if (Timers[OBSTRUCTION] >= 5) // check obstruction every .5 sec. { // Serial.print("Obstruction: "); // Serial.println(obstructionCounter); Timers[OBSTRUCTION] = 0; obstructionIsSensed = 0; // noInterrupts(); if (obstructionCounter < 50) { obstructionIsSensed = 1; } obstructionCounter = 0; // interrupts(); } if (runLogic == 1) { doorLogic(); if (parm[28] == 1) screenLogic(); // v521 } if (parm[26] == 1) // v518 remote screen operation { if (exOptoTransition[2] == 1) { displayText("HA Screen UP"); rfSendKey(RF_KEY_UP, myCHAN); exOptoTransition[2] == 0; } if (exOptoTransition[3] == 1) { displayText("HA Screen DOWN"); rfSendKey(RF_KEY_DN, myCHAN); exOptoTransition[3] == 0; } } serviceIO(); voltageNow = io_array[BATT_V]; // drop motor watchdog if (motorGetPosition(0) != 9999) if (motorGetPosition(1) != 9999) io_array[POWER_RLY] ^= 1; // comms dropped on a motor if (motorGetPosition(0) == 9999) setMotorFault(0); if (motorGetPosition(1) == 9999) setMotorFault(1); if (runCAN) motorTask(); if (parm[1] == 0) inSerial2(); else runSlave(); if (millis() - displayMillis >= 20) // 988 50 { if (parm[1] == 0) serviceDisplay(); // master displayMillis = millis(); } /* if (Timers[DISPLAYSERVICETIMER] >= 1) { Timers[DISPLAYSERVICETIMER] = 0; serviceDisplay(); } */ if (Timers[TENSECOND] >= 100) { Timers[TENSECOND] = 0; runLogic = 1; sprintf(tmpstr, "********************* M0: %d M1: %d\n", motorGetPosition(0), motorGetPosition(1)); Serial.println(tmpstr); sprintf(tmpstr, "Obstruction: %d\n", obstructionIsSensed); Serial.println(tmpstr); Serial.printf("Voltage: %d, %d\n", io_array[BATT_V], analogRead(BATTERYINPUTPIN)); Serial.print("Logic Case: "); Serial.println(logicCase); } if (Timers[AT200DATA] >= parm[23]) // check in { Timers[AT200DATA] = 0; pushCheckin(); pushDoorStatus(); } rfTask(); checkSerial(); if (Timers[VOLTAGETIMER] >= 100) // 10 seconds into travel { Timers[VOLTAGETIMER] = -1; pushCheckin(); } if (doorState != lastDoorState) { pushDoorStatus(); lastDoorState = doorState; sprintf(tmpstr, "Max Current M: %d.%d S: %d.%d\n", getMaxCurrent(0) / 10, getMaxCurrent(0) % 10, getMaxCurrent(1) / 10, getMaxCurrent(1) % 10); Serial.print(tmpstr); SD_LogWrite(tmpstr); pushMaxCurrents(); } if (isDoorIdle() == 0) // door is busy Timers[ISIDLETIMER] = 0; if (Timers[ISIDLETIMER] > 10) if (Timers[ISIDLETIMER] < 12) { motorStop(); displayText("Motor Stop"); Timers[ISIDLETIMER] = 13; } //******WiFi Service master if (parm[1] == 0) // master { wiFiOK = 0; if (Timers[ISIDLETIMER] > 100) // been idle more than 10 seconds if (parm[9] == 1) // WiFi enabled { if (lastDisplayedGraphic == 8) { wiFiOK = 1; // LOGOSCREEN? } // In logo screen or no display screen if (currentDisplayCase() == 22 || currentDisplayCase() == 23 || currentDisplayCase() == 600 || currentDisplayCase() == 602) { if (Timers[WIFISERVICE] >= parm[22]) { wifiService(); Timers[WIFISERVICE] = 0; } if (Timers[AT200DATA] >= parm[23]) // check in { Timers[AT200DATA] = 0; pushCheckin(); pushDoorStatus(); } } } } //******WiFi Service slave if (parm[1] != 0) // slave { if (Timers[ISIDLETIMER] > 100) // been idle more than 10 seconds if (parm[9] == 1) // WiFi enabled if (wiFiOK == 1) { if (Timers[WIFISERVICE] >= parm[22]) { wifiService(); Timers[WIFISERVICE] = 0; } if (Timers[AT200DATA] >= parm[23]) // check in { Timers[AT200DATA] = 0; pushCheckin(); pushDoorStatus(); } } } if (onesecond) if (VB) Serial.printf("WiFiOK -> %d, ISIDLETIMER -> %d\n", wiFiOK, Timers[ISIDLETIMER]); // if (onesecond) Serial.printf("Voltage Timer: %d\n", Timers[VOLTAGETIMER]); if (Timers[OLEDBLANKTIMER] > 1200) // v1653 to blank oled { displayText(""); Timers[OLEDBLANKTIMER] = 0; } if (Timers[OLEDHOLDTIMER] > 30000) Timers[OLEDHOLDTIMER] = 2000; } int isDoorIdle(void) { if ( (logicCase == 1) || (logicCase == 2) || (logicCase == 20) || (logicCase == 10)) return (1); return (0); } void doorLogic(void) { if (parm[25] == 0) // v995 { DOOROPEN = 0; DOORCLOSE = 0; DOORSTOP = 0; DOORTOGGLE = 0; } if (parm[26] == 1) { DOOROPEN = exOpto[0]; DOORCLOSE = exOpto[1]; } else { DOOROPEN = 0; DOORCLOSE = 0; } if (parm[25]) if (onesecond) Serial.printf("ioExpander %d %d %d %d\n", exOpto[0], exOpto[1], exOpto[2], exOpto[3]); if (io_array[RF_KEYPAD] > 10) // door toggle DOORTOGGLE = 1; DOORTOGGLE = 0; // dstest /* if (io_array[JOG_EXTEND] < 50) { logicCase = 50; } if (io_array[JOG_RETRACT] < 50) { logicCase = 51; } */ if (LowBattery() == 0) if (parm[33] >= 6000) runExercise(); if (parm[16] == 1) io_array[SPARE_OUT] = 0; // v506 // v507 add interlock spare1 if ((parm[24] != 0) && (io_array[SPARE_IN] == 0)) logicCase = 0; switch (logicCase) { //********** case 0: // init logicCase++; // io_array[EXTEND] = 0; // io_array[RETRACT] = 0; motorStop(); // doorState = 0; break; case 1: // make sure all buttons are clear if ((DOOROPEN == 0) && (DOORCLOSE == 0) && (cDOOROPEN == 0) && (cDOORCLOSE == 0) && (cDOORSTOP == 0)) logicCase++; break; case 2: // idle //don't know where we are // doorState = 0; //v987 if ((DOOROPEN) || (cDOOROPEN)) // door open logicCase = 30; if ((DOORCLOSE) || (cDOORCLOSE)) // door close logicCase = 40; /* if (DOORTOGGLE) //door toggle from Spare_IN1 input { if (!LASTDIRECTION) logicCase = 30; if (LASTDIRECTION) logicCase = 40; } */ break; //****OPEN case 30: // we gonna open if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; displayText("OPENING"); logicCase = 31; io_array[COMPRESSOR] = 0; // release compressor Timers[GASKETTIMER] = 1; // if (io_array[EXT_LIMIT] != 0) // logicCase = 10; //duh, already open setCurrentBalance(0); break; case 31: // if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; if (Timers[GASKETTIMER] > parm[2]) // wait for COMPRESSOR delay logicCase = 32; break; case 32: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; Timers[DOORTRAVELTIMER] = 1; // start max timer for overall travel logicCase = 33; // parms.write(11, parm[11] + 1); //cycle counter // SD_ParmWrite(); break; case 33: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; Serial.println("Begin Open"); Timers[VOLTAGETIMER] = 0; // MOVEDIRECTION = 1; // if (motorGetPosition(0) > parm[40]) MOVEDIRECTION = 0; //we above it.. need to travel down motorMove(2999); // io_array[EXTEND] = 1;//let's open it logicCase = 34; LASTDIRECTION = 1; break; case 34: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; logicCase++; /* if (Timers[DOORTRAVELTIMER] > parm[5]) //must be fully open { logicCase = 35; } */ if ((DOORSTOP) || (cDOORSTOP)) logicCase = 0; if (DOORTOGGLE) logicCase = 0; break; case 35: // if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; // io_array[EXTEND] = 0; // io_array[RETRACT] = 0;//let's close it Timers[DOORTRAVELTIMER] = 1; // logicCase = 60; // forwardCase = 36; logicCase++; break; case 36: // io_array[EXTEND] = 0; // io_array[RETRACT] = 1;//let's close it to stop if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; logicCase = 37; break; case 37: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; if (Timers[DOORTRAVELTIMER] > parm[6]) // just in case { logicCase = 0; Serial.println("Open Travel Timeout"); displayText("Open Timeout"); pushDoorStatus(); } // v984 balance current while running if (motorGetPosition(0) < (parm[40] - BALANCEDEADBAND)) { setCurrentBalance(parm[49]); } else { setCurrentBalance(0); } // finished if (motorGetPosition(0) >= parm[40]) { logicCase = 10; Serial.printf("Open Limit reached %d - %d\n", motorGetPosition(0), parm[40]); displayText("Open Limit reached"); motorStop(); parms.write(11, parm[11] + 1); // cycle counter } /* if (io_array[EXT_LIMIT] > 5)//v108 .. was 10 { logicCase = 10; Serial.println("Limit reached"); } */ if ((DOORSTOP) || (cDOORSTOP)) logicCase = 0; if (DOORTOGGLE) logicCase = 0; break; //****CLOSE case 40: // we gonna close if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; logicCase = 42; displayText("CLOSING"); Serial.println("CLOSING"); /* if (io_array[RET_LIMIT] > 10) logicCase = 20; //duh, already closed */ break; case 42: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; Timers[DOORTRAVELTIMER] = 1; // start max timer for overall travel logicCase = 43; break; case 43: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; // io_array[RETRACT] = 1;//let's close it Serial.println("Begin Close"); Timers[VOLTAGETIMER] = 0; motorMove(10); logicCase = 46; LASTDIRECTION = 0; break; case 46: forwardCase = 30; if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; if (Timers[DOORTRAVELTIMER] > parm[5]) // just in case { logicCase = 20; pushDoorStatus(); displayText("Close Timeout"); } // v984 balance current while running if (motorGetPosition(0) > (parm[39] + BALANCEDEADBAND)) { setCurrentBalance(parm[50]); } else { setCurrentBalance(0); } if (motorGetPosition(0) <= parm[39]) { logicCase = 20; motorStop(); displayText("Limit reached"); Serial.println("Limit reached"); } if (parm[54] == 0) // no LiDar v979 if ((DOORSTOP) || (cDOORSTOP) || ((cDOORCLOSE == 0) && (DOORCLOSE == 0))) // v995 { // forwardCase = 30; //to reverse // logicCase = 60; logicCase = 0; } if (parm[54] == 1) // use LiDar v979 if ((DOORSTOP) || (cDOORSTOP)) { logicCase = 0; } if (parm[4] != 0) { if (obstructionIsSensed == 1) { forwardCase = 30; logicCase = 60; Serial.println("Photo Obstruction!! Change Direction"); showObstructionScreen(); faultNum = 1; faultAB = 0; faultData = 0; } } if (Timers[LIDARTIMER] > 30) { if (parm[54] != 0) // use Lidar { // check for deadzones at ends if (motorGetPosition(0) <= (parm[39] + parm[66])) clearLidarObstruction(); // 200 up from closed if (motorGetPosition(0) >= (parm[40] - parm[65])) clearLidarObstruction(); // 400 down from open if (checkLidarObstruction()) { forwardCase = 30; logicCase = 60; Serial.println("Lidar Obstruction!! Change Direction"); qualifyFault(35, 0); restoreFault(35); showObstructionScreen(); faultNum = 5; faultAB = 0; faultData = 0; } } } else { clearLidarObstruction(); } if (DOORTOGGLE) { forwardCase = 30; logicCase = 60; } break; case 60: // Reverse delay if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; Timers[DOORTRAVELTIMER] = 0; displayText("Reverse"); motorStop(); // io_array[EXTEND] = 0; // io_array[RETRACT] = 0; logicCase++; break; case 61: if (parm[16] == 1) // v506 io_array[SPARE_OUT] = 1; if (Timers[DOORTRAVELTIMER] > 10) logicCase = forwardCase; break; //*********** case 10: // door is open doorState = 1000; logicCase = 0; // if ((DOORCLOSE) || (cDOORCLOSE))logicCase = 40; // if (DOORTOGGLE) logicCase = 40; // io_array[EXTEND] = 0; // io_array[RETRACT] = 0; break; //*********** case 20: // door is closed doorState = 0; logicCase = 0; io_array[COMPRESSOR] = 1; // compressor on if ((DOOROPEN) || (cDOOROPEN)) logicCase = 30; if (DOORTOGGLE) logicCase = 30; // io_array[EXTEND] = 0; // io_array[RETRACT] = 0; break; default: logicCase = 0; Serial.println("entered door logic default case"); break; } if (isDoorIdle() == 0) if (parm[27] != 0) // turn on current limit if (Timers[DOORTRAVELTIMER] > 30) // if we have been running over 3 seconds { if (motorGetCurrent(0) > parm[27]) { sprintf(tmpstr, "M Overcurrent %d", motorGetCurrent(0)); displayText(String(tmpstr)); motorStop(); parms.write(33, 0); logicCase = 0; // delay(1000); } if (motorGetCurrent(1) > parm[27]) { sprintf(tmpstr, "S Overcurrent %d", motorGetCurrent(1)); displayText(String(tmpstr)); motorStop(); parms.write(33, 0); logicCase = 0; // delay(1000); } } // if (VB) if (lastCase != logicCase) { Serial.print("Logic Case: "); Serial.println(logicCase); lastCase = logicCase; } } void runExercise(void) { if (Timers[EXERCISETIMER] < 0) Timers[EXERCISETIMER] = 0; // start it if (Timers[EXERCISETIMER] > parm[33]) Timers[EXERCISETIMER] = 0; // start over if (cDOORSTOP != 0) // cancel the whole thing { Timers[EXERCISETIMER] = -1; // stop it parms.write(33, 0); return; } // open cDOOROPEN = 0; if (Timers[EXERCISETIMER] > 20) if (Timers[EXERCISETIMER] < 30) // let's open cDOOROPEN = 1; // close cDOORCLOSE = 0; if (Timers[EXERCISETIMER] > (parm[33] / 2)) // let's close halfway through timeout if (Timers[EXERCISETIMER] < (parm[33] - 30)) cDOORCLOSE = 1; if (onesecond) Serial.printf("Exercise timer: %d\n", Timers[EXERCISETIMER]); } void checkSerial() { static String fromSerial; // needs to keep its value between calls int pnum; uint32_t pdata, edata; // if something is available - make sure you have line feed enabled if (Serial.available()) { char c = Serial.read(); if (c == '\n' || c == '\r') { if (fromSerial.length() > 0) { Serial.println(fromSerial); // for debugging, just echo back what you got fromSerial = ""; // Clear the string for the next line } } else { fromSerial += c; // Append the received character to the string } // parm write PW ppp 1234567 if (fromSerial[0] == 'P' && fromSerial[1] == 'W' && fromSerial.length() == 14) { // writing parm - must match length // first pull down the string, convert from ASCII to decimal, and combine the bytes pnum = ((fromSerial[3] - 48) * 100) + ((fromSerial[4] - 48) * 10) + ((fromSerial[5] - 48) * 1); pdata = ((fromSerial[7] - 48) * 1000000) + ((fromSerial[8] - 48) * 100000) + ((fromSerial[9] - 48) * 10000) + ((fromSerial[10] - 48) * 1000) + ((fromSerial[11] - 48) * 100) + ((fromSerial[12] - 48) * 10) + ((fromSerial[13] - 48) * 1); if (VB == 1) { Serial.print("Attempt Parm# "); Serial.print(pnum); Serial.print(" = "); Serial.println(pdata); } parms.write(pnum, pdata); } // parm read PR ppp if (fromSerial[0] == 'P' && fromSerial[1] == 'R' && fromSerial.length() == 6) { // reading parm - must match length // first pull down the string, convert from ASCII to decimal, and combine the bytes pnum = ((fromSerial[3] - 48) * 100) + ((fromSerial[4] - 48) * 10) + ((fromSerial[5] - 48) * 1); Serial.print("Parm# "); Serial.print(pnum); Serial.print(" = "); Serial.println(parm[pnum]); if (pnum == 64) // serial# for label printer Serial.printf("serial: %d\n", parm[64]); delay(2000); } // toggle ioExpander relays if (fromSerial[0] == 'T' && fromSerial[1] == 'R' && fromSerial.length() == 6) { // reading parm - must match length // first pull down the string, convert from ASCII to decimal, and combine the bytes pnum = ((fromSerial[3] - 48) * 100) + ((fromSerial[4] - 48) * 10) + ((fromSerial[5] - 48) * 1); if (pnum < 8) { if (exRly[pnum]) exRly[pnum] = 0; else exRly[pnum] = 1; Serial.printf("ioExpander Relay %d = %d\n", pnum, exRly[pnum]); } else Serial.println("Invalid relay#"); delay(2000); } if (fromSerial[0] == 'I') // V511 read unused inputs { Serial.printf("Retract Switch %d\n", io_array[RET_LIMIT]); Serial.printf("Extend Switch %d\n", io_array[EXT_LIMIT]); Serial.printf("Open Limit Switch %d\n", io_array[OPEN_LIMIT]); Serial.printf("RF Keypad %d\n", io_array[RF_KEYPAD]); Serial.printf("Spare Input %d\n", io_array[SPARE_IN]); } /* //List Directory if (fromSerial[0] == 'L' && fromSerial[1] == 'D') listDir("/", 3); //Create Directory if (fromSerial[0] == 'C' && fromSerial[1] == 'D') createDir("/data"); //Move File if (fromSerial[0] == 'M' && fromSerial[1] == 'F') renameFile("/update.bin", "/data/update.old"); //Save Queue // if (fromSerial[0] == 'S' && fromSerial[1] == 'Q') // save_aQbuffer(); //Battery A2D //if (fromSerial[0] == 'B' && fromSerial[1] == 'D') //{ // Serial.print("Battery A2D: "); // Serial.println(analogRead(BATTERYINPUTPIN)); //} //Upload Data if (fromSerial[0] == 'U' && fromSerial[1] == 'D') { if(uploadFtpFile("/50-4-10-13-25-35.atQ","/httpdocs/aQData","50-4-10-13-25-35.atQ")) renameFile("/50-4-10-13-25-35.atQ", "/data/50-4-10-13-25-35.uld"); // effectivley.. this moves it to another dir as well } */ // Toggle Spare if (fromSerial[0] == 'T' && fromSerial[1] == 'S' && fromSerial.length() == 2) { // reading if (io_array[SPARE_OUT]) io_array[SPARE_OUT] = 0; else io_array[SPARE_OUT] = 1; Serial.printf(" Spare = %d\n", io_array[SPARE_OUT]); } // Epoch read ER if (fromSerial[0] == 'E' && fromSerial[1] == 'R' && fromSerial.length() == 2) { // reading Serial.printf("RTC Epoch Time: %u\n", getEpochRtc()); } // Timer Read if (fromSerial[0] == 'T' && fromSerial[1] == 'R' && fromSerial.length() == 6) { // reading parm - must match length // first pull down the string, convert from ASCII to decimal, and combine the bytes pnum = ((fromSerial[3] - 48) * 100) + ((fromSerial[4] - 48) * 10) + ((fromSerial[5] - 48) * 1); Serial.print("Timer# "); Serial.print(pnum); Serial.print(" = "); Serial.println(Timers[pnum]); } // Epoch write EW 1234567890 if (fromSerial[0] == 'E' && fromSerial[1] == 'W' && fromSerial.length() == 13) { edata = ((fromSerial[3] - 48) * 1000000000) + ((fromSerial[4] - 48) * 100000000) + ((fromSerial[5] - 48) * 10000000) + ((fromSerial[6] - 48) * 1000000) + ((fromSerial[7] - 48) * 100000) + ((fromSerial[8] - 48) * 10000) + ((fromSerial[9] - 48) * 1000) + ((fromSerial[10] - 48) * 100) + ((fromSerial[11] - 48) * 10) + ((fromSerial[12] - 48) * 1); setEpochRtc(edata); } } } // v521 screen stuff int screenCase = 0; bool SCREENOPEN = 0; bool SCREENCLOSE = 0; bool SCREENSTOP = 0; #define SCREEN_UP 0 #define SCREEN_DN 1 #define SCREEN_STP 2 void screenLogic(void) { // Serial.print(screenCase); Serial.print(" "); Serial.println(Timers[SCREENTIMER]); switch (screenCase) { case 0: screenCase = 1; exRly[SCREEN_UP] = 0; exRly[SCREEN_DN] = 0; exRly[SCREEN_STP] = 0; SCREENOPEN = 0; SCREENCLOSE = 0; SCREENSTOP = 0; break; case 1: // idle if (SCREENOPEN) { exRly[SCREEN_UP] = 1; Timers[SCREENTIMER] = 1; screenCase = 2; } if (SCREENCLOSE) { exRly[SCREEN_DN] = 1; Timers[SCREENTIMER] = 1; screenCase = 2; } if (SCREENSTOP) { exRly[SCREEN_STP] = 1; Timers[SCREENTIMER] = 1; screenCase = 2; } break; case 2: { if (Timers[SCREENTIMER] > parm[3]) // screen button timeout screenCase = 0; } break; default: screenCase = 0; break; } } int relayTest; void ioTest(void) { int ii; for (ii = 0; ii < 4; ii++) { exRly[ii] = 0; } exRly[relayTest] = 1; if (++relayTest >= 4) relayTest = 0; for (ii = 0; ii < 4; ii++) { Serial.print(" In"); Serial.print(exOpto[ii]); Serial.print(" Out"); Serial.print(exRly[ii]); } Serial.println(); } void tone(byte pin, int freq, int duration) { int CHANNEL = 1; ledcSetup(CHANNEL, freq, 8); // V511 was ledcSetup(pin,freq,8) ledcAttachPin(pin, CHANNEL); ledcWrite(CHANNEL, 128); // 50% duty cycle delay(duration); ledcWrite(CHANNEL, 0); // turn off pwm ledcDetachPin(pin); }