Code to have 11 presets and have a decreasing off time for each preset

I used chatgpt do generate this Arduino code, it should have the relay "on" time as constant on 0.1s and the "off" time should decrease for each preset. Presets should change on button press and if the button is pressed for more than 1s it should go back to preset 0.

What is wrong with the generated code? Now it strangely has the same "off" time as "on" time for each preset. the relay time changes on each preset but the "on" (0.1s) should always be constant...

#include <Adafruit_SSD1306.h>
#include <Wire.h>

// Define screen dimensions
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

// Initialize the OLED display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

const int buttonPin = 2;  // Button pin
const int relayPin = 0;   // Relay control pin on pin 0

// Define the number of presets
const int numPresets = 11;

// Arrays to store on and off times for each preset
unsigned long onTime = 100;  // 0.1s on time
unsigned long offTimes[numPresets] = {0, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100};

// Variable to store the current preset
int currentPreset = 0;

unsigned long previousMillis = 0;  // Declare previousMillis
unsigned long buttonPressStartTime = 0; // Time when the button was pressed
bool buttonWasPressed = false;

void setup() {
  // Initialize I2C communication with specific pins
  Wire.begin(5, 4);

  // Initialize the OLED display
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }

  // Set up the button pin with an internal pull-up resistor
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);  // Set the relay pin as OUTPUT

  // Initialize the relay to the default state (OFF)
  digitalWrite(relayPin, LOW);

  // Initialize the OLED display
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);

  // Initialize to preset 0
  currentPreset = 0;
}

void loop() {
  int buttonState = digitalRead(buttonPin);

  if (buttonState == LOW && !buttonWasPressed) {
    buttonPressStartTime = millis();
    buttonWasPressed = true;
  }

  if (buttonState == HIGH && buttonWasPressed) {
    unsigned long currentTime = millis();
    unsigned long buttonPressDuration = currentTime - buttonPressStartTime;
    if (buttonPressDuration >= 1000) {
      currentPreset = 0;
      digitalWrite(relayPin, LOW);
    } else {
      currentPreset = (currentPreset + 1) % numPresets;
    }
    buttonWasPressed = false;
  }

  // Toggle relay based on the current preset
  if (currentPreset != 0 && millis() - previousMillis >= offTimes[currentPreset]) {
    previousMillis = millis();
    digitalWrite(relayPin, !digitalRead(relayPin));
  }

  // Display the active preset on the OLED display
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print(F("Preset: "));
  display.print(currentPreset);
  display.display();
}

That it was done by an AI.
Ask the AI what it did wrong.

Regards

1 Like

I did like 40 times, on each iteration :sweat_smile:

It is apparent you do not know what you have nor have you posted a schematic. Ask AI to come to your lab and troubleshoot your problem and generate an annotated schematic. Maybe you should ask AI for working code!

1 Like

But I'm here now, in your microcosmos.

I avoided to start out here because forums is usually a toxic place but see and behold, its different here...

#include <Adafruit_SSD1306.h>
#include <Wire.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

const int buttonPin = 2;
const int relayPin = 0;

const int numPresets = 11;
const unsigned long onTime = 100;  // 0.1s on time
const unsigned long offTimes[numPresets] = {0, 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100};

int currentPreset = 0;
unsigned long previousMillis = 0;
unsigned long buttonPressStartTime = 0;
bool buttonWasPressed = false;

void setup() {
  Wire.begin(5, 4);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
    Serial.println(F("SSD1306 allocation failed"));
    // Handle the display initialization error here
  }

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW);

  initializeDisplay();
  currentPreset = 0;
}

void loop() {
  handleButtonInput();

  if (currentPreset != 0 && millis() - previousMillis >= offTimes[currentPreset]) {
    previousMillis = millis();
    digitalWrite(relayPin, HIGH); // Turn the relay on
    delay(onTime);              // Keep the relay on for 0.1s
    digitalWrite(relayPin, LOW);  // Turn the relay off
  }

  updateDisplay();
}

void initializeDisplay() {
  display.display();
  delay(2000);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
}

void handleButtonInput() {
  int buttonState = digitalRead(buttonPin);

  if (buttonState == LOW && !buttonWasPressed) {
    buttonPressStartTime = millis();
    buttonWasPressed = true;
  }

  if (buttonState == HIGH && buttonWasPressed) {
    unsigned long currentTime = millis();
    unsigned long buttonPressDuration = currentTime - buttonPressStartTime;
    if (buttonPressDuration >= 1000) {
      currentPreset = 0;
      digitalWrite(relayPin, LOW);
    } else {
      currentPreset = (currentPreset + 1) % numPresets;
    }
    buttonWasPressed = false;
  }
}

void updateDisplay() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.print(F("Preset: "));
  display.print(currentPreset);
  display.display();
}

Explanation of fixes:

  1. Relay Control: In the loop function, when a preset is active, the relay is turned on with digitalWrite(relayPin, HIGH), and then a delay of onTime (0.1s) is used to keep the relay on. After that, the relay is turned off with digitalWrite(relayPin, LOW). This enforces a constant 0.1s "on" time for each preset while using the specified "off" times.

  2. Updated Loop Logic: The loop logic now correctly uses onTime for the "on" time, and offTimes for the "off" time for each preset.

These changes ensure that the "on" time remains constant (0.1s) for each preset while the "off" time decreases as specified in the offTimes array.

Thanks, I will test this directly and change the loop logic accordingly.

Now the code does what it should, I tested it!

Thanks you so much! Now I can finish of my huge DIY magnetic mycelium aggitator and hopefully soon get growing =)

This is not a logic answer at all, imagine if you focused on helping out and very clearly pointed out the errors in the code like the knowledgable member below that actually answered the question did. In that way AI would have indexed the answer in the future and corrected itself, and by that you would have kept people like me out from this forum asking silly questions that you don't have time to answer. That would be impressing for sure.

1 Like

Just to do something right =)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.