Is it possible to have multiple loops?

Hi! is it possible to have two loops?

this is what I want to achieve

loop1
{
  
  //do this continuously 

  if(pin interrupt occurs)
    {
     break and go to loop2
    }   
}

loop2
{
  
  //do this continuously 

  if(pin interrupt occurs)
    {
       break and go to loop1
    }   
}

Thanks! :smiley:

yes, have loop() call loop1() and loop2(), as as many other sub-functions as you'd like

void loop (void)
{
    loop1 ();
    loop2 ();
}

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

But why?

#define INITIAL_ISR 0

byte lastISR = INITIAL_ISR;

void ISR1() { lastISR = 1; }
void ISR2() { lastISR = 2; }

void loop()
{
  if (lastISR == 1)
  {
    //Do this
  }
  else if (lastISR == 2)
  {
    //Do that
  }
}

There is normally one "main" loop().

Beyond that you can have:
[u]for() loops[/u]
[u]while() loops[/u]
[u]do-while() loops[/u]

And, loops can be nested.

The main difference is that the main loop normally runs forever (with most of you other code, including other loops inside that main loop) whereas the other loops usually end or you "break out" under some condition.

Loops and conditional execution (if-statements, etc.) are the two most important & useful programming concepts.

Yes.
Part 1

#include "sdkconfig.h"
#include "esp_system.h" //This inclusion configures the peripherals in the ESP system.
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include <SimpleKalmanFilter.h>
#include <driver/adc.h>
#include "esp_sleep.h"
#include "driver/mcpwm.h"
const int TaskCore1 = 1;
const int TaskCore0 = 0;
const int TaskStack20K = 20000;
const int Priority3 = 3;
const int Priority4 = 4;
volatile bool EnableTracking = true;
////
void setup()
{
  // set up A:D channels
  adc_power_on( );
  vTaskDelay( 1 );
  adc1_config_width(ADC_WIDTH_12Bit);
  // ADC1 channel 0 is GPIO36 (ESP32), GPIO1 (ESP32-S2)
  adc1_config_channel_atten(ADC1_CHANNEL_0 , ADC_ATTEN_DB_11); // azimuth 0
  //  // ADC1_CHANNEL_3  ADC1 channel 3 is GPIO39 (ESP32)
  adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11); // azimuth 1
  //  // ADC1 channel 5 is GPIO33
  adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_DB_11); // altitude 1
  //  // ADC1 channel 6 is GPIO34
  adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); // altitude 0
  //  // adc for light dark detection, ADC1 channel 7 is GPIO35 (ESP32)
  adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_11);
  // control for relay to supply power to the servos
  pinMode( 5, OUTPUT );
  vTaskDelay(1);
  //
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_NUM_4 ); // Azimuth
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_12 ); // Altitude servo
  //
  mcpwm_config_t pwm_config = {};
  pwm_config.frequency = 50;    //frequency = 50Hz, i.e. for every servo motor time period should be 20ms
  pwm_config.cmpr_a = 0;    //duty cycle of PWMxA = 0
  pwm_config.cmpr_b = 0;    //duty cycle of PWMxb = 0
  pwm_config.counter_mode = MCPWM_UP_COUNTER;
  pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
  //
  //
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);    //Configure PWM0A timer 0 with above settings
  mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_1, &pwm_config);    //Configure PWM0A timer 1 with above settings
  //  ////
  fMoveAltitude( 1500 );
  fMoveAzimuth( 900 );
  ////
  xTaskCreatePinnedToCore( TrackSun, "TrackSun", TaskStack20K, NULL, Priority3, NULL, TaskCore1 ); // assigned to core
  xTaskCreatePinnedToCore( fDaylight, "fDaylight", TaskStack20K, NULL, Priority3, NULL, TaskCore0 ); // assigned to core
  ////  // esp_sleep_enable_timer_wakeup( (60000000 * 2) ); // set timer to wake up once a minute 60000000uS
}
//
void fDaylight( void * pvParameters )
{
  int lightLevel = 0;
  while (1)
  {
     lightLevel = adc1_get_raw(ADC1_CHANNEL_7);
     if ( adc1_get_raw(ADC1_CHANNEL_7) <= 300 )
     {
     // if light level to low park boom
     fMoveAltitude( 1475 );
     vTaskDelay( 30 );
     fMoveAzimuth( 2000 );
     vTaskDelay( 25 );
     // put esp32 into deep sleep
     EnableTracking = false;
     digitalWrite( 5, HIGH ); // remove power from relay module.
     vTaskDelay( 1 );
     esp_sleep_enable_timer_wakeup( (60000000 * 2) ); // set timer to wake up once a minute 60000000uS
     esp_deep_sleep_start();
     } else {
    digitalWrite( 5, LOW ); // energize servo motors
    EnableTracking = true;
     }
    vTaskDelay( 1000 );
  } // while(1)
} // void fDaylight( void * pvParameters )
////
void mcpwm_gpio_initialize(void)
{
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM1A, GPIO_NUM_4 );
  mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_NUM_12 );
}
////
// void TrackSun( int Altitude, int Azimuth )
void TrackSun( void * pvParameters )
{
  int64_t EndTime = esp_timer_get_time();
  int64_t StartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros
  int Altitude = 1500;
  int Azimuth = 900;
  int maxAltitudeRange = 2144;
  int minAltitudeRange = 900;
  int maxAzimuthRange = 2144;
  int minAzimuthRange = 900;
  float AltitudeThreashold = 10.0f;
  float AzimuthThreashold = 10.0f;
  float kalmanThreshold = 80.0f;
  SimpleKalmanFilter kfAltitude0( AltitudeThreashold, kalmanThreshold, .01 ); // kalman filter Altitude 0
  SimpleKalmanFilter kfAltitude1( AltitudeThreashold, kalmanThreshold, .01 ); // kalman filter Altitude 1
  SimpleKalmanFilter kfAzimuth0( AzimuthThreashold, kalmanThreshold, .01 ); // kalman filter Azimuth 0
  SimpleKalmanFilter kfAzimuth1( AzimuthThreashold, kalmanThreshold, .01 ); // kalman filter Azimuth 1
  float filteredAltitude_0 = 0.0f;
  float filteredAltitude_1 = 0.0f;
  float filteredAzimuth_0 = 0.0f;
  float filteredAzimuth_1 = 0.0f;
  uint64_t AzimuthEndTime = esp_timer_get_time();
  uint64_t AzimuthStartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros,
  uint64_t AltitudeEndTime = esp_timer_get_time();
  uint64_t AltitudeStartTime = esp_timer_get_time(); //gets time in uSeconds like Arduino Micros,
  int StartupCount = 0;
  int TorqueAmmount = 5;
  while (1)
  {
    if ( EnableTracking )
    {
      //Altitude
      AltitudeEndTime = esp_timer_get_time() - AltitudeStartTime; // produce elasped time for the simpleKalmanFilter
      kfAltitude0.setProcessNoise( float(AltitudeEndTime) / 1000000.0f );
      kfAltitude1.setProcessNoise( float(AltitudeEndTime) / 1000000.0f );
      filteredAltitude_0 = kfAltitude0.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_6) );
      filteredAltitude_1 = kfAltitude1.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_5) );
      if ( (filteredAltitude_0 > filteredAltitude_1) && (abs(filteredAltitude_0 - filteredAltitude_1) > AltitudeThreashold))
      {
        Altitude -= TorqueAmmount;
        if ( Altitude < minAltitudeRange )
        {
          Altitude = 900;
        }
        fMoveAltitude( Altitude );
        AltitudeStartTime = float(esp_timer_get_time());
      }
      if ( (filteredAltitude_0 < filteredAltitude_1) && (abs(filteredAltitude_0 - filteredAltitude_1) > AltitudeThreashold) )
      {
        Altitude += TorqueAmmount;
        if ( Altitude >= maxAltitudeRange )
        {
          Altitude = 900;
        }
        fMoveAltitude( Altitude );
        AltitudeStartTime = esp_timer_get_time();
      }
 
