#include <Arduino.h>
const int valvePins[] = {3, 4, 5, 6, 7, 8, 9}; // Pins for valves
const int numValves = 7; // Number of valves
bool stopExecution = false; // Flag to indicate if the execution should be stopped
String pulseSequences[10]; // Array to store user-inputted pulse sequences
int currentSequenceIndex = 0; // Index of the current pulse sequence
const int maxSequences = 10; // Maximum number of supercycles
int numSequences = 0; // Number of sequences inputted by the user
unsigned long totalRemainingTime = 0; // Variable to store the total remaining time
int totalRemainingCycles = 0; // Variable to store the total remaining cycles
const int activeStatePin = 10; // Pin for active state (state 12)
const int nonActiveStatePin = 11; // Pin for non-active state (state 13)
const int errorStatePin = 12; // Pin for error state
void displayHelp() {
Serial.println();
Serial.println("Available commands:");
Serial.println(" h: Display this help message");
Serial.println(" v: Show current state of valves");
Serial.println(" g: Start execution of pulse sequence");
Serial.println(" t: Show total remaining time");
Serial.println(" s: Show help for entering pulse sequence");
Serial.println(" Any other character: Exit program");
Serial.println();
Serial.println("General instructions");
Serial.println("To enter a pulse sequence, follow the format:");
Serial.println("'valve1,valve2,...,valveN,Ttime1;valve1,valve2,...,valveN,Ttime2;...;cycles'");
Serial.println("Each valve state is represented as 0 (OFF) or 1 (ON), and Ttime represents the time in 0.1-second intervals for the pulse.");
Serial.println("Example: 1,1,1,1,1,1,1,T100;1,0,1,1,1,0,1,T50;30");
Serial.println();
}
void processPulse(String valveStates, int time) {
int valveValues[numValves];
for (int i = 0; i < numValves; ++i) {
valveValues[i] = valveStates.substring(i * 2, i * 2 + 1).toInt();
}
Serial.print("Setting valve states: ");
for (int i = 0; i < numValves; ++i) {
digitalWrite(valvePins[i], valveValues[i]);
Serial.print(valveValues[i]);
Serial.print(" ");
}
Serial.println();
Serial.println("Remaining Time: ");
for (int remainingTime = time; remainingTime > 0; --remainingTime) {
if (remainingTime % 10 == 0) {
Serial.print(remainingTime / 10);
Serial.print("s ");
}
delay(100);
if (Serial.available()) {
String userInput = Serial.readStringUntil('\n');
if (userInput.equalsIgnoreCase("q")) {
stopExecution = true;
break;
} else if (userInput.equalsIgnoreCase("v")) {
showValveStates();
}
}
}
totalRemainingTime += (time * (totalRemainingCycles - 1));
for (int i = 0; i < numValves; ++i) {
digitalWrite(valvePins[i], LOW);
}
}
void showValveStates() {
Serial.print("Current valve states: ");
for (int i = 0; i < numValves; ++i) {
int valveState = digitalRead(valvePins[i]);
Serial.print(valveState);
Serial.print(" ");
}
Serial.println();
}
void showTotalRemainingTime() {
Serial.print("Total Remaining Time: ");
Serial.print((totalRemainingTime / 10));
Serial.println("s");
}
void setup() {
Serial.begin(9600);
Serial.println("Welcome to J-Tool! Press 'h' for help with commands.");
Serial.println("Press 'g' to start the pulse sequence.");
for (int i = 0; i < numValves; ++i) {
pinMode(valvePins[i], OUTPUT);
digitalWrite(valvePins[i], LOW); // Initialize valves to OFF state
}
pinMode(activeStatePin, OUTPUT); // Set the active state pin as output
pinMode(nonActiveStatePin, OUTPUT); // Set the non-active state pin as output
pinMode(errorStatePin, OUTPUT); // Set the error state pin as output
digitalWrite(nonActiveStatePin, HIGH); // Initially set to non-active (state 13 on)
digitalWrite(activeStatePin, LOW); // Initially set to active (state 12 off)
digitalWrite(errorStatePin, LOW); // Initially set to no error
}
void loop() {
while (true) {
while (!Serial.available()) {}
String input = Serial.readStringUntil('\n');
Serial.print("You entered: ");
Serial.println(input);
if (input.equalsIgnoreCase("h")) {
displayHelp();
continue;
}
if (input.equalsIgnoreCase("q")) {
Serial.println("Exiting program.");
return;
}
if (input.equalsIgnoreCase("v")) {
showValveStates();
continue;
}
if (input.equalsIgnoreCase("g")) {
if (numSequences > 0) {
executePulseSequence();
} else {
Serial.println("No pulse sequences entered. Please enter valid pulse sequences.");
}
continue;
}
if (input.equalsIgnoreCase("t")) {
showTotalRemainingTime();
continue;
}
if (numSequences < maxSequences) {
pulseSequences[numSequences++] = input;
Serial.print("Sequence queued. Total sequences: ");
Serial.println(numSequences);
} else {
Serial.println("Max number of sequences reached or currently executing.");
}
}
}
void executePulseSequence() {
digitalWrite(activeStatePin, HIGH); // Set active state pin high
digitalWrite(nonActiveStatePin, LOW); // Set non-active state pin low
Serial.println("Starting pulse sequence execution...");
while (currentSequenceIndex < numSequences) {
if (stopExecution) {
Serial.println("Pulse sequence stopped by user.");
break; // Exit the while loop, stopping all sequences
}
String currentSequence = pulseSequences[currentSequenceIndex];
// Split the current pulse sequence into its individual pulses
String pulses[10]; // Assuming a maximum of 10 pulses in a sequence
int pulseCount = 0;
int startIndex = 0;
int lastSemicolonIndex = currentSequence.lastIndexOf(';');
for (int i = 0; i < lastSemicolonIndex; ++i) {
if (currentSequence.charAt(i) == ';') {
pulses[pulseCount++] = currentSequence.substring(startIndex, i);
startIndex = i + 1;
}
}
pulses[pulseCount++] = currentSequence.substring(startIndex, lastSemicolonIndex);
// Extract cycle count from the end of the sequence
int cycleCount = currentSequence.substring(lastSemicolonIndex + 1).toInt();
for (int cycle = 0; cycle < cycleCount; ++cycle) {
if (stopExecution) {
Serial.println("Pulse sequence stopped by user.");
break; // Exit the for loop, stopping the current sequence
}
for (int pulseIndex = 0; pulseIndex < pulseCount; ++pulseIndex) {
if (stopExecution) {
Serial.println("Pulse sequence stopped by user.");
break; // Exit the for loop, stopping the current pulse processing
}
int commaIndex = pulses[pulseIndex].lastIndexOf(',');
String valveStates = pulses[pulseIndex].substring(0, commaIndex);
int time = pulses[pulseIndex].substring(commaIndex + 2).toInt(); // Skip 'T' and extract time
Serial.println();
Serial.print("Setting valve states for pulse ");
Serial.print(pulseIndex + 1);
Serial.print(": ");
processPulse(valveStates, time);
}
Serial.println();
Serial.print("Cycles remaining: ");
Serial.println(cycleCount - cycle - 1);
}
currentSequenceIndex++;
}
digitalWrite(activeStatePin, LOW); // Set active state pin low
digitalWrite(nonActiveStatePin, HIGH); // Set non-active state pin high
if (!stopExecution) {
Serial.println("All pulse sequences completed.");
} else {
Serial.println("Pulse sequence execution stopped.");
stopExecution = false; // Reset stopExecution flag
}
// Reset for the next set of sequences
currentSequenceIndex = 0;
numSequences = 0;
}