Door opener with 4x4 keypad via MQTT.

Here is some ESP code I wrote that opens WiFi, connects to a MQTT Broker, maintains an open connection and publishes stuff.

#include <WiFi.h>
#include <PubSubClient.h>
#include "certs.h" // include the connection infor for WiFi and MQTT
#include "sdkconfig.h" // used for log printing
#include "esp_system.h"
#include "freertos/FreeRTOS.h" //freeRTOS items to be used
#include "freertos/task.h"
#include <SPI.h> // ada fruity needs this ...
#include <Adafruit_Sensor.h> // and this ...
#include <Adafruit_BME280.h> // to run this library
#include <driver/adc.h>
#include "esp32-hal-ledc.h"
////
Adafruit_BME280 bme280( GPIO_NUM_5 ); // use hardware SPI, set GPIO pin to use
WiFiClient      wifiClient; // do the WiFi instantiation thing
PubSubClient    MQTTclient( mqtt_server, mqtt_port, wifiClient ); //do the MQTT instantiation thing
////
#define evtDoParticleRead   ( 1 << 0 ) // declare an event
#define evtWaitForBME       ( 1 << 1 )
#define evtDoBlue           ( 1 << 2 )
#define evtDoRed            ( 1 << 3 )
#define evtDoGreen          ( 1 << 4 )
EventGroupHandle_t eg; // variable for the event group handle
////
String AirQuality;
////
esp_timer_handle_t oneshot_timer; //veriable to store the hardware timer handle
////
////
void IRAM_ATTR oneshot_timer_callback( void* arg )
{
  BaseType_t xHigherPriorityTaskWoken;
  xEventGroupSetBitsFromISR( eg, evtDoParticleRead, &xHigherPriorityTaskWoken ); 
} //void IRAM_ATTR oneshot_timer_callback( void* arg )
////
/*
   This semaphore is used to stop or prevent a publish from happening during client.loop()
*/
SemaphoreHandle_t sema_MQTT_KeepAlive;
////
// interrupt service routine for WiFi events put into IRAM
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      log_i("Connected to access point");
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
////
void setup()
{
  // red
  ledcSetup( 6, 12000, 8 ); // ledc: 4  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_14, 6 );   // gpio number and channel
  ledcWrite( 6, 0 ); // write to channel number 6
  // green
  ledcSetup( 5, 12000, 8 ); // ledc: 5  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_13, 5 );   // gpio number and channel
  ledcWrite( 5, 0 ); // write to channel number 5
  // blue
  ledcSetup( 4, 12000, 8 ); // ledc: 4  => Group: 0, Channel: 2, Timer: 1, led frequency, resolution  bits // blue led
  ledcAttachPin( GPIO_NUM_12, 4 );   // gpio number and channel
  ledcWrite( 4, 0 ); // write to channel number 4
  //
  eg = xEventGroupCreate(); // get an event group handle
  //
  gpio_config_t io_cfg = {}; // initialize the gpio configuration structure
  io_cfg.mode = GPIO_MODE_OUTPUT; // set gpio mode
  //bit mask of the pins to set
  io_cfg.pin_bit_mask = ( (1ULL << GPIO_NUM_4) ); // assign gpio number to be configured
  //configure GPIO with the given settings
  gpio_config(&io_cfg); // configure the gpio based upon the parameters as set in the configuration structure
  gpio_set_level( GPIO_NUM_4, LOW); // set air particle sensor trigger pin to LOW
  // set up A:D channels
  // https://dl.espressif.com/doc/esp-idf/latest/api-reference/peripherals/adc.html
  adc1_config_width(ADC_WIDTH_12Bit);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);// using GPIO 36
  //
  // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/esp_timer.html?highlight=hardware%20timer High Resoultion Timer API
  esp_timer_create_args_t oneshot_timer_args = {}; // initialize High Resoulition Timer (HRT) configuration structure
  oneshot_timer_args.callback = &oneshot_timer_callback; // configure for callback, name of callback function
  esp_timer_create( &oneshot_timer_args, &oneshot_timer ); // assign configuration to the HRT, receive timer handle
  //
  xTaskCreatePinnedToCore( MQTTkeepalive, "MQTTkeepalive", 20000, NULL, 5, NULL, 1 ); // create and start the two tasks to be used, set those task to use 20K stack
  xTaskCreatePinnedToCore( DoTheBME280Thing, "DoTheBME280Thing", 20000, NULL, 4, NULL, 1);
  xTaskCreatePinnedToCore( fDoBlue, "fDoBlue", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoRed, "fDoRed", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoGreen, "fDoGreen", 4000, NULL, 3, NULL, 1 );
  xTaskCreatePinnedToCore( fDoParticleDetector, "fDoParticleDetector", 6000, NULL, 3, NULL, 1 ); // assign all to core 1
  
} //void setup()
////
void fDoRed( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoRed, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    //log_i( "red %d", countUpDown );
    ledcWrite( 6, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoRed( void * paramater )
////
void fDoGreen( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoGreen, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    //log_i( "green %d", countUpDown );
    ledcWrite( 5, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoGreen( void * paramater )
////
void fDoBlue( void * paramater )
{
  bool UpDown = true;
  int countUpDown = 0;
  for( ;; )
  {
     xEventGroupWaitBits (eg, evtDoBlue, pdTRUE, pdTRUE, portMAX_DELAY );
     // send led data, increment led count, determine end stops and direction
    if ( UpDown )
    {
      countUpDown++;
    } else {
      countUpDown--;
    }
    if ( countUpDown <= 0 )
    {
      UpDown = true;
    }
    if ( countUpDown >= 255 )
    {
      UpDown = false;
    }
    // log_i( "blue %d", countUpDown );
    ledcWrite( 4, countUpDown ); // write to channel number 4
    //
  }
   vTaskDelete( NULL );
} // void fDoBlue( void * paramater )
//