Reset button to run program A or B

Hi
It is possible to switch two programs (A , B ) using reset button.
1.press just reset button - program B is running.
2. Pressing button on PB9 an holding it, then press reset button - program A is running.

void setup() {
  pinMode(PB9, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(PB9) == LOW)// while  arduino reset button is pressed
  {
    run program A
  }
  else
  {
    run program B
  }
}

Program A

const int analogIn = PA6;
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

float val = 0;// define the variable as value=0

void setup()

{
  Serial.begin(115200);
  lcd.begin(16, 2);
}

void loop()
{
val = analogRead(PA6);
 // val = val / 1024 * 5.0; // Convert the data to the corresponding voltage value in a math

  Serial.println(val);//Print the number of val on the serial monitor

  lcd.setCursor(0, 0);
  lcd.print(val,1);//Print the number of val on the LCD
 // delay(200); //Wait for 200ms

}

program B

/*https://create.arduino.cc/projecthub/jasirtp/arduino-frequency-counter-with-16x2-lcd-display-c99779
 
 * 
*/

#include <LiquidCrystal.h>
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

long microSecs;
long freq;
int lastBit;
int nowVal;
long secs;
long maxHz;
long minHz;
long minmax;
void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Loading...");
  pinMode(PA7,INPUT);
  pinMode(PA6,OUTPUT);
  microSecs = micros();
  freq = 0;
  lastBit = 0;
  nowVal =0;
  maxHz=0;
  minHz=0;
  minmax=0;
  secs = millis();
  //Serial.begin(9600);
}
int x=0;
void loop() {


  if ((microSecs+20)<micros()){
      nowVal=digitalRead(PA7);
 
      if (lastBit!=nowVal) {
        lastBit=nowVal;
        freq=freq+1;
      }
      if (freq>maxHz){
        maxHz=freq;
      }
      if (freq<minHz){
        minHz=freq;
      }
      //lcd.clear();
      //lcd.print();
      microSecs = micros();
  }
  if (secs+1000<millis()){

    if (minmax+300000<millis())
    {
      minmax=millis();
      minHz=freq;
      maxHz=freq;
      
    }
      
      lcd.clear();
      lcd.print((freq/2));
      lcd.print(" Hz");
      lcd.setCursor(0,1);
      lcd.print("+: ");
      lcd.print(maxHz);
      lcd.print(" -: ");
      lcd.print(minHz);
      
      freq=0;
      secs=millis();
      
  }

}

Do you have a question?

Timing should be done with unsigned long

I'm sure a way could be figured out with an Uno. I am, also, sure that by the time all the hardware is purchased, put together, and debugged and the code written and debugged that buying an extra Uno to run the other thing would be more cost effective and less time consuming.

You would have to have both programs inside of one main program (as functions). You could store a variable in EEPROM that tells the main program which of the programs (functions) to run at start up. Then if you run program A at reset, change the variable to run program B and store the variable in EEPROM so that the B program will run at the next reset.

You could use an ESP32 and A load both programs in to run with a button selection or B, create/destroy tasks on the fly to completely reload a new environment with the push of a button. No resetting required.

Learning curve, months. ESP32 <10.00USD.

bool RunA;

void setup()
{
  pinMode(9, INPUT_PULLUP);
  RunA = digitalRead(9) == HIGH;

  if (RunA)
    setupA();
  else
    setupB();
}

void loop()
{
  if (RunA)
    loopA();
  else
    loopB();
}

const int analogIn = A6;
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);

float val = 0;// define the variable as value=0

void setupA()
{
  Serial.begin(115200);
  lcd.begin(16, 2);
}

void loopA()
{
  val = analogRead(A6);
  // val = val / 1024 * 5.0; // Convert the data to the corresponding voltage value in a math

  Serial.println(val);//Print the number of val on the serial monitor

  lcd.setCursor(0, 0);
  lcd.print(val, 1); //Print the number of val on the LCD
  // delay(200); //Wait for 200ms
}


/*https://create.arduino.cc/projecthub/jasirtp/arduino-frequency-counter-with-16x2-lcd-display-c99779
*/

long microSecs;
long freq;
int lastBit;
int nowVal;
long secs;
long maxHz;
long minHz;
long minmax;

void setupB()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Loading...");
  pinMode(A7, INPUT);
  pinMode(A6, OUTPUT);
  microSecs = micros();
  freq = 0;
  lastBit = 0;
  nowVal = 0;
  maxHz = 0;
  minHz = 0;
  minmax = 0;
  secs = millis();
  //Serial.begin(9600);
}

