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