Have a code written but can't seem to make some functions work. I probably did something wrong. Who's willing to help me out ? I'll draw schematics and post my code here in a minute. Code is about 600 lines and messy so hopefully we can tidy it up and make it work.
---------------------------------------------------------------UPDATE--------------------------------------------------------------------
//“S”: Starts all delays for the solenoids.
//“6”: Moves the cursor up.
//“4”: Moves the cursor down.
//“8”: Toggles the edit mode.
//“EEPROM RESET”: Resets all EEPROM values to zero.
//“DEFAULT”: Sets the Offsets and Intervals to their default values and saves them to the EEPROM.
//--------------------------------------------------------------------------------------------------------------------------------------------------------
//
// ______ _ _____ _ _ __ ___ _ _
// | ____| | | / ____| | | | | /_ | / _ \ | | | |
// | |__ | | ___ __ __ | | ___ _ __ | |_ _ __ ___ | | __ __ | | | | | | | |__ ___ | |_ __ _
// | __| | | / _ \ \ \ /\ / / | | / _ \ | '_ \ | __| | '__| / _ \ | | \ \ / / | | | | | | | '_ \ / _ \ | __| / _` |
// | | | | | (_) | \ V V / | |____ | (_) | | | | | | |_ | | | (_) | | | \ V / | | _ | |_| | | |_) | | __/ | |_ | (_| |
// |_| |_| \___/ \_/\_/ \_____| \___/ |_| |_| \__| |_| \___/ |_| \_/ |_| (_) \___/ |_.__/ \___| \__| \__,_|
//
//
//
// SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFF
// SS:::::::::::::::S E::::::::::::::::::::E F::::::::::::::::::::F
// S:::::SSSSSS::::::S E::::::::::::::::::::E F::::::::::::::::::::F
// S:::::S SSSSSSS EE::::::EEEEEEEEE::::E FF::::::FFFFFFFFF::::F
// S:::::S E:::::E EEEEEE F:::::F FFFFFF
// S:::::S E:::::E F:::::F
// S::::SSSS E::::::EEEEEEEEEE F::::::FFFFFFFFFF
// SS::::::SSSSS E:::::::::::::::E F:::::::::::::::F
// SSS::::::::SS E:::::::::::::::E F:::::::::::::::F
// SSSSSS::::S E::::::EEEEEEEEEE F::::::FFFFFFFFFF
// S:::::S E:::::E F:::::F
// S:::::S E:::::E EEEEEE F:::::F
// SSSSSSS S:::::S EE::::::EEEEEEEE:::::E FF:::::::FF
// S::::::SSSSSS:::::S E::::::::::::::::::::E F::::::::FF
// S:::::::::::::::SS E::::::::::::::::::::E F::::::::FF
// SSSSSSSSSSSSSSS EEEEEEEEEEEEEEEEEEEEEE FFFFFFFFFFF
//
//-------------------------------------------------------------------------------------------------------------------------------------------------------
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// Define the LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Define the relay pins
const int relayPins[] = {22, 23, 24, 25, 26, 27};
// Define the relay states
int relayStates[] = {LOW, LOW, LOW, LOW, LOW, LOW}; // Start with all relays off
// Define the delay times (in milliseconds)
unsigned long Offsets[6];
unsigned long Intervals[6];
unsigned long lastButtonUpTime = 0;
unsigned long lastButtonDownTime = 0;
unsigned long lastButtonSelectTime = 0;
unsigned long debounceDelay = 500; // Adjust the debounce delay as needed
unsigned long currentTime = millis();
//Double press mills
unsigned long buttonPressTime = 0;
// Define the button pins
const int buttonUp = 12;
const int buttonDown = 13;
const int buttonSelect = 11;
// Define the cursor position
volatile int cursorPosition = 0;
// Define the edit mode
volatile bool editMode = false;
// Define LCD update
volatile bool updateLCD = true;
// Define the number of solenoids
const int numSolenoids = 6;
// Define the edit item (0 = Offset, 1 = Opening Time)
volatile int editItem = 0;
// Try get updates instantly. Test logic
bool eepromUpdated = false;
//Rest of additional menus and options
bool secretMenuActive = false;
bool simulateOption = false;
bool cleaningOption = false;
// Define a timer class
class Timer {
private:
unsigned long startTime;
unsigned long interval;
bool running;
public:
Timer(unsigned long interval = 0) {
this->interval = interval;
running = false;
}
void start() {
startTime = millis();
running = true;
}
void stop() {
running = false;
}
bool isRunning() {
return running;
}
bool event() {
if (running && millis() - startTime >= interval) {
startTime = millis(); // reset the start time
return true;
}
return false;
}
};
// Define a delay class
class Delay {
private:
unsigned long startDTime;
unsigned long delayTime;
bool running;
public:
Delay(unsigned long delayTime = 0) {
this->delayTime = delayTime;
running = false;
}
void start() {
startDTime = millis();
running = true;
}
void stop() {
running = false;
}
bool isRunning() {
return running;
}
bool event() {
if (running && millis() - startDTime >= delayTime) {
startDTime = millis(); // reset the start time
return true;
}
return false;
}
};
// Create timers for each relay
Timer timers[6];
// Create timer Delays for each relay
Delay Delays[6];
void setup() {
// Initialize the LCD
lcd.init();
lcd.backlight();
// Bootloader
lcd.setCursor(2, 1);
lcd.print("Bandau Uzsikraut");
lcd.setCursor(0, 2);
for (int i = 0; i < 20; ++i) {
lcd.print(".");
delay(100);
}
delay(500);
// Clear screen after loading animation
lcd.clear();
delay(750);
// Set the relay pins as output and initialize states
for (int i = 0; i < 6; i++) {
pinMode(relayPins[i], OUTPUT);
digitalWrite(relayPins[i], relayStates[i]); // Ensure all relays start off
}
// Set pullup on buttons
pinMode(buttonUp, INPUT_PULLUP);
pinMode(buttonDown, INPUT_PULLUP);
pinMode(buttonSelect, INPUT_PULLUP);
// Begin serial communication
Serial.begin(9600);
// Load the values from the EEPROM
for (int i = 0; i < numSolenoids; i++) {
Offsets[i] = EEPROM.read(18 + i * 3) * 10;
Intervals[i] = EEPROM.read(i * 3) * 10;
timers[i] = Timer(Intervals[i]); // Initialize the timers
Delays[i] = Delay(Offsets[i]); // Initialize the delays
}
// Read and print EEPROM values
printEEPROMValues();
// Attach interrupts to the buttons
attachInterrupt(digitalPinToInterrupt(buttonUp), moveCursorUp, RISING);
attachInterrupt(digitalPinToInterrupt(buttonDown), moveCursorDown, RISING);
attachInterrupt(digitalPinToInterrupt(buttonSelect), toggleEditMode, RISING);
}
void loop() {
static unsigned long lastButtonUpTime = 0;
static unsigned long lastButtonDownTime = 0;
static unsigned long lastButtonSelectTime = 0;
unsigned long lastUpdate = 0;
unsigned long debounceDelay = 250; // Adjust the debounce delay as needed
unsigned long currentTime = millis();
// Button Up
if (currentTime - lastButtonUpTime > debounceDelay && digitalRead(buttonUp) == LOW) {
moveCursorUp();
lastButtonUpTime = currentTime;
}
// Button Down
if (currentTime - lastButtonDownTime > debounceDelay && digitalRead(buttonDown) == LOW) {
moveCursorDown();
lastButtonDownTime = currentTime;
}
// Button Select
if (currentTime - lastButtonSelectTime > debounceDelay && digitalRead(buttonSelect) == LOW) {
toggleEditMode();
lastButtonSelectTime = currentTime;
}
//Secret menu call and axit
if (digitalRead(buttonUp) == LOW && digitalRead(buttonDown) == LOW) {
if (buttonPressTime == 0) { // if not already started
buttonPressTime = millis(); // start timer
} else if (millis() - buttonPressTime >= 2000) { // if 2 seconds have passed
secretMenu(); // call your function
secretMenuActive = true;
buttonPressTime = 0; // reset timer
updateLCD = true;
}
}
// Check for serial input
if (Serial.available()) {
processSerialCommand();
}
// Update relay states
updateRelayStates();
// Update the LCD if needed
if (updateLCD) {
updateLCDContent();
}
}
void printEEPROMValues() {
Serial.println("------------------------------------------------");
for (int i = 0; i < numSolenoids; i++) {
Serial.print("Solenoid ");
Serial.print(i + 1);
Serial.print(" Opening Time [ ");
Serial.print(EEPROM.read(i * 3) * 10);
Serial.print(" ] Offset [ ");
Serial.print(EEPROM.read(18 + i * 3) * 10);
Serial.println(" ]");
}
Serial.println("------------------------------------------------");
}
void processSerialCommand() {
String command = Serial.readStringUntil('\n');
command.trim();
if (command == "HELP") {
// Display help information
displayHelp();
} else if (command == "S") {
// Load the values from the EEPROM
for (int i = 0; i < numSolenoids; i++) {
Offsets[i] = EEPROM.read(18 + i * 3) * 10;
Intervals[i] = EEPROM.read(i * 3) * 10;
timers[i] = Timer(Intervals[i]); // Initialize the timers
Delays[i] = Delay(Offsets[i]); // Initialize the delays
}
// Start all delays for the solenoids
startAllDelays();
updateRelayStates();
} else if (command == "6") {
moveCursorUp();
} else if (command == "4") {
moveCursorDown();
} else if (command == "8" || (digitalRead(buttonSelect) == LOW )) {
toggleEditMode();
} else if (command == "DEFAULT") {
setDefaultValues();
} else if (command == "EEPROM RESET") {
resetEEPROMValues();
} else if (command == "Print") {
printEEPROMValues();
} else if (command == "x") {
startSimulation();
} else if (command == "Menu") {
secretMenuActive = true;
secretMenu();
}
}
void secretMenu() {
int currentPage = 1; // Track the current page in the secret menu
int cursorPosition = 0; // Track the cursor position (0 for ON, 1 for OFF)
unsigned long lastUpdate = 0; // Variable to store the last update time
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("* Secret Menu *");
delay(1000);
Serial.println("Entering Secret Menu");
lcd.clear();
while (secretMenuActive) {
if (currentPage == 1) {
lcd.setCursor(5, 0);
lcd.print("Simulation");
lcd.setCursor(2, 2);
lcd.print(cursorPosition == 1 ? "<< ON >> OFF " : " ON << OFF >>");
} else if (currentPage == 2) {
lcd.setCursor(6, 0);
lcd.print("Cleaning");
lcd.setCursor(2, 2);
lcd.print(cursorPosition == 1 ? "<< ON >> OFF " : " ON << OFF >>");
}
if (digitalRead(buttonUp) == LOW) {
if (currentPage == 2) {
currentPage = 1;
lcd.clear();
}
} else if (digitalRead(buttonDown) == LOW) {
if (currentPage == 1) {
currentPage = 2;
lcd.clear();
}
} else if (digitalRead(buttonSelect) == LOW) {
// Toggle the cursor position
cursorPosition = !cursorPosition;
delay(300);
if (currentPage == 1) {
if (cursorPosition == 1) {
simulateOption = true ;
} else {
stopSimulation();
simulateOption = false;
}
} else if (currentPage == 2) {
if (cursorPosition == 1) {
startCleaning();
cleaningOption = true;
} else {
stopCleaning();
cleaningOption = false;
}
}
}
if (simulateOption && millis() - lastUpdate >= 2000) {
startSimulation();
}
if (cleaningOption && millis() - lastUpdate >= 5000) {
startCleaning();
Serial.println("Cleaning mode active. Press 'OFF' to stop.");
lastUpdate = millis();
}
//Secret menu call and axit
if (digitalRead(buttonUp) == LOW && digitalRead(buttonDown) == LOW) {
if (buttonPressTime == 0) { // if not already started
buttonPressTime = millis(); // start timer
} else if (millis() - buttonPressTime >= 2000) { // if 2 seconds have passed
Serial.println("Exiting");
lcd.clear();
lcd.setCursor(5,1);
lcd.print("Exiting...");
delay(1000);
secretMenuActive = false;
buttonPressTime = 0; // reset timer
updateLCD = true;
} else if (millis() - buttonPressTime >= 3000) {
Serial.print("pritruko palaikyt nulinam laikmati knopkem");// if 3 seconds have passed
buttonPressTime = 0;
}
}
}
}
//----------------------------------------Secret menu end
void startAllDelays() {
for (int i = 0; i < numSolenoids; i++) {
Delays[i].start();
}
Serial.println("---Values updated for cycle");
}
void updateRelayStates() {
for (int i = 0; i < numSolenoids; i++) {
if (Delays[i].event()) {
Offsets[i] = EEPROM.read(18 + i * 3) * 10;
Intervals[i] = EEPROM.read(i * 3) * 10;
timers[i].start();
relayStates[i] = HIGH;
digitalWrite(relayPins[i], relayStates[i]);
Delays[i].stop();
}
if (timers[i].event()) {
relayStates[i] = LOW;
digitalWrite(relayPins[i], relayStates[i]);
timers[i].stop();
}
}
}
//-------------------------------------------------------------------------------
void startSimulation() {
static Timer simulationTimer(2000); // Adjust the interval as needed
if (simulationTimer.event()) {
// Load the values from the EEPROM
for (int i = 0; i < numSolenoids; i++) {
Offsets[i] = EEPROM.read(18 + i * 3) * 10;
Intervals[i] = EEPROM.read(i * 3) * 10;
}
// Start all delays for the solenoids
startAllDelays();
updateRelayStates();
Serial.println("----Simulation completed----");
updateLCD = true;
}
}
//--------------------------------------------Trying to get Simulation to work on toggle....
void startCleaning() {
// Open all relays
for (int i = 0; i < numSolenoids; i++) {
relayStates[i] = HIGH;
digitalWrite(relayPins[i], HIGH);
}
updateLCD = true; // Set the flag to update the LCD
}
void stopSimulation() {
// Add logic to stop the simulation
Serial.println("-------------Simulation stopped----------------");
updateLCD = true; // Set the flag to update the LCD
}
void stopCleaning() {
// Add logic to stop the cleaning
for (int i = 0; i < numSolenoids; i++) {
relayStates[i] = LOW;
digitalWrite(relayPins[i], relayStates[i]);
}
updateLCD = true; // Set the flag to update the LCD
Serial.println("Cleaning mode stopped. Returning to normal state.");
}
//--------------------------------------------------------------------------------
void updateLCDContent() {
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Solenoid ");
lcd.print(cursorPosition + 1);
lcd.setCursor(0, 1);
lcd.print("Offset : ");
if (editMode && editItem == 0) {
lcd.print("<< ");
lcd.print(Offsets[cursorPosition] / 10);
lcd.print(" >> %");
} else {
lcd.print(Offsets[cursorPosition] / 10);
lcd.print(" %");
}
lcd.setCursor(0, 2);
lcd.print("Opening: ");
if (editMode && editItem == 1) {
lcd.print("<< ");
lcd.print(Intervals[cursorPosition] / 10);
lcd.print(" >> cs");
} else {
lcd.print(Intervals[cursorPosition] / 10);
lcd.print(" cs");
}
updateLCD = false; // Reset the flag
}
void displayHelp() {
Serial.println("List of available commands:");
Serial.println("\"S\": Start all delays for the solenoids.");
Serial.println("\"6\": Move the cursor up.");
Serial.println("\"4\": Move the cursor down.");
Serial.println("\"8\": Toggle the edit mode.");
Serial.println("\"EEPROM RESET\": Reset all EEPROM values to zero.");
Serial.println("\"DEFAULT\": Set the Offsets and Intervals to their default values and save them to the EEPROM.");
Serial.println("\"Print\": Prints a table of current values saved on Solenoids.");
Serial.println("\"Menu\": Secret menu to Operate Simulation and Cleaning.");
Serial.println("\"Exit\": Exit Secret Menu");
}
void moveCursorUp() {
if (editMode) {
// Increment the value of the selected item
if (editItem == 0) {
Offsets[cursorPosition] = min(1500, Offsets[cursorPosition] + 10);
} else {
Intervals[cursorPosition] += 10;
}
} else {
// Move the cursor up
cursorPosition = min(numSolenoids - 1, cursorPosition + 1);
}
updateLCD = true; // Set the flag to update the LCD
}
void moveCursorDown() {
if (editMode) {
// Decrement the value of the selected item
if (editItem == 0) {
Offsets[cursorPosition] = max(0, Offsets[cursorPosition] - 10);
} else {
Intervals[cursorPosition] = max(0, Intervals[cursorPosition] - 10);
}
} else {
// Move the cursor down
delay(1000);
cursorPosition = max(0, cursorPosition - 1);
}
updateLCD = true; // Set the flag to update the LCD
}
void toggleEditMode() {
if (editMode) {
// Switch to the next item to edit
editItem = (editItem + 1) % 2;
if (editItem == 0) {
// If we've cycled back to the first item, exit edit mode and display a "Saved" message
editMode = false;
displaySavedMessage();
delay(2000);
saveValuesToEEPROM();
eepromUpdated = true;
}
} else {
// Enter edit mode
editMode = true;
}
updateLCD = true; // Set the flag to update the LCD
}
void displaySavedMessage() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("*******************");
lcd.setCursor(5, 1);
lcd.print("Solenoid ");
lcd.print(cursorPosition + 1);
lcd.setCursor(7, 2);
lcd.print("Saved!");
lcd.setCursor(0, 3);
lcd.print("*******************");
}
void saveValuesToEEPROM() {
for (int i = 0; i < numSolenoids; i++) {
EEPROM.update(18 + i * 3, Offsets[i] / 10);
EEPROM.update(i * 3, Intervals[i] / 10);
}
Serial.println("Values saved to EEPROM.");
}
void setDefaultValues() {
for (int i = 0; i < numSolenoids; i++) {
if (i == 0 || i == 2 || i == 4) { // Solenoids 1, 3, 5
Offsets[i] = 0;
} else { // The rest of the solenoids
Offsets[i] = 500;
}
Intervals[i] = 60;
EEPROM.update(18 + i * 3, Offsets[i] / 10);
EEPROM.update(i * 3, Intervals[i] / 10);
}
Serial.println("Default Values Saved to EEPROM.");
updateLCD = true; // Set the flag to update the LCD
}
void resetEEPROMValues() {
// Zero out the EEPROM values
for (int i = 0; i < numSolenoids * 2 + 1; i++) {
EEPROM.update(i, 0);
}
Serial.println("EEPROM VALUES ZEROED");
updateLCD = true; // Set the flag to update the LCD
}
[ PINOUT ]
Power:
[ RELAY SHIELD ]
* DC + = Connected to 14.6 V bench power station to simulate running tractor voltage.
* DC - = Connected to the same power stations return as one should.
[ MEGA ]
* VIN = Connected to 5V output from relay shield.
* GND = Connected to ground pin of both Arduino Mega and relay shield.
Buttons:
- Digital Pin 11 = Connected to button 1 signal pin. (SELECT)
- Digital Pin 12 = Connected to button 2 signal pin. (DOWN)
- Digital Pin 13 = Connected to button 3 signal pin. (UP)
- GND (Ground) = Connected to the common ground pin of the keypad.
Relays:
- Relay 1 Control Pin = Connected to Pin 22)
- Relay 1 Control Pin = Connected to Pin 23)
- Relay 1 Control Pin = Connected to Pin 24)
- Relay 1 Control Pin = Connected to Pin 25)
- Relay 1 Control Pin = Connected to Pin 26)
- Relay 1 Control Pin = Connected to Pin 27)
Cant get the simulation to work. It needs to run through the UpdateRelays sequence once every second or run continuously through the sequence. sequence completes and starts over again.
for budget please give me a quote. my budget is flexible just give me quotes please. Or if you think this is a pretty simple fix and I'm just blind mock me virtually but help me fix it . this should be a simple fix for someone that is good at coding. this is my first ever