int x = 0;

void loopB()
{
  if ((microSecs + 20) < micros())
  {
    nowVal = digitalRead(A7);

    if (lastBit != nowVal)
    {
      lastBit = nowVal;
      freq = freq + 1;
    }
    if (freq > maxHz)
    {
      maxHz = freq;
    }
    if (freq < minHz)
    {
      minHz = freq;
    }
    //lcd.clear();
    //lcd.print();
    microSecs = micros();
  }
  
  if (secs + 1000 < millis())
  {
    if (minmax + 300000 < millis())
    {
      minmax = millis();
      minHz = freq;
      maxHz = freq;
    }

    lcd.clear();
    lcd.print((freq / 2));
    lcd.print(" Hz");
    lcd.setCursor(0, 1);
    lcd.print("+: ");
    lcd.print(maxHz);
    lcd.print(" -: ");
    lcd.print(minHz);

    freq = 0;
    secs = millis();
  }
}

Big thanks, it is working.
It is possible to switch //#define SAMPLES in this program using 5 different buttons


#include "LiquidCrystal.h"
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);


////////////////////////////////////////////////

//#define SAMPLES 57
#define SAMPLES 40
//#define SAMPLES 41
//#define SAMPLES 42
//#define SAMPLES 43

///////////////////////////////////////////////



 #include <libmaple/dma.h>

dma_tube_config dma_cfg, dma_cfg2;
 
int flag1 = 0;
int flag2 = 0;
 
int out1 = PB7;           
int out2 = PA8;
 
int val1[SAMPLES];
int val2[SAMPLES];
 
int16 shift = 0;
 int ovfi;
int amp = 35;
int cnt = 0;
int time_track = 0;
float stp = 6.2831/SAMPLES;    
int ret = 17;
 
timer_dev *dev1 = PIN_MAP[out1].timer_device;
timer_dev *dev2 = PIN_MAP[out2].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;
 
void fun()
{
    flag1++;
}
 
void fun2()
{
    flag2++;
}
 
void timer_conf()
{
  
  timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
  timer_dma_set_burst_len(dev1, 1);
  timer_dma_enable_req(dev1, cc_channel1);
  timer_set_reload(dev1, 102);
  timer_set_prescaler(dev1, 0);
  
  timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
  timer_dma_set_burst_len(dev2, 1);
  timer_dma_enable_req(dev2, cc_channel2);
  timer_set_reload(dev2, 102);
  timer_set_prescaler(dev2, 0);
}
 
void dma_conf()
{
    dma_init(DMA1);
    /* T4C2 DMA C4 */
    dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
    dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
    dma_cfg.tube_src = val1;
    dma_cfg.tube_src_size = DMA_SIZE_32BITS;
    
    dma_cfg.tube_nr_xfers = SAMPLES;
    dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
    
    dma_cfg.tube_req_src = DMA_REQ_SRC_TIM4_CH2;
    dma_cfg.target_data = 0;
    
    ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
    
    /* T1C1 DMA C2 */
    dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
    dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
    dma_cfg.tube_src = val2;
    dma_cfg.tube_src_size = DMA_SIZE_32BITS;
    
    dma_cfg.tube_nr_xfers = SAMPLES;
    dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;
    
    dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1;
    dma_cfg.target_data = 0;
    
    ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
}
 
void dma_start()
{
  dma_attach_interrupt(DMA1, DMA_CH4, fun);
    
  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);
  
  dma_attach_interrupt(DMA1, DMA_CH2, fun2);
    
  dma_enable(DMA1, DMA_CH2);
  timer_resume(dev2);
}
 
void init_wave()
{
  int i;
  for(i=0;i<SAMPLES;i++)
  {
      val1[i] = 50 + amp * sin(stp * i);
      val2[i] = val1[i];
  }
}
 
void get_wave(int16 shift)
{
   int i;
  int ovfi;
    ovfi = 1000 - i;
  for(i=0;i<SAMPLES;i++)
  {
      val2[i] = 50 + amp * sin( stp * i + shift * 0.1 * 6.2831 / 360);
  }
}
 
void setup() {
   lcd.begin(16, 2);
int i;
  pinMode(out1, PWM);
  pinMode(out2, PWM);
 
 }
 
void loop() {
    lcd.setCursor(0, 1);
  lcd.print("SAMPLES ");
    lcd.print(SAMPLES );
 
}
 

 

#define macro substitution is a pre-compilation step, you can't change them at runtime, so your assertion is false.

