// 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));
}
}