### Introduction to ESP32 The ESP32 is a series of low-cost, low-power microcontrollers with integrated Wi-Fi and dual-mode Bluetooth. Developed by Espressif Systems, it is ideal for IoT applications and embedded projects due to its versatility and connectivity capabilities. ### Key Features - **CPU:** Xtensa LX6 32-bit dual-core or single-core, up to 240 MHz. - **Memory:** 520 KB SRAM, 448 KB ROM. - **Flash:** Integrated 4MB to 16MB (SPI Flash). - **Wireless Connectivity:** - Wi-Fi 802.11 b/g/n (2.4 GHz). - Bluetooth v4.2 BR/EDR and Bluetooth LE (Low Energy). - **Peripherals:** - 34x programmable GPIO pins. - 12-bit ADC (up to 18 channels). - 2x 8-bit DAC. - 10x capacitive touch sensors. - 4x SPI, 2x I2S, 2x I2C, 3x UART. - SD/eMMC/SDIO Host, SDIO Slave. - Ethernet MAC. - CAN 2.0 Controller. - Timers (Timer Group, RTC Timer, Watchdog). - PWM (LED PWM Controller). - **Security:** Hardware acceleration for AES, SHA, RSA, ECC, RNG. Encrypted Flash, Secure Boot. - **Low Power Modes:** Multiple power-saving modes. ### GPIO Pins and Functions The ESP32 has a total of 34 GPIO pins, many of which have multiple functions. | GPIO Pin | Common Function(s) | Notes | |----------|-------------------------------------------------------|--------------------------------------------------------------------| | GPIO0 | Boot button, Flash mode select, ADC2_CH9 | **Caution!** Pull LOW to enter flash mode. | | GPIO1 | TX0 (UART0 Transmit), ADC2_CH0 | Used for serial communication with PC. | | GPIO2 | Boot mode select, ADC2_CH2, Touch2, HSPIWP | **Caution!** Pull LOW on boot for flashing. | | GPIO3 | RX0 (UART0 Receive), ADC2_CH3 | Used for serial communication with PC. | | GPIO4 | ADC2_CH4, Touch0, HSPIHD | Useful for general input/output. | | GPIO5 | VSPI_SS0, HSPI_CS0, PWM, ADC2_CH5 | Useful as SPI CS, PWM. | | GPIO6-11 | Used for SPI Flash (not recommended for general use) | Connected to internal SPI Flash. | | GPIO12 | MTDI, HSPI_MISO, ADC2_CH5, Touch5 | **Caution!** Pull LOW on boot can cause issues. | | GPIO13 | MTCK, HSPI_MOSI, ADC2_CH4, Touch4 | | | GPIO14 | MTMS, HSPI_CLK, ADC2_CH6, Touch6 | | | GPIO15 | MTDO, HSPI_CS0, ADC2_CH7, Touch7 | | | GPIO16 | RX2 (UART2 Receive), I2S_IN_DATA | | | GPIO17 | TX2 (UART2 Transmit), I2S_OUT_DATA | | | GPIO18 | VSPI_CLK | | | GPIO19 | VSPI_MISO | | | GPIO21 | SDA (I2C Data) | Commonly used for I2C. | | GPIO22 | SCL (I2C Clock) | Commonly used for I2C. | | GPIO23 | VSPI_MOSI | | | GPIO25 | DAC1, ADC2_CH8 | | | GPIO26 | DAC2, ADC2_CH9 | | | GPIO27 | ADC2_CH7, Touch7 | | | GPIO32 | ADC1_CH4, Touch9 | | | GPIO33 | ADC1_CH5, Touch8 | | | GPIO34 | ADC1_CH6 | Input only. | | GPIO35 | ADC1_CH7 | Input only. | | GPIO36 | SENSOR_VP, ADC1_CH0 | Input only. | | GPIO39 | SENSOR_VN, ADC1_CH3 | Input only. | **Note on ADC:** - **ADC1:** Can be used when Wi-Fi is in use. - **ADC2:** Cannot be used when Wi-Fi is in use. **Pins with internal pull-up/pull-down resistors:** - Most GPIO pins have software-configurable pull-up/pull-down resistors. - Some pins have fixed internal pull-up/pull-down resistors (e.g., GPIO0, GPIO2, GPIO12, GPIO15). ### General Architecture The ESP32 integrates a microcontroller (MCU), Wi-Fi, and Bluetooth connectivity on a single chip. - **CPU:** Two 32-bit Xtensa LX6 cores (or one, depending on the model), which can operate independently or cooperatively. - **Core 0 (PRO_CPU):** Executes most application tasks. - **Core 1 (APP_CPU):** Can be used for background tasks, such as the Wi-Fi and Bluetooth stack, or for user application tasks. - **Memory:** - **SRAM:** 520 KB on-chip SRAM for data and code. - **ROM:** 448 KB ROM for boot-up and basic functions. - **External SPI Flash:** Connected via a high-speed SPI controller. - **Memory Controller:** Manages access to external SPI Flash and SRAM. - **RTC (Real-Time Clock):** Keeps time, even in low-power modes, and manages wake-up functions. - **Peripherals:** Various modules for interacting with the outside world (ADC, DAC, UART, SPI, I2C, etc.). - **Radio Modules:** Wi-Fi and Bluetooth, with their own MAC and baseband. - **Memory Management Unit (MMU):** Allows mapping external Flash into the CPU's address space to execute code directly from there. ### Power Management The ESP32 offers several power-saving modes to optimize consumption. - **Active Mode:** CPU and radios fully operational. - **Modem-sleep Mode:** CPU active, Wi-Fi/Bluetooth radios disabled. - **Light-sleep Mode:** CPU suspended, RTC and RTC peripherals active, memory retained. - **Deep Sleep Mode:** CPU powered off, most SRAM powered off. Only RTC and its memory (RTC_SRAM) active. Wake up by RTC timer or specific GPIO pins. - **Hibernation Mode:** The lowest power consumption mode. RTC oscillator off, only a slow boot-up timer and some RTC GPIOs active. ### Development Platforms - **ESP-IDF (Espressif IoT Development Framework):** Espressif's official SDK. Based on FreeRTOS, it offers full control over the hardware. - **Arduino IDE:** Allows programming the ESP32 using the familiar Arduino environment, with many libraries available. - **MicroPython:** Optimized Python 3 implementation for microcontrollers, including the ESP32. - **PlatformIO:** A cross-platform development environment and command-line tool that supports ESP32 with ESP-IDF, Arduino, etc. ### Basic Programming (Arduino IDE) #### 1. IDE Setup - Install "ESP32 by Espressif Systems" in the Boards Manager. - Select the correct board (e.g., "ESP32 Dev Module"). #### 2. Example: Blink LED ```cpp // Define the LED pin (usually integrated on the board) const int ledPin = 2; // GPIO2 is common for integrated LEDs void setup() { // Initialize the pin as an output pinMode(ledPin, OUTPUT); Serial.begin(115200); // Initialize serial communication } void loop() { Serial.println("LED ON"); digitalWrite(ledPin, HIGH); // Turn the LED on delay(1000); // Wait for 1 second Serial.println("LED OFF"); digitalWrite(ledPin, LOW); // Turn the LED off delay(1000); // Wait for 1 second } ``` #### 3. Example: Wi-Fi Connection ```cpp #include const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi Connected!"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); } void loop() { // Your application code here } ``` ### Advanced Topics - **FreeRTOS:** The ESP32 uses FreeRTOS for task management, allowing concurrent (multitasking) programming. - **Inter-Core Communication:** Using FreeRTOS Queues or Semaphores for communication between the two CPU cores. - **OTA (Over-The-Air) Updates:** Updating the ESP32 firmware wirelessly via Wi-Fi. - **Hardware Cryptography:** Utilizing hardware accelerators for encryption/decryption (AES, SHA, RSA). - **Specific Peripheral Usage:** Configuration and use of I2S for audio, Ethernet, CAN. - **Power Optimization:** Implementing advanced Deep Sleep strategies and wake-up by specific events. - **Controlling an External LED with a Mobile Phone (HTTP Server):** To control an external LED connected to the ESP32 using a mobile phone, a simple web server can be implemented on the ESP32. #### 1. Hardware Connection: - Connect the anode (long leg) of an LED to an ESP32 GPIO pin (e.g., GPIO13). - Connect the cathode (short leg) of the LED to a 220-330 ohm resistor. - Connect the other end of the resistor to GND (ground) of the ESP32. #### 2. Code (Arduino IDE): This example creates a Wi-Fi Access Point (AP) with the ESP32, and then a web server that responds to HTTP requests to turn the LED on or off. ```cpp #include #include // ESP32 Access Point (AP) Configuration const char* ssid = "ESP32_LED_Control"; const char* password = "your_password"; // Minimum 8 characters // LED Pin const int ledPin = 13; // We will use GPIO13 // WebServer object on port 80 WebServer server(80); void handleRoot() { // Simple HTML page to control the LED String html = " ESP32 LED Control "; html += " "; html += " "; html += " ESP32 LED Control "; html += " LED Status: "; html += (digitalRead(ledPin) == HIGH) ? "ON" : "OFF"; html += " "; html += " TURN ON "; html += " TURN OFF "; html += " "; server.send(200, "text/html", html); } void handleLedOn() { digitalWrite(ledPin, HIGH); server.sendHeader("Location", "/"); // Redirect to the main page server.send(303); // See Other } void handleLedOff() { digitalWrite(ledPin, LOW); server.sendHeader("Location", "/"); // Redirect to the main page server.send(303); // See Other } void handleNotFound() { String message = "File Not Found\n\n"; message += "URI: "; message += server.uri(); message += "\nMethod: "; message += (server.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += server.args(); server.send(404, "text/plain", message); } void setup() { Serial.begin(115200); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); // Ensure LED is off at startup Serial.print("Setting up AP mode... "); WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); // Configure web server routes server.on("/", handleRoot); server.on("/on", handleLedOn); server.on("/off", handleLedOff); server.onNotFound(handleNotFound); server.begin(); Serial.println("HTTP server started"); } void loop() { server.handleClient(); // Process client requests } ``` #### 3. Steps to Use: 1. **Connect the LED:** Ensure the LED is connected to GPIO13 with a current-limiting resistor to GND. 2. **Upload the Code:** Compile and upload the code to the ESP32 using the Arduino IDE. 3. **Connect Mobile Phone:** On your mobile phone, search for Wi-Fi networks and connect to the network named `ESP32_LED_Control` (or your configured SSID) using the password `your_password`. 4. **Open Browser:** Open a web browser on your phone and navigate to the ESP32's IP address (usually `192.168.4.1`). 5. **Control the LED:** You will see a simple web page with "TURN ON" and "TURN OFF" buttons for the LED. Clicking them will toggle the LED's state. #### Detailed Explanation: - **`WiFi.softAP(ssid, password);`**: The ESP32 is configured as a Wi-Fi Access Point (AP), creating its own network. Your phone will connect to this network. - **`WebServer server(80);`**: A web server is initialized to listen for requests on port 80 (the standard HTTP port). - **`server.on("/", handleRoot);`**: When a browser accesses the root IP address (e.g., `192.168.4.1/`), the `handleRoot()` function is called. This function generates an HTML page with the control buttons. - **`server.on("/on", handleLedOn);`** and **`server.on("/off", handleLedOff);`**: When the buttons on the web page are clicked, the browser sends a request to `/on` or `/off`. These functions call `digitalWrite()` to change the LED's state and then redirect the user back to the main page to update the displayed status. - **`server.handleClient();`**: In the `loop()`, this function is crucial. It continuously listens for incoming client requests (your phone, in this case) and directs them to the appropriate `handle` function. - **Controlling an External LED Remotely with Blynk.App:** Blynk is a platform with iOS and Android apps to control Arduino, Raspberry Pi, ESP8266, and ESP32 over the Internet. It's a convenient way to build IoT projects without deep web development knowledge. #### 1. Blynk Setup: - **Download the Blynk App:** Install "Blynk IoT" from your mobile app store (Google Play or Apple App Store). - **Create a New Project:** Open the app, create a new account (if you don't have one), and then create a "New Project." - **Choose Device:** Select "ESP32" as your device. - **Connection Type:** Choose "Wi-Fi." - **Auth Token:** An "Auth Token" will be sent to your email. This token is crucial for your ESP32 code to connect to your Blynk project. Keep it safe! - **Add a Widget:** Tap on the screen to open the Widget Box. Add a "Button" widget. - **Button Settings:** - Assign it to a Virtual Pin (e.g., `V1`). Virtual pins allow you to send data to and from your hardware without directly assigning to specific GPIOs, giving more flexibility. - Set "Mode" to "SWITCH" (so it stays ON/OFF). - You can label it "LED Control" or similar. #### 2. Hardware Connection: - Connect the LED as described in the HTTP Server section: LED anode to an ESP32 GPIO pin (e.g., GPIO13), cathode to a 220-330 ohm resistor, and the other end of the resistor to GND. #### 3. Code (Arduino IDE): You'll need to install the Blynk library in your Arduino IDE (`Sketch > Include Library > Manage Libraries...` and search for "Blynk"). ```cpp #define BLYNK_TEMPLATE_ID "YOUR_BLYNK_TEMPLATE_ID" #define BLYNK_DEVICE_NAME "YOUR_BLYNK_DEVICE_NAME" #define BLYNK_AUTH_TOKEN "YOUR_BLYNK_AUTH_TOKEN" #include #include #include // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "YOUR_WIFI_SSID"; char pass[] = "YOUR_WIFI_PASSWORD"; // LED Pin const int ledPin = 13; // We will use GPIO13 // This function will be called every time the Virtual Pin V1 state changes BLYNK_WRITE(V1) { int pinValue = param.asInt(); // Get value as integer (0 or 1) if (pinValue == 1) { digitalWrite(ledPin, HIGH); Serial.println("LED ON"); } else { digitalWrite(ledPin, LOW); Serial.println("LED OFF"); } } void setup() { Serial.begin(115200); pinMode(ledPin, OUTPUT); digitalWrite(ledPin, LOW); // Ensure LED is off at startup // Initialize Blynk connection Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); } void loop() { Blynk.run(); // This handles all the Blynk communication } ``` #### 4. Steps to Use: 1. **Update Code:** Replace `YOUR_BLYNK_TEMPLATE_ID`, `YOUR_BLYNK_DEVICE_NAME`, `YOUR_BLYNK_AUTH_TOKEN` (from your email), `YOUR_WIFI_SSID`, and `YOUR_WIFI_PASSWORD` with your actual credentials. 2. **Connect the LED:** As described above, LED anode to GPIO13, cathode to resistor, resistor to GND. 3. **Upload the Code:** Compile and upload the code to your ESP32. 4. **Run Blynk App:** Open the Blynk app on your phone and press the "Play" button (triangle icon) in the top right corner of your project screen. 5. **Control the LED:** Use the button widget you added to turn the LED on and off. The ESP32 will connect to your home Wi-Fi, then to the Blynk server, and receive commands from your phone app. #### Detailed Explanation: - **`#define BLYNK_AUTH_TOKEN ...`**: This is your unique token that identifies your device to the Blynk server. - **`#include