Not easily. The arrays are static and the size has to be a compile-time constant. The state of the buttons is only available at run time. You would have to change your arrays from statically allocated to dynamically allocated. That will take some research on your part.

How about adding program C ?

What does that mean?

A third program

Sure. Pick another input pin. In setup(), set a global variable to one of three (or four) values based on the state of the input pins . Then, still in setup(), call the chosen setupN(). In loop() call the chosen loopN().

I did this way, error - 'setupC' was not declared in this scope

bool RunA;

void setup()
{
  pinMode(PB9, INPUT_PULLUP);
  RunA = digitalRead(PB9) == HIGH;

  if (RunA)
    setupA();
  else
    setupB();
    
    /////////////
  pinMode(PB8, INPUT_PULLUP);
  RunA = digitalRead(PB8) == HIGH;

  if (RunA)
    setupA();
  else
    setupC();
    ////////////
}

void loop()
{
  if (RunA)
    loopA();
  else
    loopB();

    else
    loopC();
    
}



//A
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
const int analogIn = PA6;
#include <LiquidCrystal.h>
//LiquidCrystal lcd(PB15, PB5, PA2, PB6, PB8, PB9);
//LiquidCrystal lcd(A0, A1, A2, A3, A4, A5);
LiquidCrystal lcd(PA0, PA1, PA2, PA3, PA4, PA5);

float val = 0;// define the variable as value=0

void setupA()
{
  Serial.begin(115200);
  lcd.begin(16, 2);
}

void loopA()
{
  val = analogRead(PA6);
  // val = val / 1024 * 5.0; // Convert the data to the corresponding voltage value in a math

  Serial.println(val);//Print the number of val on the serial monitor

  lcd.setCursor(0, 0);
  lcd.print(val, 1); //Print the number of val on the LCD
  // delay(200); //Wait for 200ms
}
//+++++++++++++++++++++++++++++++++++++++++++



//B
//+++++++++++++++++++++++++++++++++++++++++++=
long microSecs;
long freq;
int lastBit;
int nowVal;
long secs;
long maxHz;
long minHz;
long minmax;

void setupB()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Loading...");
  pinMode(PA7, INPUT);
  pinMode(PA6, OUTPUT);
  microSecs = micros();
  freq = 0;
  lastBit = 0;
  nowVal = 0;
  maxHz = 0;
  minHz = 0;
  minmax = 0;
  secs = millis();
  //Serial.begin(9600);
}

int x = 0;

void loopB()
{
  if ((microSecs + 20) < micros())
  {
    nowVal = digitalRead(PA7);

    if (lastBit != nowVal)
    {
      lastBit = nowVal;
      freq = freq + 1;
    }
    if (freq > maxHz)
    {
      maxHz = freq;
    }
    if (freq < minHz)
    {
      minHz = freq;
    }
    //lcd.clear();
    //lcd.print();
    microSecs = micros();
  }
  
  if (secs + 1000 < millis())
  {
    if (minmax + 300000 < millis())
    {
      minmax = millis();
      minHz = freq;
      maxHz = freq;
    }

    lcd.clear();
    lcd.print((freq / 2));
    lcd.print(" Hz");
    lcd.setCursor(0, 1);
    lcd.print("+: ");
    lcd.print(maxHz);
    lcd.print(" -: ");
    lcd.print(minHz);

    freq = 0;
    secs = millis();
  }
}
//++++++++++++++++++++++++++++++++++++++++


// C
//+++++++++++++++++++++++++++++++++++++++++++++++++++
#define SAMPLES 100


#include <libmaple/dma.h>

struct debounce_info
{
  int start, state;
  int16 shift;
}  up, down;

dma_tube_config dma_cfg, dma_cfg2;

int flag1 = 0;
int flag2 = 0;
/////////////////////////////
int out1 = PA10;
int out2 = PA8;
/////////////////////////////
int val1[SAMPLES];
int val2[SAMPLES];
int ampp = PB9;
int ampn = PB6;
//int ampn = PB11;
int16 shift = 0;
int amp = 35;
int cnt = 0;
int time_track = 0;
float stp = 6.2831 / SAMPLES;
int ret = 17;

//////////////////////////////////////////////////
timer_dev *dev1 = PIN_MAP[out1].timer_device;
uint8 cc_channel1 = PIN_MAP[out1].timer_channel;
//////////////////////////////////////////////////////////

