I have few functionalities in the below sketch and now I want to switch between the functionalities if pin 2 is connected to GND pin once the code is executed completely then the mode1 should change to mode2. Note that I would like to use the same pins for both modes for different actions. For example PIN 2 in mode1 as input but PIN 2 in mode2 as output.
Please help me how to achieve this in a single sketch with atmega328P.
int mode;
bool newMode;
void setup() {
Serial.begin(115200);
// Do set up which is the same for all modes and only needs to be done once in here
// ...
mode = 0; // or set it to whatever mode value you want
newMode = true; // to force setup for mode to be done
}
void loop() {
switch (mode) {
case 0:
if (newMode) {
setupForMode0();
newMode = false;
}
loopForMode0();
break;
case 1:
if (newMode) {
setupForMode1();
newMode = false;
}
loopForMode1();
break;
// add more cases if you want more modes
default:
Serial.println("Invalid mode");
delay(1000); // to stop serial monitor filling up quickly
}
}
void setupForMode0() {
// Write setup code for mode 0 here
}
void setupForMode1() {
// Write setup code for mode 1 here
}
void loopForMode0() {
// Write loop code for mode 0 here
// The code in here can change the value of mode when you want to switch modes
// If the value of mode is changed in here it must also set newMode = true;
}
void loopForMode1() {
// Write loop code for mode 1 here
// The code in here can change the value of mode when you want to switch modes
// If the value of mode is changed in here it must also set newMode = true;
}
Here's @paulpaulson's sketch with the delays removed. I can confirm proper operation on the UNO Arduino board.
//https://forum.arduino.cc/t/different-modes-in-single-sketch/1336242
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Different modes in single sketch"
#define NotesOnRelease "Arduino MEGA tested"
// make names
enum TimerEvent {NotExpired, Expired};
enum OnOff {Off, On};
// make variables
uint32_t currentMillis = millis();
constexpr uint8_t ButtonPin{A0};
// make structures
//-----------------------------------------
struct BUTTON
{
uint8_t buttonPin;
uint16_t stateOld;
uint16_t selector;
uint32_t interval;
uint32_t now;
void make ()
{
pinMode(buttonPin, INPUT_PULLUP);
stateOld = digitalRead(buttonPin) ? Off : On;
}
uint16_t getButton(uint32_t currentMillis)
{
if (currentMillis - now >= interval == Expired)
{
now = currentMillis;
uint8_t stateNew = digitalRead(buttonPin) ? Off : On;
if (stateOld != stateNew)
{
stateOld = stateNew;
if (stateNew == On) selector = selector ? Off : On;
}
}
return selector;
}
};
BUTTON pushbutton {ButtonPin, Off, Off, 20, 0};
//-----------------------------------------
// make user tasks
//-----------------------------------------
int lastPrinted = -1; // not for long
void loopOne()
{
if (lastPrinted == 1) return; // already said
lastPrinted = 1;
Serial.print("now looping ");
Serial.println(__func__);
// delay(500); //for test purposes only and must be deleted
}
void loopTwo()
{
if (lastPrinted == 2) return; // already said
lastPrinted = 2;
Serial.print("now looping ");
Serial.println(__func__);
// delay(500); // for test purposes only and must be deleted
}
void (*looping[])(void) {
loopOne, loopTwo
};
//-----------------------------------------
// 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 application
void setup()
{
Serial.begin(115200);
for (uint8_t n = 0; n < 32; n++) Serial.println("");
Serial.print("Source: "), Serial.println(__FILE__);
Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);
pushbutton.make();
delay(777);
Serial.println(" =-> and off we go\n");
}
void loop()
{
currentMillis = millis();
# define theHeart 7
heartBeat(theHeart, currentMillis);
looping[pushbutton.getButton(currentMillis)]();
}
I wired in the heart beat, which works well in the absence of those delays.
But... I ask what is going on here? I thought the semicolon was stray, but removing it makes an syntax error, and I don't (yet) understand its roll in the dispatch:
Thanks for your reply. I didn't see different setups fro different loops. For example for the loop1 setup should be different and for the loop2 setup should be different as i am going to use same pins for different purposes. I have a question on Hardware part.
For example, in setup1 I use pin2 as input and in setup2, the pin2 might be output.
So howcome same pin can use as input in mode1 and as output in mode2??
Sure will try and let you know. BTW I am trying to use arduino reset functionality in the sketch. This code is working only in atmega8 microcontroller but not in atmega328 and attiny2313 chips.
#include <avr/wdt.h>
void resetMicrocontroller() {
wdt_enable(WDTO_15MS); // Enable the watchdog timer to reset in 15ms
while (true) {
// Wait for the watchdog to reset the system
}
}
void waitAndReset() {
const unsigned long fiveMinutes = 5UL * 60 * 1000; // 5 minutes in milliseconds
unsigned long startTime = millis();
while (millis() - startTime < fiveMinutes) {
// Do nothing, just wait
delay(1000); // Avoid WDT issues; adjust if WDT is enabled
}
resetMicrocontroller(); // Reset the microcontroller
}