// defines

// Board pins
#define LED1 38
#define LED2 37
#define BUTTON1 36
#define BUTTON2 35

#define LED1_TASK_CORE 0
#define LED2_TASK_CORE 0
#define BUTTON1_TASK_CORE 1
#define BUTTON2_TASK_CORE 1

#define LED1_TASK_PRIORITY 3
#define LED2_TASK_PRIORITY 3
#define BUTTON1_TASK_PRIORITY 4
#define BUTTON2_TASK_PRIORITY 5

#define LED1_TASK_STACK_SIZE 2000
#define LED2_TASK_STACK_SIZE 2000
#define BUTTON1_TASK_STACK_SIZE 2000
#define BUTTON2_TASK_STACK_SIZE 2000

#define BUTTON1_TASK_DELAY_MS 50
#define BUTTON2_TASK_DELAY_MS 50

#define LEDMODE_MAX_ITENS 10

typedef enum {
  lmClear = 0,
  lmSolid,
  lmSlowBlink,
  lmBlink,
  lmFastBlink,
  lmCustom
} enLedMode;

// led modes
typedef struct {
  unsigned char state;
  unsigned int  delay;
} xLedMode;

typedef struct {
  unsigned char pin;
  unsigned char mode;
  unsigned char change;
} xLed;

// consts

const xLedMode LED_MODES[][LEDMODE_MAX_ITENS] = {
  {
   {0, 100}			// off
   },
  {
   {1, 100}			// on
   },

  {
   {0, 1000},			// slow blink
   {1, 1000},
   },

  {
   {0, 500},			// normal blink
   {1, 500},
   },

  {
   {0, 2000},			// fast blink, aka pulse
   {1, 250},
   },

  {
   {0, 500},			// custom blink
   {1, 500},
   {0, 250},
   {1, 250},
   {0, 500},
   {1, 500},
   {0, 1000},
   {1, 1000}
   }
};


// function prototypes

void appSetup(void);
void appShowLedModes(void);

void appTasksCreate(void);

void led1TaskCreate   (void);
void led2TaskCreate   (void);
void button1TaskCreate(void);
void button2TaskCreate(void);

static void led1Task   (void *pvParameters);
static void led2Task   (void *pvParameters);
static void button1Task(void *pvParameters);
static void button2Task(void *pvParameters);

// public variables
xLed led1, led2;

TaskHandle_t led1TaskHandle;
TaskHandle_t led2TaskHandle;
TaskHandle_t button1TaskHandle;
TaskHandle_t button2TaskHandle;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  appSetup();
  appTasksCreate();
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.printf("----- START APPLICATION -----\n");
  vTaskDelete(NULL);
}

void appSetup(void)
{

  led1.pin    = LED1;
  led1.mode   = lmClear;
  led1.change = false;

  led2.pin    = LED2;
  led2.mode   = lmClear;
  led2.change = false;

  pinMode(led1.pin, OUTPUT);
  pinMode(led2.pin, OUTPUT);

  pinMode(BUTTON1, INPUT_PULLUP);
  pinMode(BUTTON2, INPUT_PULLUP);
  
  digitalWrite(led1.pin, LOW);
  digitalWrite(led2.pin, LOW);

}


// just check LED_MODES array
void appShowLedModes(void)
{
  int x, y, length;

  const xLedMode *ptr = NULL;

  length = (sizeof(LED_MODES) / sizeof(xLedMode)) / LEDMODE_MAX_ITENS;

  Serial.printf("Size LED_MODES: %d\n", sizeof(LED_MODES));
  Serial.printf("Size xLedMode: %d\n", sizeof(xLedMode));
  Serial.printf("Length: %d\n", length);

  for (y = 0; y < length; y++)
  {
    ptr = LED_MODES[y];
    for (x = 0; x < LEDMODE_MAX_ITENS; x++)
	  {
	    Serial.printf("Index: %d -- State: %d -- Delay: %d\n", x, (ptr + x)->state, (ptr + x)->delay);
	  }
  }

}