timer_dev *dev2 = PIN_MAP[out2].timer_device;
uint8 cc_channel2 = PIN_MAP[out2].timer_channel;

void fun()
{
  flag1++;
}

void fun2()
{
  flag2++;
}

void timer_conf()
{
  ///////////////////
  timer_dma_set_base_addr(dev1, TIMER_DMA_BASE_CCR2);
  timer_dma_set_burst_len(dev1, 1);
  timer_dma_enable_req(dev1, cc_channel1);
  timer_set_reload(dev1, 102);
  timer_set_prescaler(dev1, 0);
  //////////////////////
  timer_dma_set_base_addr(dev2, TIMER_DMA_BASE_CCR1);
  timer_dma_set_burst_len(dev2, 1);
  timer_dma_enable_req(dev2, cc_channel2);
  timer_set_reload(dev2, 102);
  timer_set_prescaler(dev2, 0);
}

void dma_conf()
{

  dma_init(DMA1);
  //////////////////////////////////////////////////////////////////////////////////
  /* T1C3 DMA C4 */
  dma_cfg.tube_dst = &(dev1->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val1;
  dma_cfg.tube_src_size = DMA_SIZE_32BITS;

  dma_cfg.tube_nr_xfers = SAMPLES;
  dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;

  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH3;  //T1C3, PA10

  dma_cfg.target_data = 0;
  ret = dma_tube_cfg(DMA1, DMA_CH4, &dma_cfg);
  ///////////////////////////////////////////////////////////////////////////////////
  // ampl
  /* T1C1 DMA C2 */
  dma_cfg.tube_dst = &(dev2->regs.gen->DMAR);
  dma_cfg.tube_dst_size = DMA_SIZE_32BITS;
  dma_cfg.tube_src = val2;
  dma_cfg.tube_src_size = DMA_SIZE_32BITS;

  dma_cfg.tube_nr_xfers = SAMPLES;
  dma_cfg.tube_flags = DMA_CFG_SRC_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE;

  dma_cfg.tube_req_src = DMA_REQ_SRC_TIM1_CH1; // T1C1,PA8

  dma_cfg.target_data = 0;
  ret = dma_tube_cfg(DMA1, DMA_CH2, &dma_cfg);
}

void dma_start()
{
  /////////////////////////
  dma_attach_interrupt(DMA1, DMA_CH4, fun);
  dma_enable(DMA1, DMA_CH4);
  timer_resume(dev1);
  ////////////////////////

  dma_attach_interrupt(DMA1, DMA_CH2, fun2); //PA8
  dma_enable(DMA1, DMA_CH2);
  timer_resume(dev2);
}
/////////////////////////////////////////////////////////////////
void init_wave()
{
  int i;
  for (i = 0; i < SAMPLES; i++)
  {
    val1[i] = 50 + amp * sin(stp * i);
    val2[i] = val1[i];
  }
}
/////////////////////////////////////////////////////////////////
void get_wave(int16 shift)
{

  int i;

  for (i = 0; i < SAMPLES; i++)

  {
    val2[i] = 50 + amp * sin( stp * i + shift * 0.1 * 6.2831 / 360);
      val1[i] = 50 + amp * cos( stp * i + shift * 0.1 * 6.2831 / 360);
  }
}

void setup() {

  pinMode(out1, PWM);
  pinMode(out2, PWM);
  
  Serial.begin(9600);

  timer_conf();
  dma_conf();
  dma_start();

  init_wave();


}

void loopC()
{
 
}

Did you forget a C there?

Thanks, this error is gone, I have a new one from this part

void loop()
{
  if (RunA)
    loopA();
  else
    loopB();

    else
    loopC();
    
}

error
'else' without a previous 'if'

An if/else is a binary proposition.

If something is true then do this, else (otherwise) do something (one other thing) else.

Maybe try switch/case,or another if

Now I have no errors, but pin PB9 is not working

bool RunA;

void setup()
{
  pinMode(PB9, INPUT_PULLUP);
  RunA = digitalRead(PB9) == HIGH;

  if (RunA)
    setupA();
  else
    setupB();
    
    /////////////
  pinMode(PB8, INPUT_PULLUP);
  RunA = digitalRead(PB8) == HIGH;

  if (RunA)
    setupA();
  else
    setupC();
    ////////////
}

void loop()
{
  if (RunA)
    loopA();
  else
    loopB();
    
    if (RunA)
    loopA();

    else
    loopC();
    
}

Can you just slow down and start thinking?

If runA is LOW, you'll run loopB and loopC

"not working" in what way, exactly?