|
david_femi June 17, 2024, 2:59pm 1
I have beginner skills on arduino, and I kind of jumped the gun into a project for school, to build a programmable switch timer, it has 4 buttons The switch is to be able to program on and off times of a bulb, it should be able to set 2 programs daily for each day of the week(i.e. i can manually program 2 on/off times for each day Monday through sunday).This also implies that date, time are variables that can be programmed. It should also display the room temperature. I WANT IT TO PERFORM CERTAIN FUNCTIONS USING 4 PUSHBUTTONS,
Button 1 (Manual Control): This button will allow manual control over the relay module, overriding the programmed settings.
Button 2 (Set Button): This button will be used to set the ON and OFF times for a specific day of the week.
Button 3 (Adjust Variable):This button will be used to adjust the value of any variable during the programming mode. When Button 3 is pressed, it should increment the chosen variable's value by one. If the maximum variable value is reached, the value should wrap around to the minimum value.
Button 4 (Next Variable): This button will be used to move to the next variable to be adjusted during the programming mode. When Button 4 is pressed, it should move to the next variable's tab to let it be adjusted by Button 3 I have a code, but it doesn't work as intended, can someone help me analyze and find what i did wrong
Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!
alto777 June 17, 2024, 3:09pm 2
Welcom to the forum.
I have a code I look later. And thanks for using the wokwi, it really helps helpers. Who wrote or where did you find inspiration (!) for this code you have? If the manual override turns on the relay when it was off, what happens when the next "on" timed event arrives? Stay on? Unanswered questions will be whatever happens that you didn't plan. a7
alto777 June 17, 2024, 3:13pm 3
OK, I looked briefly.
it doesn't work as intended Perhaps you could save some time by elaborating. What does it not do,that it should, or do that it should not? You may benefit from using a button library, I like ezButton, it gets my highest praise for button libraries "it doesn't suck". That would make the hole thing more responsive, you could get rid of some of the dealy() calls. a7
blh64 June 17, 2024, 3:14pm 4
First off, no need for those pull-down resistors on your buttons. You have configured them as INPUT_PULLUP. When you press the Manual button, mode goes from 0 to 1. The next time through loop(), you check if mode == 0 else mode == 2 and since neither of those tests are true, nothing gets done and there is no way to change the mode. Much better to recode as a finite state machine.
david_femi June 17, 2024, 3:54pm 5
Yes, it should stay on as long as the manual override is On
david_femi June 17, 2024, 3:55pm 6
From my simulation, when I press the manual override button, it just stays on, I try pressing the button again to turn it off, but no results, and I am completely unable to perform any function with the other buttons
david_femi June 17, 2024, 3:57pm 7
Alright, thank you, I would take out those resistors now
alto777 June 17, 2024, 4:12pm 8
long as the manual override is On That makes no sense. A button press did the override. How does it remain overridden? Or do,you mean to have a switch? Or do you mean that override obtains until the same button gets you out of the manual override relay condition?
refined by Ai OK, so what kind of sketch can you write, and do you understand what you have in front of you? The nice thing about code is that it does what you wrote. Use some serial printing at various points in your code to "see" the flow and check on the values of variables that inform it. Those 10K resistors are perfectly harmless, and in some circumstances advisable. Old fashioned ppl, or just old ppl, cough! use pullup resistors even though an internal pullup is available. I would just leave them there. if I was making a million copies, I might think about saving what you would by omitting them. a7
david_femi June 17, 2024, 7:27pm 9
Hi, thank you for responding continually, so yes, the Override button is basically supposed to act as a manual switch, it keeps the system on until it is turned off again using the same button, then which it can go back to coming on and going off at the programmed times.
alto777 June 18, 2024, 4:04am 10
OK, I just lost a lengthy post, the main point of which was that you should learn about finite state machines. I also suggested that trying AI but describing your problem knowing about FSMs might generate some better results. Indeed feeding Write a function that is a finite state machine to handle four buttons. Button one should call functions allDone and resetMachine For the buttons, assume that when the function is called, a function button(i) will return true if button number has become pressed since the last call. worked well but each time it made code, I saw some way to help it along. I had to ask it to use C, not whatever it picked at random. I told it to use switch/case instead of if/else chains. I suggested using an integer to hold the state instead of the whizzy struct it was using, which involved an enum and pointers. (For this kind of code, an integer and # defined state names is entirely fine, as in not underkill). It switched to an integer instead of an enum type, but left it in the struct. It cheerfully took my suggestion to just drop the struct and pointer stuff: sorry posted accidentally so I am finishing this now alto777: you don't need to use a struct, it's just one integer. this will make things simpler ChatGPT: Absolutely, we can simplify the implementation further by directly using an int variable to represent the state of the FSM without encapsulating it in a struct. And closer and closer. So meet this wherever you want - learn how to code, or learn how to tell an AI what you want - I have no doubt that sooner or later "we" could have gotten something plausible working. In any case, no time spent looking into finite state machines will be wasted. a7
alto777 June 18, 2024, 3:57pm 11
I tried again. Using the C language write a function that is a finite state machine to handle four buttons. It will be called continuously to check on button presses. Any buttons that get pressed will need actions. Button one should call functions allDone and resetMachine For the buttons, assume that when the function is called, a function button(i) will return true if button number has become pressed since the last call. Use switch/case statements where you can, not chains of if/else statements. The state can be represented by an integer, for nice names use # define. With the above, and a bit of back and forth (the code was always plausible, but unnecessarily complicate) this pops out, the state machine disappeared as unnecessary. // Simulated button function (replace with actual button reading function) bool button(int buttonNumber); // Function to handle button presses void handleButtonPresses(void) { // Check button presses using the button function bool button1Pressed = button(1); bool button2Pressed = button(2); bool button3Pressed = button(3); bool button4Pressed = button(4); // Handle button presses if (button1Pressed) { allDone(); resetMachine(); } if (button2Pressed) { selectNextParameter(); } if (button3Pressed) { incrementCurrentParameter(); } if (button4Pressed) { decrementCurrentParameter(); } } Explanation:
Button Functionality: button(int buttonNumber) is assumed to correctly detect the rising edge (when the button is pressed) and returns true only once per press.
Reading Button States: At the beginning of handleButtonPresses(), the function reads the state of each button (button1Pressed, button2Pressed, etc.) using the button() function.
Handling Button Presses: Based on the state of each button, the corresponding function (allDone, resetMachine, selectNextParameter, incrementCurrentParameter, decrementCurrentParameter) is called. Notes:Ensure that button(int buttonNumber) correctly detects button presses and returns true only once per press (rising edge detection). Replace the simulated function with actual hardware or software-specific implementation as needed. This implementation efficiently handles button presses by first reading the state of each button and then executing the corresponding action, adhering to your request to place the button reading at the top of the function. So when you are in adjustment mode, just keep calling the function and it will update the parameters. A button is provided to clean up and exit the mode. Then I thought it could write the higher level mode switching code, why not? Please write a function that switches modes to allow various interpretations of some other buttons. Just one button should switch between 5 modes, just call them MODE1 through MODE5. The button can be checked with the button(i) function, which will return true once each time it is pressed. Each press shouls switch to the next mode, at the end wrap around and start with MODE1 again. The mode can be an integer, use # define for nice names. At the end of that we got // Simulated button function (replace with actual button reading function) bool button(int buttonNumber) { // Replace this with actual code to read button state // For simulation purposes, function body is left empty // Return value is placeholder return false; // Replace with actual button reading logic } // Define modes #define MODE1 1 #define MODE2 2 #define MODE3 3 #define MODE4 4 #define MODE5 5 // Function prototypes void handleModeSwitch(void); // Global variable to store current mode int currentMode = MODE1; // Function to handle mode switching void handleModeSwitch(void) { // Check if the mode switch button (button 1) is pressed if (button(1)) { // Increment the current mode currentMode++; // Wrap around if exceeding the maximum mode if (currentMode > MODE5) { currentMode = MODE1; } } } Explanation:
Simulated button function: button(int buttonNumber) is declared with an empty body, as requested. This function is intended to be replaced with actual code that reads the state of the specified button (buttonNumber).
Mode Switching Logic: The handleModeSwitch() function remains the same as previously explained. It checks if button 1 is pressed (using button(1)), increments currentMode, and wraps around if it exceeds MODE5.
Define Modes and Function Prototypes: Modes (MODE1 through MODE5) and function prototypes (handleModeSwitch()) are defined and declared respectively. Notes:Ensure to replace the empty body of button(int buttonNumber) with actual code that reads the state of the specified button in your hardware or software environment. This structure allows you to integrate the simulated button() function with actual button reading logic seamlessly once implemented. Here's my side of the conversation. chatGPT is indefatigavle and patient, each suggestion resulted in a full code and explanation. alto777: Button one should call functions allDone and resetMachine For the buttons, assume that when the function is called, a function button(i) will return true if button number has become pressed since the last call. Use switch/case statements where you can, not chains of if/else statements. The state can be represented by an integer, for nice names use # define. alto777: alto777: alto777: alto777: alto777: Just one button should switch between 5 modes, just call them MODE1 through MODE5. The button can be checked with the button(i) function, which will return true once each time it is pressed. Each press shouls switch to the next mode, at the end wrap around and start with MODE1 again. The mode can be an integer, use # define for nice names. alto777: alto777: The fake *button*() function can be replaced with ezButton's bool button1Pressed = button1.isPressed(); I see I should have just asked chatGPT to not bother reading the switches, the button() function could be used directly in the if statements. Too much fun. I lost track of states and modes. If I started again and took it a bit more seriously I think "we" could have done better. But the idea is that at a high level you switch modes, and depending on the mode, send any buttons presses to functions that handle them one at a time. a7
paulpaulson June 20, 2024, 7:33am 12
Hello david_femi Welcome to the best Arduino forum ever
Check and test this button manager for your timer project. You have to modify this sketch to your project needs. //https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg #define ProjectName "Basic Button Manager" #define NotesOnRelease "Arduino MEGA tested" // -- some useful text replacements used because I'm lazy with typing -- #define equ == #define nequ != #define view(x) Serial.print(x) #define viewLn(x) Serial.println(x) // make names enum ButtonState {Released, Pressed}; enum TimerEvent {NotExpired, Expired}; enum ButtonNames {One, Two, Three, Four}; // make variables constexpr uint8_t ButtonPins[] {A0, A1, A2, A3}; // forward declarations void manualControl(); void setButton(); void adjustVariable(); void nextVariable(); void (*task[])() { manualControl, setButton, adjustVariable, nextVariable }; // make structures struct TIMER { uint32_t interval; uint32_t now; uint8_t expired(uint32_t currentMillis) { uint8_t timerEvent = currentMillis - now >= interval; if (timerEvent equ Expired) now = currentMillis; return timerEvent; } }; struct BUTTON { const uint8_t Name; const uint8_t Button; void (*task)(); uint8_t stateOld; TIMER debounce; void check(uint32_t currentMillis) { if (debounce.expired(currentMillis) equ Expired) { uint8_t stateNew = digitalRead(Button) ? LOW : HIGH; if (stateOld nequ stateNew) { stateOld = stateNew; view ("button "), view(Name), view(" becomes "); viewLn (stateNew ? "pressed" : "released"); if (stateNew equ Pressed) { Serial.print("calling task: "); task(); } } } } }; BUTTON buttons[] { {One, ButtonPins[One], task[One], LOW, 20, 0}, {Two, ButtonPins[Two], task[Two], LOW, 20, 0}, {Three, ButtonPins[Three], task[Three], LOW, 20, 0}, {Four, ButtonPins[Four], task[Four], LOW, 20, 0}, }; // make support void heartBeat(const uint8_t LedPin, uint32_t currentMillis) { static bool setUp = false; if (setUp == false) pinMode (LedPin, OUTPUT), setUp = true; digitalWrite(LedPin, (currentMillis / 500) % 2); } //-- //---------------------------- make applications ---------------------------------------------- // void manualControl() { Serial.println(__func__); } void setButton() { Serial.println(__func__); } void adjustVariable() { Serial.println(__func__); } void nextVariable() { Serial.println(__func__); } //--- //---------------------------------------------------------------------------------- void setup() { Serial.begin(115200); Serial.print("Source: "), Serial.println(__FILE__); Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease); for (auto ButtonPin : ButtonPins) pinMode (ButtonPin, INPUT_PULLUP); Serial.println(" =-> and off we go\n"); } void loop() { uint32_t currentMillis = millis(); heartBeat(LED_BUILTIN, currentMillis); for (auto &button : buttons) button.check(currentMillis); }Have a nice day and enjoy coding in C++.
system Closed December 17, 2024, 7:34am 13
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed. (责任编辑:) |



