#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif
BluetoothSerialSerialBT;
voidsetup(){
Serial.begin(115200);
SerialBT.begin(device_name);//Bluetooth device name
uint8_tmac_arr[6];// Byte array to hold the MAC address from getBtAddress()
BTAddressmac_obj;// Object holding instance of BTAddress with the MAC (for more details see libraries/BluetoothSerial/src/BTAddress.h)
Stringmac_str;// String holding the text version of MAC in format AA:BB:CC:DD:EE:FF
SerialBT.getBtAddress(mac_arr);// Fill in the array
mac_obj=SerialBT.getBtAddressObject();// Instantiate the object
mac_str=SerialBT.getBtAddressString();// Copy the string
Serial.print("This device is instantiated with name ");Serial.println(device_name);
Serial.print("The mac address using byte array: ");
for(inti=0;i<ESP_BD_ADDR_LEN-1;i++){
Serial.print(mac_arr[i],HEX);Serial.print(":");
}
Serial.println(mac_arr[ESP_BD_ADDR_LEN-1],HEX);
Serial.print("The mac address using BTAddress object using default method `toString()`: ");Serial.println(mac_obj.toString().c_str());
Serial.print("The mac address using BTAddress object using method `toString(true)`\n\twhich prints the MAC with capital letters: ");Serial.println(mac_obj.toString(true).c_str());// This actually what is used inside the getBtAddressString()
Serial.print("The mac address using string: ");Serial.println(mac_str.c_str());
This example will blink the built-in LED and read analog data.
Additionally, this example demonstrates the usage of the task handle, simply by deleting the analog
read task after 10 seconds from the main loop by calling the function `vTaskDelete`.
### Theory:
A task is simply a function that runs when the operating system (FreeeRTOS) sees fit.
This task can have an infinite loop inside if you want to do some work periodically for the entirety of the program run.
This, however, can create a problem - no other task will ever run and also the Watch Dog will trigger and your program will restart.
A nice behaving tasks know when it is useless to keep the processor for itself and give it away for other tasks to be used.
This can be achieved in many ways, but the simplest is called `delay(`milliseconds)`.
During that delay, any other task may run and do its job.
When the delay runs out the Operating System gives the processor the task which can continue.
For other ways to yield the CPU in a task please see other examples in this folder.
It is also worth mentioning that two or more tasks running the same function will run them with separate stacks, so if you want to run the same code (which could be differentiated by the argument) there is no need to have multiple copies of the same function.
**Task creation has a few parameters you should understand:**
```
xTaskCreate(TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
```
- **pxTaskCode** is the name of your function which will run as a task
- **pcName** is a string of human-readable descriptions for your task
- **usStackDepth** is the number of words (word = 4B) available to the task. If you see an error similar to this "Debug exception reason: Stack canary watchpoint triggered (Task Blink)" you should increase it
- **pvParameters** is a parameter that will be passed to the task function - it must be explicitly converted to (void*) and in your function explicitly converted back to the intended data type.
- **uxPriority** is a number from 0 to configMAX_PRIORITIES which determines how the FreeRTOS will allow the tasks to run. 0 is the lowest priority.
- **pxCreatedTask** task handle is a pointer to the task which allows you to manipulate the task - delete it, suspend and resume.
If you don't need to do anything special with your task, simply pass NULL for this parameter.
You can read more about task control here: https://www.freertos.org/a00112.html
# Supported Targets
This example supports all SoCs.
### Hardware Connection
If your board does not have a built-in LED, please connect one to the pin specified by the `LED_BUILTIN` in the code (you can also change the number and connect it to the pin you desire).
Optionally you can connect the analog element to the pin. such as a variable resistor, analog input such as an audio signal, or any signal generator. However, if the pin is left unconnected it will receive background noise and you will also see a change in the signal when the pin is touched by a finger.
Please refer to the ESP-IDF ADC documentation for specific SoC for info on which pins are available:
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file.
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source***
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)
This example demonstrates the basic usage of FreeRTOS Mutually Exclusive Locks (Mutex) for securing access to shared resources in multi-threading.
Please refer to other examples in this folder to better understand the usage of tasks.
It is also advised to read the documentation on FreeRTOS web pages:
https://www.freertos.org/a00106.html
This example creates 2 tasks with the same implementation - they write into a shared variable and then read it and check if it is the same as what they have written.
In single-thread programming like on Arduino this is of no concern and will be always ok, however when multi-threading is used the execution of the task is switched by the FreeRTOS and the value can be rewritten from another task before reading again.
The tasks print write and read operation - each in their column for better reading. Task 0 is on the left and Task 1 is on the right.
Watch the writes and read in secure mode when using the mutex (default) as the results are as you would expect them.
Then try to comment the USE_MUTEX and watch again - there will be a lot of mismatches!
### Theory:
Mutex is a specialized version of Semaphore (please see the Semaphore example for more info).
In essence, the mutex is a variable whose value determines if the mute is taken (locked) or given (unlocked).
When two or more processes access the same resource (variable, peripheral, etc) it might happen, for example, that when one task starts to read a variable and the operating system (FreeRTOS) will schedule the execution of another task
which will write to this variable and when the previous task runs again it will read something different.
Mutexes and binary semaphores are very similar but have some subtle differences:
Mutexes include a priority inheritance mechanism, whereas binary semaphores do not.
This makes binary semaphores the better choice for implementing synchronization (between tasks or between tasks and an interrupt), and mutexes the better
choice for implementing simple mutual exclusion.
What is priority inheritance?
If a low-priority task holds the Mutex but gets interrupted by a Higher priority task, which
then tries to take the Mutex, the low-priority task will temporarily ‘inherit’ the high priority so a middle-priority task can't block the low-priority task, and thus also block the high priority task.
Semaphores don't have the logic to handle this, in part because Semaphores aren't 'owned' by the task that takes them.
A mutex can also be recursive - if a task that holds the mutex takes it again, it will succeed, and the mutex will be released
for other tasks only when it is given the same number of times that it was taken.
You can check the danger by commenting on the definition of USE_MUTEX which will disable the mutex and present the danger of concurrent access.
# Supported Targets
This example supports all ESP32 SoCs.
## How to Use Example
Flash and observe the serial output.
Comment the `USE_MUTEX` definition, save and flash again and observe the behavior of unprotected access to the shared variable.
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
#### Using Arduino IDE
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file.
## Example Log Output
The expected output of shared variables protected by mutex demonstrates mutually exclusive access from tasks - they do not interrupt each other and do not rewrite the value before the other task has read it back.
```
Task 0 | Task 1
| Starting
| 0 <- 227
Starting |
| R: 227
227 <- 737 |
R: 737 |
| 737 <- 282
| R: 282
282 <- 267 |
```
The output of unprotected access to shared variable - it happens often that a task is interrupted after writing and before reading the other task write a different value - a corruption occurred!
```
Task 0 | Task 1
| Starting
| 0 <- 333
Starting |
333 <- 620 |
R: 620 |
620 <- 244 |
| R: 244
| Mismatch!
| 244 <- 131
R: 131 |
Mismatch! |
131 <- 584 |
| R: 584
| Mismatch!
| 584 <- 134
| R: 134
| 134 <- 554
R: 554 |
Mismatch! |
554 <- 313 |
```
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source***
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)
Serial.println("Queue could not be created. Halt.");
while(1)delay(1000);// Halt at this point as is not possible to continue
}
// Set up two tasks to run independently.
xTaskCreate(
TaskWriteToSerial
,"Task Write To Serial"// A name just for humans
,2048// The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
,NULL// No parameter is used
,2// Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
,NULL// Task handle is not used here
);
xTaskCreate(
TaskReadFromSerial
,"Task Read From Serial"
,2048// Stack size
,NULL// No parameter is used
,1// Priority
,NULL// Task handle is not used here
);
// Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
Serial.printf("\nAnything you write will return as echo.\nMaximum line length is %d characters (+ terminating '0').\nAnything longer will be sent as a separate line.\n\n",MAX_LINE_LENGTH-1);
}
voidloop(){
// Loop is free to do any other work
delay(1000);// While not being used yield the CPU to other tasks
This example reads data received on the serial port (sent by the user) pass it via queue to another task which will send it back on Serial Output.
### Theory:
A queue is a simple-to-use data structure (in the most basic way) controlled by `xQueueSend` and `xQueueReceive` functions.
Usually, one task writes into the queue and the other task reads from it.
Usage of queues enables the reading task to yield the CPU until there are data in the queue and therefore not waste precious computation time.
# Supported Targets
This example supports all ESP32 SoCs.
## How to Use Example
Flash and write anything to serial input.
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
#### Using Arduino IDE
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file.
## Example Log Output
```
Anything you write will return as echo.
Maximum line length is 63 characters (+ terminating '0').
Anything longer will be sent as a separate line.
```
< Input text "Short input"
``Echo line of size 11: "Short input"``
< Input text "An example of very long input which is longer than default 63 characters will be split."
```
Echo line of size 63: "An example of very long input which is longer than default 63 c"
Echo line of size 24: "haracters will be split."
```
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source***
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)
Semaphore is in essence a variable. Tasks can set the value, wait until one or more
semaphores are set and thus communicate between each other their state.
A binary semaphore is a semaphore that has a maximum count of 1, hence the 'binary' name.
A task can only 'take' the semaphore if it is available, and the semaphore is only available if its count is 1.
Semaphores can be controlled by any number of tasks. If you use semaphore as a one-way
signalization with only one task giving and only one task taking there is a much faster option
called Task Notifications - please see FreeRTOS documentation and read more about them: [https://www.freertos.org/RTOS-task-notifications.html](https://www.freertos.org/RTOS-task-notifications.html)
This example uses a semaphore to signal when a package is delivered to a warehouse by multiple
delivery trucks, and multiple workers are waiting to receive the package.
# Supported Targets
This example supports all ESP32 SoCs.
## How to Use Example
Read the code and try to understand it, then flash and observe the Serial output.
* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide).
#### Using Arduino IDE
To get more information about the Espressif boards see [Espressif Development Kits](https://www.espressif.com/en/products/devkits).
* Before Compile/Verify, select the correct board: `Tools -> Board`.
* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port.
#### Using Platform IO
* Select the COM port: `Devices` or set the `upload_port` option on the `platformio.ini` file.
## Example Log Output
```
Anything you write will return as echo.
Maximum line length is 63 characters (+ terminating '0').
Anything longer will be sent as a separate line.
```
< Input text "Short input"
``Echo line of size 11: "Short input"``
< Input text "An example of very long input which is longer than default 63 characters will be split."
```
Echo line of size 63: "An example of very long input which is longer than default 63 c"
Echo line of size 24: "haracters will be split."
```
## Troubleshooting
***Important: Make sure you are using a good quality USB cable and that you have a reliable power source***
## Contribute
To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst)
If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome!
Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else.
## Resources
* Official ESP32 Forum: [Link](https://esp32.com)
* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)
* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf)
* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf)
* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf)
* ESP32-S3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s3_datasheet_en.pdf)
* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com)