EVOG2-Spiffs-Avery/EVOG2.ino

1328 lines
33 KiB
C++

// 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 <SPI.h>
//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 <esp_task_wdt.h>
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);
}