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();
}
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!
#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:
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.
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.
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.