ESP32 - RTOS - Example project

This tutorial instructs you how to use RTOS with ESP32 to make a project that include IR sensor (status) +OLED, Button (toggle)+Motor, Buzzer(Police note)+LED (blinking)

Video Tutorial

you can watch this video tutorial

Hardware Required

1×ESP-WROOM-32 Dev Module
1×Micro USB Cable
1×IR sensor
1×OLED Display
1×Button
1×Motor
1×Buzzer
1×LED
1×Breadboard
n×Jumper Wires

About This project

We will make a project that include IR sensor (status) +OLED, Button (toggle)+Motor, Buzzer(Police note)+LED (blinking)

Review Topics

Please review this topics to get a better understand of this project

  • Basic RTOS project. go to this link
  • OLED tutorial. go to this link
  • IR tutorial. go to this link
  • Button tutorial. go to this link
  • Motor tutorial. go to this link
  • BUZZER tutorial. go to this link
  • LED tutorial. go to this link

Wiring Diagram

ESP32 Button LED Wiring Diagram

Image is developed using Fritzing. Click to enlarge image

click to see ESP32 pin out
Copy

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE 0
#else
#define ARDUINO_RUNNING_CORE 1
#endif


#include 
#include 
#include 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);



// Motor 
int motor1Pin1 = 27; 
int motor1Pin2 = 26; 
int enable1Pin = 25; 
// Setting PWM properties
const int m_freq = 30000;
const int m_pwmChannel = 3;
const int m_resolution = 8;
int m_dutyCycle = 200;


int BUZZER_PIN = 13;
int BUZZER_CHANNEL = 0;

int ButtonPin = 14;
int ButtonStatus = 0;

int IrPin = 19;
int IrStatus = 0;



void TaskIR     ( void *pvParameters );
void TaskOLED   ( void *pvParameters );
void TaskBUTTON ( void *pvParameters );
void TaskMOTOR  ( void *pvParameters );
void TaskBUZZER ( void *pvParameters );
void TaskLED    ( void *pvParameters );

void setup() {

  // Now set up three tasks to run independently.
  xTaskCreatePinnedToCore(
    TaskIR
    ,  "TaskIR"   // A name just for humans
    ,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

    xTaskCreatePinnedToCore(
    TaskOLED
    ,  "TaskOLED"   // A name just for humans
    ,  4024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

    xTaskCreatePinnedToCore(
    TaskBUTTON
    ,  "TaskBUTTON"   // A name just for humans
    ,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);
    xTaskCreatePinnedToCore(
    TaskMOTOR
    ,  "TaskMOTOR"   // A name just for humans
    ,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

    xTaskCreatePinnedToCore(
    TaskBUZZER
    ,  "TaskBUZZER"   // A name just for humans
    ,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);

    xTaskCreatePinnedToCore(
    TaskLED
    ,  "TaskLED"   // A name just for humans
    ,  1024  // This stack size can be checked & adjusted by reading the Stack Highwater
    ,  NULL
    ,  2  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL 
    ,  ARDUINO_RUNNING_CORE);
    
  
  Serial.begin(115200);
  
}

void loop() {
  
}

void TaskLED(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
*/

  // initialize digital LED_BUILTIN on pin 13 as an output.
  pinMode(12, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(12, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay(500);  // one tick delay (15ms) in between reads for stability
    digitalWrite(12, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay(500);  // one tick delay (15ms) in between reads for stability
  }
}
void TaskOLED(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  OLED
  Show status of all elements on the projects
*/

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  vTaskDelay(2000); // Pause for 2 seconds

  display.clearDisplay();                 // clear display
  display.setTextSize(1);                 // set text size
  display.setTextColor(WHITE, BLACK);     // set text color

  for (;;) // A Task shall never return or exit.
  {
    if(ButtonStatus==1)
    {
      display.setCursor(5, 5);                   // set position to display
      display.println("button status : ON ");    // set text
      display.display();                         // display on OLED
    }
    else
    {
      display.setCursor(5, 5);                   // set position to display
      display.println("button status : OFF");    // set text
      display.display();                         // display on OLED
    }

    if(IrStatus==1)
    {
      display.setCursor(5, 20);                     // set position to display
      display.println("IR status : ON ");    // set text
      display.display();                         // display on OLED
    }
    else
    {
      display.setCursor(5, 20);                     // set position to display
      display.println("IR status : OFF");    // set text
      display.display();                         // display on OLED
    }
    
  }
}

void TaskMOTOR(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  MOTOR
  Controll the motor
*/

  // sets the pins as outputs:
  pinMode(motor1Pin1, OUTPUT);
  pinMode(motor1Pin2, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  
  // configure LED PWM functionalitites
  ledcSetup(m_pwmChannel, m_freq, m_resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(enable1Pin, m_pwmChannel);

  for (;;) // A Task shall never return or exit.
  {
    // Move the DC motor forward at maximum speed
    Serial.println("Moving Forward");
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, HIGH); 
    vTaskDelay(2000);
  
    // Stop the DC motor
    Serial.println("Motor stopped");
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, LOW);
    vTaskDelay(1000);
  
    // Move DC motor backwards at maximum speed
    Serial.println("Moving Backwards");
    digitalWrite(motor1Pin1, HIGH);
    digitalWrite(motor1Pin2, LOW); 
    vTaskDelay(2000);
  
    // Stop the DC motor
    Serial.println("Motor stopped");
    digitalWrite(motor1Pin1, LOW);
    digitalWrite(motor1Pin2, LOW);
    vTaskDelay(1000);
  }
}

void TaskBUZZER(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  Buzzer
  play police note on the buzzer
*/

  ledcAttachPin(BUZZER_PIN, BUZZER_CHANNEL);

  for (;;) // A Task shall never return or exit.
  {
    ledcSetup(BUZZER_CHANNEL, 635, 8);
    ledcWrite(BUZZER_CHANNEL, 50);
    vTaskDelay(700);
    ledcSetup(BUZZER_CHANNEL, 911, 8);
    ledcWrite(BUZZER_CHANNEL, 50);
    vTaskDelay(700);
  }
}

void TaskBUTTON(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  Button
  read the state of the button
*/

  // initialize Button pin as an INPUT.
  pinMode(ButtonPin,INPUT_PULLUP);

  for (;;) // A Task shall never return or exit.
  {
    if (digitalRead(ButtonPin)== LOW)
    {
        ButtonStatus = 1;
        vTaskDelay(10);
    }
    else
    {
      ButtonStatus = 0;
      vTaskDelay(10);
    }
  }
}

void TaskIR(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

/*
  IR sensor
  read the state of the IR sensor
*/

  // initialize IR pin as an INPUT.
  pinMode(IrPin,INPUT);

  for (;;) // A Task shall never return or exit.
  {
    if (digitalRead(IrPin)== LOW)
    {
        IrStatus = 1;
        vTaskDelay(10);
    }
    else
    {
      IrStatus = 0;
      vTaskDelay(10);
    }
  }
}           

Quick Steps

  • power up your board
  • Open Arduino IDE
  • Select the right board
  • Select the right port
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to ESP32
  • Arduino IDE Upload Code
  • See the changes you made

Book Tutorial

We are considering to make the book tutorials. If you think the book tutorials are essential, you can download it. download book

References

※ NOTE THAT:

Some components works on 3.3v and others works on 5v!