int Cell_1_ADC1; int Cell_1_ADC2; int Cell_1_ADC3; int Cell_1 = A0; float Cell_1_Temp; int Cell_2_ADC1; int Cell_2_ADC2; int Cell_2_ADC3; int Cell_2 = A2; float Cell_2_Temp; int BusBar_ADC1; int BusBar_ADC2; int BusBar_ADC3; int BusBar = A1; float BusBar_Temp; int volt_ADC1; int volt_ADC2; int volt_ADC3; int volt_input = A3; float battery_volts; int interval_1 = 100; int Task = 0; unsigned long Time = 0; unsigned long LastTime = 0; boolean Task_1_Done = LOW; boolean Task_2_Done = LOW; boolean Task_3_Done = LOW; boolean Task_4_Done = LOW; boolean Task_5_Done = LOW; boolean Task_6_Done = LOW; int enableLoad = 9; int maxBusBarTemp = 100; // maximum temp for busbar. Test will stop if exceeded int maxCellTemp = 80; // maximum temp for cells. Test will stop if exceeded int MinBattV = 11; // minimum battery voltage. Test will stop if below boolean syatemSafe = LOW; // system is safe if high boolean runTest = LOW ; // enables load when high int secondsSinceStart = 0; char serialIn; // contains ascii from serial byte int stateCase = 0; // state machine state int statePosition = 0; // state machine state boolean dataError = LOW; // will go high if unexpected data is recieved in serial buffer static char buffer[5]; boolean expectNumeric = LOW; // will pass data into buffer rather than run through state machine when high boolean newNumericData = LOW; // will be high when a new numeric value has been recieved float numericData = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(enableLoad, OUTPUT); digitalWrite(enableLoad, LOW); } void loop() { //---------------------------------------------------------------------------- // Sequences Tasks //---------------------------------------------------------------------------- Time = millis(); if ((Time - LastTime) > interval_1) { LastTime = Time; Task++; if (Task >= 10) { Task = 0; Task_1_Done = LOW; Task_2_Done = LOW; Task_3_Done = LOW; Task_4_Done = LOW; Task_5_Done = LOW; Task_6_Done = LOW; } } //---------------------------------------------------------------------------- // Check for data //---------------------------------------------------------------------------- if (Serial.available() > 0) { // read the incoming byte: serialIn = Serial.read(); Serial.print(serialIn); // Loopback //if (expectNumeric == LOW) { serialStateMachine(serialIn); //} /*else { readNumeric(serialIn, buffer, 5); if (newNumericData == HIGH) { float test = atoi(buffer); test = test / 100.00; Serial.println(); Serial.print("you entered "); Serial.println(test); newNumericData = LOW; expectNumeric = LOW; } }*/ } /* if(serialIn == 104){ Serial.println("thanks for the h"); stateCase = 1; statePosition = 1; } else { Serial.println("unknown command"); stateCase = 0; statePosition = 0; } if(serialIn == 101 && stateCase == 1 && statePosition == 1){ stateCase = 1; statePosition = 2; } else { Serial.println("unknown command"); stateCase = 0; statePosition = 0; } } */ //---------------------------------------------------------------------------- // Read ADC's //---------------------------------------------------------------------------- if (Task == 1 && Task_1_Done == LOW) { Cell_1_ADC1 = analogRead(Cell_1); Cell_2_ADC1 = analogRead(Cell_2); BusBar_ADC1 = analogRead(BusBar); volt_ADC1 = analogRead(volt_input); Task_1_Done = HIGH; } if (Task == 2 && Task_2_Done == LOW) { Cell_1_ADC2 = analogRead(Cell_1); Cell_2_ADC2 = analogRead(Cell_2); BusBar_ADC2 = analogRead(BusBar); volt_ADC2 = analogRead(volt_input); Task_2_Done = HIGH; } if (Task == 3 && Task_3_Done == LOW) { Cell_1_ADC3 = analogRead(Cell_1); Cell_2_ADC3 = analogRead(Cell_2); BusBar_ADC3 = analogRead(BusBar); volt_ADC3 = analogRead(volt_input); Task_3_Done = HIGH; } //---------------------------------------------------------------------------- // Calculate Actual Temps //---------------------------------------------------------------------------- if (Task == 4 && Task_4_Done == LOW) { Cell_1_Temp = (Cell_1_ADC1 + Cell_1_ADC2 + Cell_1_ADC3); Cell_1_Temp = scaleTempSensor(Cell_1_Temp); Cell_2_Temp = (Cell_2_ADC1 + Cell_2_ADC2 + Cell_2_ADC3); Cell_2_Temp = scaleTempSensor(Cell_2_Temp); BusBar_Temp = (BusBar_ADC1 + BusBar_ADC2 + BusBar_ADC3); BusBar_Temp = scaleTempSensor(BusBar_Temp); battery_volts = (volt_ADC1 + volt_ADC2 + volt_ADC3); battery_volts /= 3; battery_volts = (battery_volts * 0.004955) * 5; } //---------------------------------------------------------------------------- // Print Analogues //---------------------------------------------------------------------------- if (Task == 5 && Task_5_Done == LOW) { if (runTest) { Serial.print(secondsSinceStart); Serial.print(","); PrintSensors(); secondsSinceStart ++; } Task_5_Done = HIGH; } //---------------------------------------------------------------------------- // Check Safe //---------------------------------------------------------------------------- if (Task == 6 && Task_6_Done == LOW) { if (runTest) { if (CheckSafety() == LOW) { Task_6_Done = HIGH; runTest = LOW; Serial.println("Test Stopped"); } } } if (runTest == HIGH) { digitalWrite(enableLoad, HIGH); } else { digitalWrite(enableLoad, LOW); } } //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Functions //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------- // SerialStateMachine //---------------------------------------------------------------------------- int serialStateMachine(int input) { switch (serialIn) { case 97: // 97 = a if (stateCase == 2 && statePosition == 2) { stateCase = 2; statePosition = 3; } else { dataError = HIGH; } break; /*case 99: // 99 = c if (stateCase == 3 && statePosition == 2) { stateCase = 3; statePosition = 3; } else if (stateCase == 0 && statePosition == 0) { stateCase = 4; statePosition = 1; } else { dataError = HIGH; } break;*/ case 101: // 101 = e if (stateCase == 1 && statePosition == 1) { stateCase = 1; statePosition = 2; } else { dataError = HIGH; } break; case 104: // 104 = h if (stateCase == 0 && statePosition == 0) { stateCase = 1; statePosition = 1; } else { dataError = HIGH; } break; /*case 105: // 105 = i if (stateCase == 3 && statePosition == 1) { stateCase = 3; statePosition = 2; } if (stateCase == 4 && statePosition == 6) { stateCase = 4; statePosition = 7; } else { dataError = HIGH; } break;*/ case 108: // 108 = l if (stateCase == 1 && statePosition == 2) { stateCase = 1; statePosition = 3; } else { dataError = HIGH; } break; /*case 109: // 109 = m if (stateCase == 4 && statePosition == 5) { stateCase = 4; statePosition = 6; } else { dataError = HIGH; } break;*/ /*case 110: // 110 = n if (stateCase == 4 && statePosition == 7) { stateCase = 4; statePosition = 8; } else { dataError = HIGH; } break;*/ /* case 111: // 111 = o if (stateCase == 2 && statePosition == 4) { stateCase = 2; statePosition = 5; } else { dataError = HIGH; } break;*/ case 112: // 112 = p if (stateCase == 1 && statePosition == 3) { stateCase = 1; statePosition = 4; } else { dataError = HIGH; } break; case 114: // 114 = r if (stateCase == 2 && statePosition == 3) { stateCase = 2; statePosition = 4; } else { dataError = HIGH; } break; case 115: // 115 = s if (stateCase == 0 && statePosition == 0) { stateCase = 2; statePosition = 1; } else { dataError = HIGH; } break; case 116: // 116 = t if (stateCase == 2 && statePosition == 1) { stateCase = 2; statePosition = 2; } else if (stateCase == 2 && statePosition == 4) { stateCase = 2; statePosition = 5; } else { dataError = HIGH; } break; /* case 117: // 117 = u if (stateCase == 3 && statePosition == 4) { stateCase = 3; statePosition = 5; } else { dataError = HIGH; } break;*/ /* case 118: // 118 = v if (stateCase == 4 && statePosition == 4) { stateCase = 4; statePosition = 5; } else { dataError = HIGH; } break;*/ case 13: // 13 = CR CheckInput(); break; default: stateCase = 0; statePosition = 0; break; } } //---------------------------------------------------------------------------- // Scale temp sensors a = resistance @ 25°C b = beta value. //---------------------------------------------------------------------------- float scaleTempSensor(float x) { int a = 10000; int b = 3950; x /= 3; x = (1023 / (x) - 1); x = a / x; x /= a; x = log(x); x /= b; x += 1.0 / (25 + 273.15); x = 1.0 / x; x -= 273.15; return x; } //---------------------------------------------------------------------------- // Read Temp Sensor //---------------------------------------------------------------------------- int readTempSensor (int x) { int TempVal = analogRead(x);//analogRead(x); return TempVal; } //---------------------------------------------------------------------------- // Check result from state machine //---------------------------------------------------------------------------- int CheckInput() { if (stateCase == 1 && statePosition == 4 && dataError == LOW) { PrintHelp(); stateCase = 0; statePosition = 0; } else if (stateCase == 2 && statePosition == 5 && dataError == LOW) { Serial.println(); Serial.println("Testing Start Conditiions"); PrintSensors(); if (CheckSafety() == HIGH) { Serial.println("Start Conditions Safe"); runTest = HIGH; secondsSinceStart = 0; // set test timer to zero Serial.println("Test Running"); } else { Serial.println("START CONDITIONS NOT SAFE"); runTest = LOW; } stateCase = 0; statePosition = 0; } else { if (runTest == HIGH) { runTest = LOW; Serial.println("Test Stopped"); } else { Serial.println(); Serial.println("unknown command"); Serial.println(">"); stateCase = 0; statePosition = 0; dataError = LOW; } } } //---------------------------------------------------------------------------- // Serial Print Things //---------------------------------------------------------------------------- int PrintSensors() { Serial.print("Cell 1 Temp=,"); Serial.print(Cell_1_Temp); //Serial.println(",C"); Serial.print(",Cell 2 Temp=,"); Serial.print(Cell_2_Temp); //Serial.println("C"); Serial.print(",BusBar Temp=,"); Serial.print(BusBar_Temp); //Serial.println(" C"); Serial.print(",Battery Volts=,"); Serial.print(battery_volts); Serial.println(","); //Serial.println(" V"); } int PrintHelp() { Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Serial.println("Rory's Discharge Datalogger - Help"); Serial.println(); Serial.println(); Serial.println("help - returns command list"); Serial.println("start - starts discharge test"); Serial.println("enter - stops test"); Serial.println(); Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Serial.println(">"); } /*int PrintCellSet() { Serial.println(); Serial.print("enter value xx.xx>"); expectNumeric = HIGH; }*/ //---------------------------------------------------------------------------- // adds numeric ascii to buffer, avoids decimal places //---------------------------------------------------------------------------- /* int readNumeric(int readch, char *buffer, int len) { static int pos = 0; int rpos; if (readch > 0 && isDigit(readch) || readch == 13 ) { switch (readch) { case '\n': // Ignore new-lines break; case 46: // Ignore decimal places break; default: if (pos < len - 1) { buffer[pos++] = readch; buffer[pos] = 0; } } } if (readch == 13 ) { rpos = pos; pos = 0; // Reset position index ready for next time newNumericData = HIGH; } }*/ //---------------------------------------------------------------------------- // Checks Safety Of System //---------------------------------------------------------------------------- int CheckSafety() { int a; int b; int c; int d; int e = HIGH; if (Cell_1_Temp >= maxCellTemp) { a = LOW; } else { a = HIGH; } if (Cell_2_Temp >= maxCellTemp) { b = LOW; } else { b = HIGH; } if (BusBar_Temp >= maxBusBarTemp) { c = LOW; } else { c = HIGH; } if (battery_volts <= MinBattV) { d = LOW; } else { d = HIGH; } if (a == HIGH && b == HIGH && c == HIGH && d == HIGH) { e == HIGH; } else { e = LOW; } return e; }