////

There are 2 main tasks that run in a loop on its own core. With the proper hardware what you ask is quite possible.

part 2

     //// AZIMUTH
      AzimuthEndTime = esp_timer_get_time() - AzimuthStartTime; // produce elasped time for the simpleKalmanFilter
      kfAzimuth0.setProcessNoise( float(AzimuthEndTime) / 1000000.0f ); //convert time of process to uS, update SimpleKalmanFilter q
      kfAzimuth1.setProcessNoise( float(AzimuthEndTime) / 1000000.0f ); //convert time of process to uS, update SimpleKalmanFilter q
      filteredAzimuth_0 = kfAzimuth0.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_3) );
      filteredAzimuth_1 = kfAzimuth1.updateEstimate( (float)adc1_get_raw(ADC1_CHANNEL_0) );
      if ( (filteredAzimuth_0 > filteredAzimuth_1) && (abs(filteredAzimuth_0 - filteredAzimuth_1)) > AzimuthThreashold )
      {
        Azimuth += TorqueAmmount;
        if ( Azimuth >= maxAzimuthRange )
        {
          Azimuth = 900;
        }
        fMoveAzimuth( Azimuth );
        AzimuthStartTime = esp_timer_get_time();
      }
      //    //
      if ( (filteredAzimuth_0 < filteredAzimuth_1) && (abs(filteredAzimuth_1 - filteredAzimuth_0)) > AzimuthThreashold )
      {
        Azimuth -= TorqueAmmount; // make new position to torque to
        if ( (Azimuth >= maxAzimuthRange) || (Azimuth <= minAzimuthRange) )
        {
          Azimuth = 900;
        }
        fMoveAzimuth( Azimuth );
        AzimuthStartTime = esp_timer_get_time();
      } //azmiuth end
      if ( StartupCount < 500 )
      {
        ++StartupCount;
        vTaskDelay( 10 );
      } else {
        TorqueAmmount = 1;
        esp_sleep_enable_timer_wakeup( (60000000 / 20) ); // set timer to wake up
        esp_light_sleep_start();
      }
    }
  } // while(1)
} //void TrackSun()
////
void fMoveAltitude( int MoveTo )
{
  mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, MoveTo);
  vTaskDelay( 12 );
}
//////
void fMoveAzimuth( int MoveTo )
{
  mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_1, MCPWM_OPR_A, MoveTo);
  vTaskDelay( 12 );
}
////
void loop() {}