2021-01-21 00:01:27 +01:00
/**
* @ file Blinky_LED . c
* @ brief Demo application using the mesh network
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Additional Infos : If button " BOOT " on ESP32 - Module is pressed , all LED2 ( blue ) in the network will toggle the state .
*/
2021-01-16 00:23:02 +01:00
# include "Blinky_LED.h"
static const char * LOG_TAG = " blinky_led " ;
2021-01-16 18:23:10 +01:00
static bool bLEDisOn = false ; //set led default off
2021-01-21 00:01:27 +01:00
static mesh_addr_t addrParent ; //addr of parent node
2021-01-16 18:23:10 +01:00
static mesh_addr_t childrenAddr [ CONFIG_MESH_ROUTE_TABLE_SIZE ] ; //array of children attached to this node
static uint16_t u16ChildrenSize ; //number of children attached to this node
xQueueHandle queueBlinkyLEDPackets ; //handle for led action queue
2021-01-16 00:23:02 +01:00
2021-01-21 00:01:27 +01:00
/**
* @ fn esp_err_t errBlinkyLEDInitialize ( )
* @ brief Starts the demp app
* @ param void
* @ return ESP32 error code
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Initialize the queue and starts the tasks
*/
esp_err_t errBlinkyLEDInitialize ( void )
2021-01-16 00:23:02 +01:00
{
esp_err_t err = ESP_OK ;
BaseType_t xReturned ;
vGPIOInitialize ( ) ;
2021-01-16 18:23:10 +01:00
//create queue to store led action created from BTN and mesh network events
queueBlinkyLEDPackets = xQueueCreate ( 5 , sizeof ( BLINKY_PACKET_t ) ) ;
2021-01-16 00:23:02 +01:00
if ( queueBlinkyLEDPackets = = 0 ) // Queue not created
2021-01-17 23:47:59 +01:00
{
ESP_LOGE ( LOG_TAG , " Unable to create Queue for Application Packets " ) ;
err = ESP_FAIL ;
}
2021-01-16 00:23:02 +01:00
2021-01-16 18:23:10 +01:00
//register the receiver handle in mesh network
ERROR_CHECK ( errMeshNetworkSetAppReceiveHandle ( rxHandle ) ) ;
2021-01-16 00:23:02 +01:00
if ( err = = ESP_OK )
{
2021-01-17 23:47:59 +01:00
xReturned = xTaskCreate ( vTaskReadUserInput , " vTaskReadUserInput " , 4096 , NULL , 5 , NULL ) ;
if ( xReturned ! = pdPASS )
{
err = ESP_FAIL ;
}
2021-01-16 00:23:02 +01:00
}
if ( err = = ESP_OK )
{
2021-01-17 23:47:59 +01:00
xReturned = xTaskCreate ( vTaskReceiveData , " vTaskReceiveData " , 4096 , NULL , 5 , NULL ) ;
if ( xReturned ! = pdPASS )
{
err = ESP_FAIL ;
}
2021-01-16 00:23:02 +01:00
}
return err ;
}
2021-01-21 00:01:27 +01:00
/**
* @ fn void vGPIOInitialize ( void )
* @ brief sets the GPIO pins to correct modes
* @ param void
* @ return void
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Initialize GPIO
*/
void vGPIOInitialize ( void )
2021-01-16 00:23:02 +01:00
{
gpio_config_t gpioConf ;
//LED as Output
gpio_reset_pin ( GPIO_LED ) ;
gpio_set_direction ( GPIO_LED , GPIO_MODE_OUTPUT ) ;
//BTN as Input
gpioConf . intr_type = GPIO_INTR_DISABLE ;
gpioConf . mode = GPIO_MODE_INPUT ;
gpioConf . pin_bit_mask = GPIO_INPUT_PIN_SEL ;
gpioConf . pull_down_en = 0 ;
gpioConf . pull_up_en = 1 ;
gpio_config ( & gpioConf ) ;
}
2021-01-21 00:01:27 +01:00
/**
* @ fn void rxHandle ( const uint8_t * const pu8Data , const uint8_t * const pu8Sender )
* @ brief callback handler from mesh network layer
* @ param pu8Data data received
* @ param pu8Sender sender node from data
* @ return void
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Adds the data into queue
*/
2021-01-20 22:39:18 +01:00
void rxHandle ( const uint8_t * const pu8Data , const uint8_t * const pu8Sender )
2021-01-16 18:23:10 +01:00
{
//send payload to app queue
BLINKY_PACKET_t bTmpPacket ;
memcpy ( & bTmpPacket , ( uint8_t * ) pu8Data , sizeof ( BLINKY_PACKET_t ) ) ;
memcpy ( & bTmpPacket . meshSenderAddr , ( uint8_t * ) pu8Sender , 6 ) ; //copy MAC from sender into app packet
if ( xQueueSend ( queueBlinkyLEDPackets , & bTmpPacket , portMAX_DELAY ) ! = pdPASS )
2021-01-17 23:47:59 +01:00
{
ESP_LOGE ( LOG_TAG , " Unable to push packet from mesh into Queue " ) ;
}
2021-01-16 18:23:10 +01:00
}
2021-01-21 00:01:27 +01:00
/**
* @ fn void vTaskReadUserInput ( void * arg )
* @ brief FreeRTOS task reading the user input ( button )
* @ param args parameter for task
* @ return void
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Adds a button press to the queue
*/
2021-01-16 00:23:02 +01:00
void vTaskReadUserInput ( void * arg )
{
2021-01-16 18:23:10 +01:00
esp_err_t err = ESP_OK ;
BLINKY_PACKET_t bTmpPacket ;
MESH_PACKET_t meshPacket ;
bTmpPacket . type = LED_OFF ; //default off
meshPacket . type = APP_Data ; //this is a app packet
2021-01-16 00:23:02 +01:00
while ( true )
{
2021-01-17 23:47:59 +01:00
//check for BTN press
if ( gpio_get_level ( GPIO_BOOT_BTN ) = = 0 )
2021-01-16 18:23:10 +01:00
{
2021-01-17 23:47:59 +01:00
err = ESP_OK ;
if ( bLEDisOn = = false )
{
bTmpPacket . type = LED_ON ;
}
else
{
bTmpPacket . type = LED_OFF ;
}
//push led action into queue
if ( xQueueSend ( queueBlinkyLEDPackets , & bTmpPacket , portMAX_DELAY ) ! = pdPASS )
{
ESP_LOGE ( LOG_TAG , " Unable to push packet into queue " ) ;
}
memcpy ( meshPacket . au8Payload , & bTmpPacket , sizeof ( BLINKY_PACKET_t ) ) ;
2021-01-20 21:40:51 +01:00
if ( bMeshNetworkIsRootNode ( ) = = false )
2021-01-17 23:47:59 +01:00
{
//this node is not root --> send led action to parent
2021-01-20 21:40:51 +01:00
ERROR_CHECK ( errMeshNetworkGetParentNode ( & addrParent ) ) ;
ERROR_CHECK ( errMeshNetworkSendMeshPacket ( & addrParent , & meshPacket ) ) ;
2021-01-17 23:47:59 +01:00
}
else
{
//this node is root --> send led action to children
2021-01-20 21:40:51 +01:00
ERROR_CHECK ( errMeshNetworkGetChildren ( childrenAddr , & u16ChildrenSize ) ) ;
2021-01-17 23:47:59 +01:00
for ( uint16_t u16Index = 0 ; u16Index < u16ChildrenSize ; u16Index + + )
{
2021-01-20 21:40:51 +01:00
ERROR_CHECK ( errMeshNetworkSendMeshPacket ( & childrenAddr [ u16Index ] , & meshPacket ) ) ;
2021-01-17 23:47:59 +01:00
}
}
vTaskDelay ( 200 / portTICK_PERIOD_MS ) ;
2021-01-16 18:23:10 +01:00
}
2021-01-17 23:47:59 +01:00
vTaskDelay ( 50 / portTICK_PERIOD_MS ) ;
2021-01-16 00:23:02 +01:00
}
}
2021-01-21 00:01:27 +01:00
/**
* @ fn void vTaskReceiveData ( void * arg )
* @ brief FreeRTOS task reading queue and setting the LED
* @ param args parameter for task
* @ return void
* @ author Hendrik Schutter
* @ date 20.01 .2021
*
* Sets the LED off or on based on data in queue
*/
2021-01-16 00:23:02 +01:00
void vTaskReceiveData ( void * arg )
{
2021-01-16 18:23:10 +01:00
esp_err_t err = ESP_OK ;
MESH_PACKET_t meshPacket ;
BLINKY_PACKET_t bTmpPacket ;
bTmpPacket . type = LED_OFF ; //default off
meshPacket . type = APP_Data ; //this is a app packet
2021-01-16 00:23:02 +01:00
while ( 1 )
{
2021-01-17 23:47:59 +01:00
if ( xQueueReceive ( queueBlinkyLEDPackets , & bTmpPacket , portMAX_DELAY ) ! = pdTRUE )
{
ESP_LOGE ( LOG_TAG , " Unable to receive packet from Queue " ) ;
}
else
{
err = ESP_OK ;
//Successfully RECEIVED the packet
switch ( bTmpPacket . type )
{
case LED_ON :
bLEDisOn = true ;
gpio_set_level ( GPIO_LED , 1 ) ; //switch on
ESP_LOGI ( LOG_TAG , " switch LED ON " ) ;
break ;
case LED_OFF :
bLEDisOn = false ;
gpio_set_level ( GPIO_LED , 0 ) ; //switch off
ESP_LOGI ( LOG_TAG , " switch LED OFF " ) ;
break ;
default :
bLEDisOn = false ;
gpio_set_level ( GPIO_LED , 0 ) ; //switch off
ESP_LOGI ( LOG_TAG , " switch LED OFF " ) ;
break ;
}
}
2021-01-16 18:23:10 +01:00
2021-01-20 21:40:51 +01:00
ERROR_CHECK ( errMeshNetworkGetChildren ( childrenAddr , & u16ChildrenSize ) ) ; //get all children attached to this node
2021-01-17 23:47:59 +01:00
memcpy ( meshPacket . au8Payload , & bTmpPacket , sizeof ( BLINKY_PACKET_t ) ) ; //copy led action in mesh packet payload
2021-01-16 18:23:10 +01:00
2021-01-17 23:47:59 +01:00
for ( uint16_t u16Index = 0 ; u16Index < u16ChildrenSize ; u16Index + + )
{
//loop through children
2021-01-21 11:43:09 +01:00
if ( bMeshNetworkCheckMacEquality ( bTmpPacket . meshSenderAddr . addr , childrenAddr [ u16Index ] . addr ) = = false ) //exclude the sender node
2021-01-17 23:47:59 +01:00
{
2021-01-20 21:40:51 +01:00
ERROR_CHECK ( errMeshNetworkSendMeshPacket ( & childrenAddr [ u16Index ] , & meshPacket ) ) ; //send to child
2021-01-17 23:47:59 +01:00
}
}
vTaskDelay ( 200 / portTICK_PERIOD_MS ) ;
2021-01-16 18:23:10 +01:00
}
2021-01-20 20:55:33 +01:00
}