void appTasksCreate(void)
{
  led1TaskCreate();
  led2TaskCreate();
  button1TaskCreate();
  button2TaskCreate();
}

void led1TaskCreate(void)
{
    BaseType_t rc;
    rc = xTaskCreatePinnedToCore
    (
        led1Task,
        "LED1",
        LED1_TASK_STACK_SIZE,
        NULL,
        LED1_TASK_PRIORITY,
        &led1TaskHandle,
        LED1_TASK_CORE
    );
    assert(rc == pdPASS);
}

void led2TaskCreate(void)
{
    BaseType_t rc;
    rc = xTaskCreatePinnedToCore
    (
        led2Task,
        "LED2",
        LED2_TASK_STACK_SIZE,
        NULL,
        LED2_TASK_PRIORITY,
        &led2TaskHandle,
        LED2_TASK_CORE
    );
    assert(rc == pdPASS);
}


void button1TaskCreate(void)
{
    BaseType_t rc;
    rc = xTaskCreatePinnedToCore
    (
        button1Task,
        "BUTTON1",
        BUTTON1_TASK_STACK_SIZE,
        NULL,
        BUTTON1_TASK_PRIORITY,
        &button1TaskHandle,
        BUTTON1_TASK_CORE
    );
    assert(rc == pdPASS);
}

void button2TaskCreate(void)
{
    BaseType_t rc;
    rc = xTaskCreatePinnedToCore
    (
        button2Task,
        "BUTTON2",
        BUTTON2_TASK_STACK_SIZE,
        NULL,
        BUTTON2_TASK_PRIORITY,
        &button2TaskHandle,
        BUTTON2_TASK_CORE
    );
    assert(rc == pdPASS);
}

static void led1Task(void *pvParameters)
{
  static const xLedMode *ptr = LED_MODES[led1.mode];
  for(;;)
  {
    if (led1.change)
    {
      led1.change = false;
      ++led1.mode %= (lmCustom+1);
      ptr = LED_MODES[led1.mode];
      Serial.printf("Led 1 Mode: %d\n", led1.mode);
    }

    digitalWrite(LED1, ptr->state);
    vTaskDelay(pdMS_TO_TICKS(ptr->delay));

    ptr++;

    if (ptr->delay == 0)
    {
      ptr = LED_MODES[led1.mode];
    }
  }
}

static void led2Task(void *pvParameters)
{
  static const xLedMode *ptr = LED_MODES[led2.mode];
  for(;;)
  {
    if (led2.change)
    {
      led2.change = false;
      ++led2.mode %= (lmCustom+1);
      ptr = LED_MODES[led2.mode];
      Serial.printf("Led 2 Mode: %d\n", led2.mode);
    }

    digitalWrite(LED2, ptr->state);
    vTaskDelay(pdMS_TO_TICKS(ptr->delay));

    ptr++;

    if (ptr->delay == 0)
    {
      ptr = LED_MODES[led2.mode];
    }
  }
}

static void button1Task(void *pvParameters)
{
  static int free = true;
  for(;;)
  {
    if (!digitalRead(BUTTON1) && free)
    {
      free = false;
      led1.change = true;
    }

    if (digitalRead(BUTTON1) && !free)
    {
      free = true;
    }
    vTaskDelay(pdMS_TO_TICKS(BUTTON1_TASK_DELAY_MS));
  }

}

static void button2Task(void *pvParameters)
{
  static int free = true;
  for(;;)
  {
    if (!digitalRead(BUTTON2) && free)
    {
      free = false;
      led2.change = true;
    }

    if (digitalRead(BUTTON2) && !free)
    {
      free = true;
    }
    vTaskDelay(pdMS_TO_TICKS(BUTTON2_TASK_DELAY_MS));
  }
}





Loading
esp32-s3-devkitc-1