I thought just the variable definitions would be enough. Here it is - it’s big!
// Version 2025-08-27 using char - Uploads ok on DELL under IDE 2.3.4
// but on laptop under 2.3.6 fails w numerous errors
// must use strcpy to assign strings to char vars
// must use char* fro params in func decs
// //mySerial monitor set for CR
// C:\Windows\SysWOW64\regsvr32 C:\Windows\SysWOW64\MSCOMM32.ocx
// arrays are zero-based
#include <Arduino.h>
# include <SoftwareSerial.h>
SoftwareSerial mySerial(15, 16);// RX, TX
unsigned long lastExecTime[] = {0, 0, 0};
int charCount = 0;
char param[2];
char sglLineState = 'C'; // WB EB CL
char* carActionOld[4] = { "XXXX", "NNNN", "NNNN" } ; // nnnnn
char* carAction[4] = { "XXXX", "NNNN", "NNNN" } ;
int MotorSpeedPin[] = { 0, 10, 11 } ;
int MotorADirnPin = 12;
int MotorBDirnPin = 13;
int SingleLineRelayPin = 14;
int c; // used in //printCarSpeed
char sCurrentProc;
bool bDebugging = false ;
int carLocation[3] = {0, 0, 0 } ;
unsigned long brakeStartMillis[2];
unsigned long accelSpdChMillis[2];
unsigned long carStopMillis[2];
int carSpeed[] = { 0, 0, 0 } ;
int speedIdx[] = { 0, 0, 0 } ;
char brakingStarted[] = { 'N', 'N', 'N'}; // using bool gives strange results
int detPins[] = { 99, 8, 2, 19, 7 } ;; // old{99, 2, 3, 5, 6} // DETS
char detSoftwareState[] = { 'n', 'U', 'U', 'U', 'U' } ;
char detSoftwareStateOld[] = { 'n', 'U', 'U', 'U', 'U' } ;
int detHardwareStateConfirmed[] = {1, 1, 1, 1, 1};
int detHardwareStatePrevLoop[] = {1, 1, 1, 1, 1};
int detHardwareStateOld[] = {1, 1, 1, 1, 1};
unsigned long detOccInstant[] = {0, 0, 0, 0, 0};
bool bDetActive[] = {false, false, false, false, false}; // car over det
// must not start w car over det
int numDets = 4;
const int speeds[] = { 0, 30, 30, 30, 30, 30}; // 6 V
const int stimes[] = {0, 300, 500, 600, 700};
bool blnTesting = false;
int iSigR = 100;
int iSigG = 100;
unsigned long detLastChangeMillis[4];
unsigned long detClrStartMillis[5];
unsigned long stopTimer1; // car 1 at stop at W sig
unsigned long detchTime[4];
bool bDetHWchanged[] = {false, false, false, false, false};
// char to hold input
bool Complete = false; // whether the char is complete
int incomingByte = 0; // for incoming //mySerial data
/* char x;
char y; */
char cmd[2];// = {'A'}; //= {}; // chars received
// this was causing out-of-memory
//char* cmd;
// signals
int wSigRpin = 3;
int wSigGpin = 6;
int eSigRpin = 9;
int eSigGpin = 5;
//-------------------------------------------------------
//void writeLog(char p1 = "X", char* p2 ="Y", int p3 = 998, int p4 = 999, ){
void writeLog(char* p1 = "X", char* p2 ="Y", char* p3 = "Z", char* p4 = "W", char* p5 = "W",char* p6 = "W"){
Serial.print("millis: ");
Serial.print(millis());
Serial.print(" Proc: ");
Serial.print(sCurrentProc);
Serial.print(p1);
Serial.print(p2);
Serial.print(p3);
Serial.println(p4);
}
void setup() { // BEGIN SETUP
//runTime = 0;
mySerial.begin(9600);
Serial.begin(9600);
mySerial.begin(9600);
writeLog("Starting---------------------------------------------------------------------");
//"119 detSoftwareState[1]", detSoftwareState[1], detSoftwareStateOld[2]);
strcpy(sCurrentProc , "setup");
// DETECTOR PINS
pinMode(2, INPUT_PULLUP); // det 2
pinMode(7, INPUT_PULLUP); // det 4
pinMode(8, INPUT_PULLUP); // det 1
pinMode(19, INPUT_PULLUP); // det 3
//sigs
pinMode(3, OUTPUT); // w sig red
pinMode(6, OUTPUT); // w sig grn
pinMode(9, OUTPUT); // e sig red
pinMode(5, OUTPUT); // e sig grn
// motor pins
pinMode(10, OUTPUT); // motor 1
pinMode(11, OUTPUT); // motor 2
//relay
pinMode(SingleLineRelayPin, OUTPUT); // relays
digitalWrite(MotorADirnPin, HIGH);
digitalWrite(MotorBDirnPin, LOW);
//digitalWrite(SingleLineRelayPin, LOW); // sets the digital pin 14 on - test relays -
//sglLineState = 'C';
setSingleLineState('C', "Setup - sglLineState set to C");
////delay(2000);
// check if car over det and initialize detHardwareStateConfirmed
for (int dxs = 1; dxs < 5; dxs++) { // FOR EACH DET IN CHK IF CAR OVER DET AT START
//writeLog(digitalRead(detPins[dxs]) == 0 );
if (digitalRead(detPins[dxs]) == 0 ) {
writeLog("Car over Det: ", "", -1 , dxs);
detHardwareStateConfirmed[dxs] = 0;
} // if det pin 0
else {
detHardwareStateConfirmed[dxs] = 1;
} // else det pin 1
} // END FOR EACH DET IN CHK IF CAR OVER DET AT START
} // END setup
// ------------------------------LOOP START
//char cmd[20];
int chCount;
int lcount;
void loop() {//...............................................VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
strcpy(sCurrentProc , "loop");
//chCount+= 1;
// Serial.println(chCount, , "Now: ", chCount);
//delay(5000);
//return;
if (bDebugging) {
////delay (5000, "Running: ", sCurrentProc);
} // if debugging
/* tLoop = millis() - tOld;
tOld = millis();
if (false) { //tLoop != tLoopOld ) // loop time w return after this is 21, 22, 23
writeLog("143 loop time ", tLoop); // loop is 10 ms here
} // END IF DEBUGGING PRINT LOOP TIME
tLoopOld = tLoop;*/
char newchar;
if (mySerial.available()) {
//writeLog("mySerial available");
incomingByte = mySerial.read();
Serial.print("221:");
Serial.println(incomingByte);
if (incomingByte != 13){
cmd[chCount] = (char)incomingByte;
//char* p =
writeLog("226: cmd[0]=", cmd[0] );
writeLog("226: cmd[1]=", cmd[1] );
chCount+=1;
}
else {
// 2025-08-25T16:25 incoming bytes disp ok in line 231 but garbage here
writeLog("235 Got:");
Serial.print(cmd[0]);
Serial.println(cmd[1]);
cmd[0] = cmd[0];
cmd[1] = cmd[1];
writeLog("Cmd:", cmd[0], cmd[1]);
chCount = 0;
cmd[0] = "";
cmd[1] = "";
ProcessSerial();
//cmd = "";
}
}
chkDets();
chkCarAction();
} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END LOOP^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ loop
void ProcessSerial() { // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV BEGIN ProcessSerial
strcpy(sCurrentProc , "ProcessSerial");
if (cmd[0] == 'Z') {
writeLog("77 Got: ", cmd[0], cmd[1]);
}
if (cmd[0] == 'S') { // cmd = s signal
writeLog("cmd s");
digitalWrite(eSigGpin, LOW); //E SIG GN
digitalWrite(eSigRpin, LOW); // W SIG RED
digitalWrite(wSigGpin, LOW); // W SIG GRN
digitalWrite(wSigRpin, LOW); // E SIG RED
sglLineState = 'C';
//writeLog(cmd[1] == '1');
//if (cmd[1] == '1') { digitalWrite(eSigGpin, HIGH); } // END IF //E SIG GN
//if (cmd[1] == '1') { digitalWrite(wSigRpin, HIGH); } // END IF // W SIG RED
if (cmd[1] == '1') { setSingleLineState('E', "Manual cmd");} // END IF
// if (cmd[1] == '2') { digitalWrite(wSigGpin, HIGH); } // END IF // W SIG GRN
// if (cmd[1] == '2') { digitalWrite(eSigRpin, HIGH); } // END IF // E SIG RED
if (cmd[1] == '2') { setSingleLineState('W', "Manual cmd");} // END IF;} // END IF
if (cmd[1] == '3') { setSingleLineState('C', "Manual cmd");} // END IF // IF param == 3
/* digitalWrite(eSigGpin, LOW); //E SIG GN
digitalWrite(eSigRpin, LOW); // W SIG RED
digitalWrite(wSigGpin, LOW); // W SIG GRN
digitalWrite(wSigRpin, LOW); // E SIG RED
sglLineState = 'C'; */
// } // END IF param == 3
writeLog("SL State: ", sglLineState);
} // END IF cmd = s
//printVar(255, "cmd[0]", cmd);
if (cmd[0] == 'I') { // print info // cmd = i print info
//https://www.google.com/search?q=ISO+C%2B%2B+forbids+converting+a+string+constant+to+%27char&oq=ISO+C%2B%2B+forbids+converting+a+string+constant+to+%27char&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg70gELNDY0MDQ4NWowajSoAgCwAgA&sourceid=chrome&ie=UTF-8
//char str = "Hello, world!";
//printCarSpeed("Cmd "i"", param, "info".c_str());
//printCarAction("Cmd "i"", param, "info");
int carNum = cmd[1] - 48; // also for 'b' etc
//printVar(319, "cmd[0]", cmd);
//printCarStatus(carNum, "275 cmd i"); // "cmd "i"");
} // END IF cmd = i print info
if (cmd[0] == 'X') { // // cmd = 'X' emerg stop
carSpeed[1] = 0;
carSpeed[2] = 0;
analogWrite(MotorSpeedPin[1], LOW);
analogWrite(MotorSpeedPin[2], LOW);
strcpy(carAction[1], "NNNN");
strcpy(carAction[2], "NNNN");
} // endif cmd = 'X' emerg stop
if (cmd[0] == 'T') { //
if (cmd[1] == '1') {
bDebugging = true;
}
else {
bDebugging = false;
}
//writeLog("305 bDebugging:", bDebugging);
} // END IF cmd = t
if (cmd[0] == 'P') {
analogWrite(11, 60);
//delay(1000);
analogWrite(11, 12);
}
if (cmd[0] == 'A') { // // cmd = a accelerate
// inchar = "";
int carNum = cmd[1] - 48; // also for 'b' etc
//accelSpdChMillis[carNum] = millis(); // manual cmd
speedIdx[carNum] = 1; // was 0
updateCarAction(carNum, "ACCL", "Manual cmd");
} // END IF CMD = "a"
if (cmd[0] == 'B') { // if cmd = b brake
writeLog("395");
int carNum = cmd[1] - 48; // also for 'b' etc
brakeStartMillis[carNum] = millis(); // manual b
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "BMAN", "Manual cmd");
////strcpy(fncmd[1], );
//printCarStatus(carNum, "403 Got Manual cmd b"); // cmd b
} // END IF cmd = b brake
if (cmd[0] == 'D') { // IF cmd = d dets
for (int d = 1; d <= numDets; d++) {
// THIS DOESN"T RELIES ON CHDETS BEING CALLED FROM LOOP
// //delay(2000);
writeLog("manual cmd - det ");
writeLog(" det[", d, "]: ");
writeLog(" old=", detSoftwareStateOld[d], " new=", detSoftwareState[d]);
} // END IF // for d
} // // END IF cmd = d dets
if (cmd[0] == 'W') { // IF cmd = w set sigs WB
//digitalWrite(SingleLineRelayPin, HIGH); // sets the digital pin 13 on - test relays - inner/car 2 WB
//sglLineState = 'W';
//fncmd[1] = "cmd w";
////strcpy(fncmd[1], );
setSingleLineState('W', "Manual cmd w");
} // // END IF cmd = w set sigs WB
if (cmd[0] == 'E') { // IF cmd = e set sigs EB
//digitalWrite(SingleLineRelayPin, LOW); // sets the digital pin 13 off i outer / car 1 EB
//sglLineState = 'E';
//fncmd[1] = "(cmd e";
////strcpy(fncmd[1], );
setSingleLineState('E', "Manual cmd e");
} // // END IF cmd = e set sigs EB
if (cmd[0] == 'C') { // IF cmd = c set sigs CL
//digitalWrite(SingleLineRelayPin, LOW); // sets the digital pin 13 off i outer / car 1 EB
//sglLineState = 'C';
//fncmd[1] = "cmd c";
////strcpy(fncmd[1], );
setSingleLineState('C', "Manual cmd c");
} // // END IF cmd = c set sigs CL
// end all code to process input here
cmd[0] = 0;
writeLog("End process mySerial-------------------------------------------------------");
} // ---------------------------------------- END PROCESS mySerial
void setSingleLineState(char PsglLineState, char* event) { // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
strcpy(sCurrentProc , "ProcessSerial");
if (true){ // IF bDebugging
writeLog( " Called By: ", event, " Sgl Line State Now: ", PsglLineState);
} // END IF bDebugging
if (PsglLineState == 'E') { // if set EB
digitalWrite(eSigGpin, LOW); //E SIG GN
digitalWrite(eSigRpin, HIGH); // E SIG RED
digitalWrite(wSigGpin, HIGH); // W SIG GRN
digitalWrite(wSigRpin, LOW); // W SIG RED
digitalWrite(SingleLineRelayPin, LOW);
} // // END IF set EB
if (PsglLineState == 'W') { // IF set WB
digitalWrite(eSigGpin, HIGH); //E SIG GN
digitalWrite(eSigRpin, LOW); // E SIG RED
digitalWrite(wSigGpin, LOW); // W SIG GRN
digitalWrite(wSigRpin, HIGH); // W SIG RED
digitalWrite(SingleLineRelayPin, HIGH);
} // // END IF set WB
if (PsglLineState == 'C') { // if set CL
digitalWrite(eSigGpin, LOW); //E SIG GN
digitalWrite(eSigRpin, LOW); // E SIG RED
digitalWrite(wSigGpin, LOW); // W SIG GRN
digitalWrite(wSigRpin, LOW); // W SIG RED
digitalWrite(SingleLineRelayPin, LOW);
} // END IF set CL
sglLineState = PsglLineState; // added 2025-08-19 a/c not being set
writeLog(millis());
writeLog(" In setSingleLineState sglLineState now set to ", sglLineState);
} // // END PROC setSingleLineState
unsigned long tdiffOld;
void chkCarAction() { //VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/ BEGIN chkCarAction
strcpy(sCurrentProc, "chkCarAction");
int carNum;
/* printVar(486, "carNum", "1");
printVar(487, "carAction", carAction[1]);
printVar(488, "carNum", "2");
printVar(489, "carAction", carAction[2]); */
for (carNum = 1; carNum <= 2; carNum++) { // BEGIN for each car main loop
writeLog("Running chkCarAction Car ", carNum);
// strncmp() function returns zero when the two strings are same up to n chars and non-zero when they are different
// IF CAR BRAKING
if (strncmp(carAction[carNum], "BSIG", 4) == 0 || strncmp(carAction[carNum], "BMAN", 4) == 0 || strncmp(carAction[carNum], "BSTP", 4 ) == 0 ) { //
writeLog("538 car");
writeLog(carNum, " Action: ", carAction[carNum]);
//strcpy(sDoing , "Process Car Braking");
// add condition else calls processCarBraking when car not in braking mode - no - carAction not set to COST when speed 0
processCarBraking(carNum);
} // END IF carAction BRAKING
// start car after stop at sig if line clear -----------------------------------------------
if (strncmp(carAction[carNum] , "LSIG", 4) == 0) {//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvBEGIN if loading sig
if (millis() - stopTimer1 > 5000) {
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "WSIG", "Loading timer exp");
} // END IF stop timer expired
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END IF loading sig
writeLog("445"); // debug
// 2025-08-18T16:28 was continuing to brake at ESIG a/c 2nd condn not present
if (strncmp(carAction[carNum], "LSTP", 4) == 0) { //vvvvvvvvvvvvvvvvvvvvvvvv BEGIN if loading stop
if (millis() - stopTimer1 > 5000) { //vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvBEGIN if stop timer expired
//strcpy(carActionOld[carNum], carAction[carNum]);
writeLog("547 Car ", carNum);
updateCarAction(carNum, "ACCL", "Stop timer expired"); // starting from stop not at signal
writeLog("550 Car ", carNum, " now ACCL");
//accelSpdChMillis[carNum] = millis(); // stop timer expired
//strcpy(fnParam[1] , "Start from Stop ");
////printCarStatus(carNum, "Start from Stop ");
//writewriteLog(carNum, carAction[carNum]);
} //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END IF stop timer exp
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END IF loading stop
if (strncmp(carAction[carNum], "WSIG", 4) == 0 ) { // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV BEGIN IF waiting sig
if (carNum == 1) {
if (sglLineState == 'C') {
sglLineState = 'E';
////strcpy(fnParam[1] , );
// set sig if car was waiting line clear
setSingleLineState('E', "Car 1 was waiting sig"); // 565 was waiting and line now clear in chkCarAction
}
if (sglLineState == 'E') {
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "ACCL", "Signal Cleared");
////strcpy(fnParam[1] , "Sig cleared");
////printCarStatus(1, "Start from Stop ");
} // END IF EB
} // END IF car 1
if (carNum == 2) {
if (sglLineState == 'C') {
//sglLineState = 'W';
////strcpy(fnParam[1] , );
setSingleLineState('W', "Car 2 was waiting sig");
}
if (sglLineState == 'W') {
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "ACCL", "Signal cleared");
////strcpy(fnParam[1], "Sig cleared");
//printCarStatus(2, "Sig cleared");
} // END IF WB
} // END IF car 2
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END IF WSIG
/* if (strncmp(carAction[carNum], carActionOld[carNum], 4) != 0 ) {
} */
if (strncmp(carAction[carNum], "ACCL", 4) == 0) { // and others
unsigned long tdiff = millis() - accelSpdChMillis[carNum];
writeLog("-------------------------------------------------------------");
writeLog("614 car no. is ");
writeLog( carNum);
writeLog("617 tdiff: ", tdiff, " 621 prev accel ch start: ", accelSpdChMillis[carNum]);
writeLog(" 623 millis now: ", millis(), " Speedidx: ", speedIdx[carNum]);
// was 300
if (tdiff > 5000) { //stimes[speedIdx[carNum]] ) { // 2025-05-21 - fixed why change it? - was stimes meant for BB?
if (speedIdx[carNum] < 5) {
speedIdx[carNum] += 1;
carSpeed[carNum] = speeds[speedIdx[carNum]];
accelSpdChMillis[carNum] = millis();
writeLog( "accelSpdChMillis now= ", static_cast<char>(accelSpdChMillis[carNum]), " 530 speed: ", static_cast<char>(speeds[speedIdx[carNum]]));
//digitalWrite(MotorSpeedPin[carNum], HIGH);
analogWrite(MotorSpeedPin[carNum], carSpeed[carNum]); // car accelertaing
//strcpy(fnParam[1] , "601 accelerating");
//printCarStatus(carNum, "631 accelerating" );
}
if (speedIdx[carNum] == 5) {
writeLog("540 speed ", "", static_cast<char>(speeds[speedIdx[carNum]]));
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "COST", "Full speed reached");
////strcpy(fnParam[1] , "578 Max spd reached");
//printCarStatus(carNum, "678 Max spd reached"); ////printCarStatus doesnt" print Called By after this -
}
else { // not at 5 yet - covered above
}
} // END IF time for increment // speedIdx[carNum] <5
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END IF carAction == "A"
//strcpy(carActionOld[carNum], carAction[carNum]);
} // FOR carNum
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^END chkCarAction
void updateCarAction(int carNum, char *sNewCarAction, char *sReason) {
strcpy(sCurrentProc, "updateCarAction");
writeLog(" 677 In updateCarAction: Car ", carNum, " Old Action: ", carActionOld[carNum]);
strcpy(carActionOld[carNum], carAction[carNum]);
strcpy(carAction[carNum], sNewCarAction);
//2025-08-24T16:11
if (strncmp(carAction[carNum], "ACCL", 4) == 0) {
accelSpdChMillis[carNum] = millis();
writeLog("679 in updateCarAction car ", carNum, " accelSpdChMillis= ", accelSpdChMillis[carNum]);
}
}
void chkDets() {
strcpy(sCurrentProc , "chkdets");
writeLog("Running chkDets", "chkg dets");
bool bdetch = false;
int s;
// save hw state every loop - if changed, save change time start timer
// if not changed, read timer and act if time exceeded
// don't need detHardwareStateConfirmed[??
for (int dc = 1; dc < 5; dc++) { // CHANGE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
// check for det stuck occ
//bDetHWchanged[dc] = false;
//if (bDebugging){//detSoftwareState[dc] == 'X' && millis() - detOccTime[dc] > 5000 ) {
writeLog("811 Chkng Det HW: ", dc);
//}
int s = digitalRead(detPins[dc]);
// if (dc == 4) { //bDebugging) {
writeLog("715 Det ", dc, " HW state: ", s);
// }
// detHardwareStateConfirmed is set after timeout
// detHardwareStatePrevLoop is last reading of pin
if (s != detHardwareStatePrevLoop[dc]) {
detchTime[dc] = millis();
bDetHWchanged[dc] = true;
//if (dc == 4) {
//static_cast<char>(A);
writeLog("801 HW Det ", static_cast<char>(dc), " ch at ", static_cast<char>(detchTime[dc]), " to ", static_cast<char>(s));
// ? only when car over det 1
/* 801 HW Det 1 ch at 81265390 to 0
801 HW Det 1 ch at 81265426 to 1 */
//}
detHardwareStatePrevLoop[dc] = s;
continue;
}
if (bDetHWchanged[dc]) {
writeLog("742 detHardwareStatePrevLoop=", detHardwareStatePrevLoop[dc]);
//}
//if(s == detHardwareStatePrevLoop[dc]) { // we know det hasn't changed here if bDetHWchanged is false
//det HARDWARE state not changed how long in this state?
// avoiding bounce?
//detHardwareStatePrevLoop[dc] = s;
unsigned long diff = millis() - detchTime[dc];
if (dc == 4) {
}
if (bDebugging) {
writeLog("635 detchTime ", static_cast<char>(detchTime[dc]));
}
if (diff < 150) { // TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2000 too long to det blue car at 4
writeLog("864 ");
continue;
}
if (dc == 2) {
}
if (bDebugging) {
writeLog("647 detchTime ", static_cast<char>(detchTime[dc]));
}
/* if (diff < 200) { // TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2000 too long to det blue car at 4
// not timeout yet
//continue;
} */
//bDetHWchanged[dc] = false;
if (s == 1) {
detSoftwareState[dc] = 'U';
}
else {
detSoftwareState[dc] = 'X';
}
if (detSoftwareStateOld[dc] != detSoftwareState[dc]) { // so no debug during timeout
writeLog(" In chkDets: Det ", dc, " software now ", detSoftwareState[dc]);
writeLog("D", dc, "=", detSoftwareState[dc]);
processDetChange(dc);
detSoftwareStateOld[dc] = detSoftwareState[dc];
}
// }
} // if hardware state unchanged
//detHardwareStateConfirmed[dc] = s; // set this every time to avoid multiple reports of same state
} // for dc
} // chkdets
void processDetChange(int detChanged) {
strcpy(sCurrentProc, "processDetChange");
// ACT ON CHANGED DET
bool bDetCh = false;
//int dx = 1;
// already reported in chkDets
writeLog(" In processDetChange detChanged = ");
writeLog(detChanged, " Now ", detSoftwareState[detChanged]);
if (detChanged == 1) {
bDetCh = true;
if (detSoftwareState[detChanged] == 'X') {
updateCarAction(1, "BSTP", "processDetChange: Det occ");
strcpy(carActionOld[1] , carAction[1]);
strcpy(carAction[1] , "BSTP");
carLocation[1] = 1;
writeLog("In processDetChange: Car: 1 Location: 1");
}
if (detSoftwareState[detChanged] == 'U') {
//strcpy(sglLineState, 'C');
setSingleLineState('C', "Det 1 clr");
}
} // end dx = 1
if (detChanged == 4) {
bDetCh = true;
// DET 4 CH
if (detSoftwareState[detChanged] == 'X') {
writeLog("In processDetChange 946: Car: 1 @ Det 4");
updateCarAction(1, "BSIG", "processDetChange: Det occ");
strcpy(carActionOld[1] , carAction[1]);
strcpy(carAction[1] , "BSIG");
carLocation[1] = 4;
if (sglLineState == 'C') {
setSingleLineState('E', "Car 1 at Det 4"); // 953 in processDetChange
// strcpy("carAction
}
else {
//strcpy
writeLog("Car 1 waiting line clear");
}
}
} // end dx = 4
//----------------------------------------------END 1 & 4---------------------------
//dx = 3; //------------------------- DET 3
// if (detSoftwareState[detChanged] != detSoftwareStateOld[detChanged]) {
if (detChanged == 3) {
//detChangedTime[detChanged] = millis();
bDetCh = true;
//strcpy(fnParam[1] , "Det 3 changed:");
//printDetState(dx, "Det 3 changed:");
strcpy(detSoftwareStateOld[detChanged], detSoftwareState[detChanged]); // MOVE TO END OF THIS PROC???????????????????????????????////
//if (bDebugging) {
writeLog("973 Det 3 SW now ", detSoftwareState[detChanged]);
// }
if (detSoftwareState[detChanged] == 'X') {
updateCarAction(2, "BSTP", "Det occ");
strcpy(carActionOld[2] , carAction[2]);
strcpy(carAction[2] , "BSTP");
carLocation[2] = 3;
writeLog("Car: 2 Location: 3");
//strcpy(fnParam[1] , "Det 3 occ");
//printCarStatus(2 , "934 Det 3 occ");
}
if (detSoftwareState[detChanged] == 'U') {
//strcpy(sglLineState, 'C');
////strcpy(fnParam[1] , "Det 3 clr");
setSingleLineState('C', "processDetChange: Det 3 clr");
}
} // end det 3
if (detChanged == 2) {
//detChangedTime[detChanged] = millis();
bDetCh = true;
if (detSoftwareState[detChanged] == 'X') {
// car 1 outer approach // STAGE 2
writeLog("In processDetChange: Car: 2 @ Det 2");
updateCarAction(2, "BSIG", "Det occ");
carLocation[2] = 2;
writeLog("Car: 2 Location: 2");
if (sglLineState == 'C') {
setSingleLineState('W', "Car 2 at det 2");
}
else {
//strcpy
writeLog("Car 2 waiting line clear");
} // END IF
} // det occ
}// end det 2 changed
}
void processCarBraking(int carNum) {
strcpy(sCurrentProc, "chkCarAction");
unsigned long tdiff;
unsigned long tNow = millis();
// with 12 V and max speed = 9 - both cars w/o trailer
tdiff = 300; // default 300 car 2 stops immed clear of det 3 but max speed was ? 10
// Set braking speed-change intervals - see next
if (carNum == 1 && carLocation[carNum] == 4) { // SL ENTRY
//tdiff = 275; // 2025-05-13 to //delay initial BB was 1000 b4 tk clng 2025-05-16
}
else if (carNum == 1 && carLocation[carNum] == 1) { // SL EXIT
//tdiff = 475;
} // if car 1 at det 1
// Initiate braking
if (brakingStarted[carNum] == 'N' ) {
brakeStartMillis[carNum] = tNow;
writeLog("1115 braking started");
brakingStarted[carNum] = 'Y';
writeLog(" In processCarBraking: Braking started for car ", carNum);
speedIdx[carNum]-= 1; // init first braking step
//continue; // next car
return;
} // end if brakingStarted = N
// HERE IF BRAKING HAS STARTED
// CHANGE SPEED IN BRAKING
writeLog(" In processCarBraking car ");
writeLog(carNum, "Braking started");
if (tNow - brakeStartMillis[carNum] > tdiff) { // BEGIN IF TIMER EXPIRED - 1st speed redn
writeLog( " 833 processCarBraking Car ", static_cast<char>(carNum), " Speed: ", static_cast<char>(speeds[speedIdx[carNum]]));
if (speedIdx[carNum] > 0) { // BEGIN IF SPEED > 0
speedIdx[carNum] -= 1;
carSpeed[carNum] = speeds[speedIdx[carNum]];
//printCarSpeed(416, carNum, "BB speed dec");
analogWrite(MotorSpeedPin[carNum], carSpeed[carNum]); // set speed BB
brakeStartMillis[carNum] = millis(); // reset BB timer was cmtd out - why??
////strcpy(fnParam[1] , "431 Now BB");
//printCarStatus(carNum, "BRAKING" ); // BB speed < 5
//if (tdiff != tdiffOld) {
writeLog("tdiff old : ", tdiffOld);
writeLog(" tdiff now : ", tdiff);
tdiffOld = tdiff;
writeLog("tdiffold now : ", tdiffOld);
//}
writeLog("565: ", millis());
} // END CHANGE SPEED IN BRAKING
else { // ELSE car stopped: speedIdx[carNum] = 0
brakingStarted[carNum] = 'N';
writeLog(" 1149 In processCarBraking: Car ");
writeLog(carNum, " now stopped");
if (strncmp(carAction[carNum], "BSIG", 4) == 0) { // BEGIN IF BSIG
//strcpy(carActionOld[carNum], carAction[carNum] );
updateCarAction(carNum, "LSIG", "Braking finished");
// don"t need cmt - actionold printed in printCarAction
//printCarAction("", carNum, "");
////strcpy(fnParam[1] , "now loading sig");
//printCarStatus(carNum, "550 now loading sig"); // loading sig
writeLog("1154 LSIG Car ", carNum);
if (carNum == 1) {
//carLocation[carNum] = 4 ;
}
stopTimer1 = millis();
writeLog(" Location ", carLocation[carNum]);
} // // END IF BS
// restart car from stop not at sig - need to
// 2025-04-12 why if carNum == 1???? condition removed
if (strncmp(carAction[carNum], "BSTP", 4) == 0) { // BEGIN IF BSTP
//carLocation[carNum] == "4 BB")
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "LSTP", "Braking finished");
//printCarAction("", carNum, "");
//carLocation[carNum] = 4;
stopTimer1 = millis();
////strcpy(fnParam[1], "now BB stop");
//printCarStatus(carNum, "1189 now BB stop");
} // END IF BP
writeLog("417"); // debug
if (strncmp(carAction[carNum], "BMAN", 4) == 0) { // manual cmd - inclu above // BEGIN IF BB MANUAL
//strcpy(carActionOld[carNum], carAction[carNum]);
updateCarAction(carNum, "NNNN", "Braking manual");//, "1193 carAction set to NNNN");
} // END IF BB MANUAL
} // END ELSE CAR STOPPED
} // END IF BRAKE TIMER EXPIRED
}