#include <EEPROM.h>
/*
TO DO
- Check 24VDC status
- Proper .csv logging format w/ toggle
*/
#define ERROR_STATE 99
#define FINISHED_STATE 50
//Pins
const int PUMPS_PIN = 10; //Pump control PWM signal goes to DIN rail mounted Crydom MOSFET-ish
const int FAN_PIN = 11; //Fanc control PWM signal goes to DIN rail mounted Crydom MOSFET-ish
/////////////////// FUNCTION INITS ///////////////////
void serialReciever();
void printInstructions();
bool isValidPwmNumber(char input[32]);
bool isValidPwmCommand(char input[32]);
void printEndMarker();
void runPumps(uint8_t _pwm);
void runFan(uint8_t _pwm);
// TaskScheduler Callback methods:
void logTaskCallback();
void readFlowTaskCallback();
/////////////////// VARIABLES ///////////////////
uint8_t state = 0;
uint32_t stateTimer = 0;
uint32_t currentMillis, lastMillis;
uint8_t fanPwm = 0;
uint8_t fanMaxPwm = 100;
uint8_t pumpsPwm = 0;
char pwmCommandPrefix[] = {'p', 'f'};
const int eeAddress1 = 4;
uint32_t cycleNumber;
uint32_t numberToBeReached = 10000;
uint32_t lastSave;
uint32_t saveNumber;
String errorMessage;
uint32_t f = 0; //EEPROM storage bullshit
bool runProgram = false;
bool log1 = false;
bool log2 = false; //second pressure sensor
bool csvLogFlag = false;
bool fastLog = false; //log flag for fast logging during pressure rise
//Serial reading
const byte numChars = 32;
char receivedChars[numChars];
bool newData = false;
bool sendEcho = false;
char endMarker = '\n';
/////////////////// SETUP ///////////////////
void setup() {
pinMode(FAN_PIN, OUTPUT);
pinMode(PUMPS_PIN, OUTPUT);
//PINMODE FOR FLOW INTERRUPTS??
Serial.begin(115200);
//Boot sequence
Serial.println(' ');
Serial.println("...booting");
printEndMarker();
printInstructions();
}//end setup
/////////////////// LOOP ///////////////////
void loop() {
currentMillis = millis();
if (runProgram == true) {
switch (state) {
case 0://START STATE RUNS ONCE
Serial.println("---------------");
Serial.println("no program");
stateTimer = currentMillis;
state++;
break;
case 1://WAIT STATE
if( currentMillis >= stateTimer + 1000){
state == FINISHED_STATE;
}
break;
case FINISHED_STATE:
Serial.println("Program finished!");
runProgram = false;
csvLogFlag = false;
break;
case ERROR_STATE://ERROR STATE, REQUIRES MANUAL RESET TO GET OUT OF
Serial.println(errorMessage);
runProgram = false;
break;
}//end program switch
}//end of program
if(fanPwm > 125 ) {fanPwm = 0; } //turn off fan if accidentally try and feed it more than 12V
serialReciever();
}//end loop
void runPumps(uint8_t _pwm){
pumpsPwm = _pwm;
analogWrite(PUMPS_PIN, pumpsPwm);
}
void runFan(uint8_t _pwm){
fanPwm = _pwm;
analogWrite(FAN_PIN, fanPwm);
}
/////////////////// SERIAL COMMUNICATION ///////////////////
void printEndMarker(){
if( endMarker == '\n' ){ Serial.println("New Line must be used as end marker"); }
if (endMarker == '\r' ){ Serial.println("Carriage Return must be used as end marker"); }
}
bool isValidPwmNumber(char input[32]){
for( int i=0 ; i<32 ; i++){
if( !isdigit(input[i]) && input[i] != '\0' ){
//Serial.print("Char at index ");
//Serial.print(i);
//Serial.println(" was not a digit");
return false;
break;
}
}
if( atoi(input) > 255 ){
Serial.println("255 is max value for PWM");
return false;
}
else { return true; }
}
bool isValidPwmCommand(char firstChar, String inputSub){
int numberOfCommands = 2;
int a = 1;
/*
Serial.print("firstChar = ");
Serial.println(firstChar);
Serial.print("inputSub.toInt() = ");
Serial.println(inputSub.toInt() );
*/
switch (a){
case 1: //check if first char is in pwmCommandPrefix arry, if yes move on
bool continueFlag = false;
for(int i=0 ; i<numberOfCommands ; i++ ){
if( firstChar == pwmCommandPrefix[i] ){
continueFlag = true;
}
}
if(continueFlag){ a++; }
else{
//Serial.println("case 1 goto");
goto bailout;
}
case 2: //check if rest of input is digits
if( inputSub.toInt() || inputSub.charAt(0) == '0' ){
//Serial.println("inside case 2 if");
a++;
}
else{
//Serial.println("case 2 goto");
goto bailout;
}
case 3: //check if input is <= 255
if( inputSub.toInt() <= 255){
return true;
}
else{
Serial.println("Max PWM value is 255");
goto bailout;
}
}
bailout:
return false;
}
void serialReciever(){
//Recieve data over serial
static byte ndx = 0;
char rc;
//Recieve stuff with end marker
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
ndx = 0;
newData = true;
}
}
//Do stuff with data
if (newData == true) {
String receivedString = receivedChars;
String receivedSubString = receivedString.substring(1);
if(sendEcho){
Serial.print("ECHO: ");
Serial.println(receivedChars);
}
/////////////////// Start of the might command-handler if/else-if
if( isValidPwmCommand(receivedChars[0], receivedSubString) ){
if( receivedChars[0] == 'p' ){
runPumps( receivedSubString.toInt() );
}
else if( receivedChars[0] == 'f' && receivedSubString.toInt() <= fanMaxPwm ){
runFan(receivedSubString.toInt());
}
else if(receivedChars[0] == 'f' && receivedSubString.toInt() > fanMaxPwm){
Serial.print("Max PWM for fan is ");
Serial.println(fanMaxPwm);
}
}
else if(strcmp(receivedChars, "beep") == 0) {
Serial.println("boop");
}
else if(strcmp(receivedChars, "echo") == 0){
sendEcho = !sendEcho;
if(sendEcho){ Serial.println("Serial echo tured ON"); }
else { Serial.println("Serial echo turned OFF"); }
}
else if(strcmp(receivedChars, "help") == 0){
printInstructions();
}
else if(strcmp(receivedChars, "eeprom") == 0) {
EEPROM.get(eeAddress1, f);
Serial.print("Saved number in EEPROM: ");
Serial.println(f);
}
else if(strcmp(receivedChars, "eepromclear") == 0) {
Serial.println("Clearing EEPROM...");
for (int i = 0 ; i < EEPROM.length() ; i++) {
EEPROM.write(i, 0);
}
Serial.println("EEPROM cleared");
}
else if(strcmp(receivedChars, "start") == 0) {
EEPROM.get(eeAddress1, f);
if( cycleNumber == 0 && f > 0){
cycleNumber = f;
}
log1 = false;
runProgram = true;
}
else if(strcmp(receivedChars, "stop") == 0) {
runProgram = false;
}
else if(strcmp(receivedChars, "reset") == 0) {
runProgram = false;
state = 0;
fanPwm = 0;
cycleNumber = 0;
lastSave = 0;
}
else if(strcmp(receivedChars, "off") == 0) {
runPumps(0);
runFan(0);
Serial.println("Pump & fan pwm set to 0");
}
else if(strcmp(receivedChars, "cycle") == 0) {
Serial.println(cycleNumber);
}
else{
Serial.println("Command not recognized");
}
//Set char array to null for safety
for( int i=0 ; i<32 ; i++){
receivedChars[i] = '\0';
}
newData = false;
}
}
void printInstructions(){
Serial.println("---------------------------------------------------------");
Serial.println("Available commands are as follows:");
Serial.println(' ');
Serial.println("help = prints list of commands");
Serial.println("echo = turns on/off serial echo (off by def)");
Serial.println("log = enables logTask");
Serial.println("eeprom = prints number saved in eeprim");
Serial.println("eepromclear = clears eeprom DO AT YOUR OWN RISK");
Serial.println("start = Starts the test cycle");
Serial.println("stop = Stops the test cycle");
Serial.println("reset = Resets state machine");
Serial.println("[Any number between 0 and 255]p = Sets the pwm for the pump");
Serial.print("[Any number between 0 and ");
Serial.print(fanMaxPwm);
Serial.println("]f = Sets the pwm for the pump");
Serial.println("off = turns OFF fan & both pumps");
//Serial.println("cycle = Prints current cycle number");
Serial.println("---------------------------------------------------------");
}