Embedded Networking and Communications

Hero Image

Task: Embedded Networking and Communications

Group assignment:

  • Send a message between two projects.
  • Document your work to the group work page and reflect on your individual page what you learned

  • Individual project:

  • design, build and connect wired or wireless node(s) with network or bus addresses and a local input and/or output devices
  • Learning Experience

    During this assignment, I gained a valuable learning experience. I worked with all three types of communication – wired, WiFi and cloud. I learned how to transfer data between microcontrollers, how to use sensors like voltage and current sensors and how to connect my project to the internet using ThingSpeak. I also gained practical experience with tools like Arduino IDE, Serial Monitor and ESP32 boards. I was able to debug my code more efficiently and reduce errors. This helped me improve my understanding of communication protocols and increase my confidence in embedded system development. Along with this, I have also prepared half of the code for my final project which was a success for me.

    Key Accomplishments

    ✅ Completed tests and final code for wired communication.
    ✅ Successfully implemented data transfer using WiFi (ESP-NOW).
    ✅ Connected IoT devices to ThingSpeak cloud platform and visualized the data.
    ✅ Integrated voltage and current sensors into my communication setup.
    ✅ Completed 50% of my final project code.
    Individual Assignment:

    For this assignment, I have decided to start by learning how to use LCD/OLED displays, voltage sensors, and current sensors. I will explore both wired and wireless communication, including IoT methods. I will also learn how to calculate power (in watts) using voltage and current, which will help me in my final project.

    Embedded Networking and Communications

    Embedded networking uses protocols like Wi-Fi, Bluetooth, I2C, and UART to help small devices—such as sensors and smart gadgets—share data. It powers smart systems in homes, businesses, and the Internet of Things (IoT). These systems need both hardware and software knowledge and must work fast, safely, and with low power. Embedded networking enables real-time communication between devices, making our lives smarter and more convenient.

    Wire Communication

    In embedded systems, wired communication means transferring data between devices using physical wires. Common protocols include UART, I2C, and SPI.

  • UART (Universal Asynchronous Receiver/Transmitter) uses two wires — TX (Transmit) and RX (Receive) — to connect microcontrollers with computers or Bluetooth modules.
  • I2C (Inter-Integrated Circuit) uses two wires — SDA (Data) and SCL (Clock) — to connect multiple devices like sensors and displays. Each device has a unique address.
  • SPI (Serial Peripheral Interface) is faster and uses four wires — MOSI (Master Out Slave In), MISO (Master In Slave Out), SCK (Clock), and SS (Slave Select). It’s often used with high-speed devices like SD cards.


  • Protocol Speed Main Use Example
    USB (Universal Serial Bus) High Transferring data and charging devices Connecting Arduino to a computer using USB
    Ethernet (LAN) Very fast (up to 10 Gbps or more) Internet access and sharing data between computers Office computers connected to a router with Ethernet cables
    SPI (Serial Peripheral Interface) Very fast Connecting microcontrollers to sensors, displays, or SD cards Arduino connected to an OLED display using SPI
    I2C (Inter-Integrated Circuit) Moderate Connecting multiple devices using fewer wires Arduino connected to temperature and humidity sensors using I2C
    UART (Universal Asynchronous Receiver/Transmitter) Medium Communication with GPS, Bluetooth, or for debugging Arduino sending data to the serial monitor on a computer

    Reference website chatgpt
    Testing the Code for Sending Data

    To transfer data between two boards, we need two separate programs — one for the sender and one for the receiver. We demonstrated this in our group assignment. The codes for both boards are provided below.


    Testing Master Code

    
    #define TX_PIN 5  // GPIO5 for TX
    #define RX_PIN 4  // GPIO4 for RX
    
    void setup() {
        Serial.begin(115200);       // USB Serial for debugging
        Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // UART communication
    }
    
    void loop() {
        Serial1.println("Hello from Master!"); // Send test message
        Serial.println("Sent: Hello from Master!");
    
        delay(2000);
    }
      

    Testing Slave Code

    
    #define TX_PIN 5  // GPIO5 for TX
    #define RX_PIN 4  // GPIO4 for RX
    
    void setup() {
        Serial.begin(115200);       // USB Serial for debugging
        Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  // UART communication
    }
    
    void loop() {
        if (Serial1.available()) {
            String received = Serial1.readStringUntil('\n');
            Serial.print("Received: ");
            Serial.println(received);
        }
    }
      


    Pin connection is done TX to RX,RX to TX



    Verifying the Code


    Uploading the Code


    Data is being sent through Wire

    My testing code is working, and I have successfully transferred random data between the boards. Now, I can use input and output devices with this setup and send data from Board A to Board B.

    Testing the Voltage Sensor

    First, I tested the voltage sensor to understand how the code works. I connected the pins correctly and powered the voltage sensor using a power supply. After that, I confirmed that the sensor was working properly.

    I searched for the voltage sensor code online, configured the pin connections, verified the code, and then uploaded it to the board.

    The voltage value from the power supply started appearing on the Serial Monitor, but it wasn’t accurate. To improve accuracy, I used a voltage sensor, which worked well. Using this code, I was able to transfer voltage data through wired communication.


    Wired Communication with Xio ESP32-C3 using Voltage Sensor and LED

    For this assignment, I worked on wired communication using the Xio ESP32-C3 microcontroller. My goal was to send and receive signals between two boards through simple wired connections. I used a voltage sensor to read data on Board A and sent that data to Board B. The received voltage data was then displayed on an LCD,.

    Components Used:

    • 2x Xiao ESP32-C3 Boards
    • 1x Voltage Sensor
    • 1x LCD
    • Jumper Wires
    • Power Supply

    Connection Table:

    Component Pin on Component Pin on Xiao ESP32-C3 Description
    UART Connection TX (Board A) RX (Board B - D7) TX of Board A to RX of Board B
    UART Connection RX (Board A) TX (Board B - D6) RX of Board A to TX of Board B
    Voltage Sensor VCC 3.3V or 5V Power supply to voltage sensor
    Voltage Sensor GND GND Common ground
    Voltage Sensor OUT A2 Signal pin to analog input (A2)
    LCD (I2C Device) SDA D4 (SDA) I2C data line
    LCD (I2C Device) SCL D5 (SCL) I2C clock line
    LCD (I2C Device) VCC 3.3V Power to I2C device
    LCD (I2C Device) GND GND Common ground

    I connected two XIAO ESP32-C3 boards using UART communication. A voltage sensor is connected to analog pin A2, and an I2C LCD display is connected using the SDA and SCL pins, as shown in the connection table above.

    Then, I opened the master and slave code and integrated the voltage sensor and LCD display code into it.

    After uploading the updated code, the master began sending random data to the slave.

    The voltage data was successfully sent to the slave's Serial Monitor and LCD, and the data transmission started as expected.



    VoltageSensor Code
    
    #define SENSOR_PIN 4   // Define the ADC pin (use a safe GPIO)
    #define REF_VOLTAGE 3.3 // ESP32-C3 operates on 3.3V
    #define ADC_RESOLUTION 4095 // 12-bit ADC resolution (0-4095)
    
    float voltageDividerFactor = 4.3;  // Adjust based on the sensor calibration
    
    void setup() {
        Serial.begin(115200);
    }
    
    void loop() {
        int adcValue = analogRead(SENSOR_PIN);  // Read ADC value
        float voltage = (adcValue * REF_VOLTAGE) / ADC_RESOLUTION;  // Convert ADC to voltage
        float measuredVoltage = voltage * voltageDividerFactor; // Adjust based on sensor ratio
    
    
        Serial.print("Voltage: ");
        Serial.print(measuredVoltage);
        Serial.println("V");
    
        delay(500);  // Read every second
    }
    
    Master Code
      
    #define TX_PIN 21
    #define RX_PIN 20
    #define SENSOR_PIN 4   // Define the ADC pin (use a safe GPIO)
    #define REF_VOLTAGE 3.3 // ESP32-C3 operates on 3.3V
    #define ADC_RESOLUTION 4095 // 12-bit ADC resolution (0-4095)
    
    float voltageDividerFactor = 4.3;  // Adjust based on the sensor calibration
    
    void setup() {
        Serial.begin(115200);     
        Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); 
    
    
    }
    
    void loop() {
      int adcValue = analogRead(SENSOR_PIN);  // Read ADC value
      float voltage = (adcValue * REF_VOLTAGE) / ADC_RESOLUTION;  // Convert ADC to voltage
      float measuredVoltage = voltage * voltageDividerFactor; // Adjust based on sensor ratio
    
        Serial1.println(measuredVoltage); 
        Serial.print("Sent:measuredVoltage=");
        Serial.print(measuredVoltage);
       Serial.println("V");
        delay(1000);
    }
    
    Slave_Code
    
    #include Wire.h
    #include LiquidCrystal_I2C.h
    #define TX_PIN 21  
    #define RX_PIN 20  
    LiquidCrystal_I2C lcd(0x27, 16, 2);
    
    void setup() {
        Serial.begin(115200);       
        Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN);  
       lcd.begin();
        lcd.backlight();
    }
    
    void loop() {
        if (Serial1.available()) {
            String receivedData = Serial1.readStringUntil('\n'); 
            receivedData.trim();  
            Serial.print("Received: ");
            Serial.println(receivedData);
             lcd.setCursor(0, 0);
            lcd.print("measuredVoltage"); // Add spaces to clear previous text
            lcd.setCursor(0, 1);
            lcd.print(receivedData);
       }
        }
    
    Wireless Communication

    Devices can exchange data without physical wires by using radio waves. This allows for greater mobility, flexibility, and easier installation. Common wireless technologies include Wi-Fi, Bluetooth, Zigbee, and LoRa. Each technology has its own use based on data speed, battery usage, and range. While wireless systems are convenient, they may face challenges like security risks, limited range, and signal interference.




    Wireless Communication Technologies
    Technology Range Frequency Main Use Example
    Wi-Fi Up to 100 meters 2.4 GHz / 5 GHz Internet access, local networking Home/office wireless routers
    Bluetooth Up to 10 meters 2.4 GHz Short-range device connectivity Wireless earphones, smartwatches
    Zigbee 10–100 meters 2.4 GHz Home automation, smart meters Smart lighting, security systems
    LoRa Up to 15 kilometers 433 MHz / 868 MHz Long-range IoT communication Smart agriculture, smart cities
    NFC Up to 4 cm 13.56 MHz Contactless payments, identity verification Google Pay, metro cards
    Infrared (IR) Few meters (line-of-sight) 850–950 nm (IR spectrum) Short-range control signals TV remotes, AC remotes
    Cellular (3G/4G/5G) Nationwide (via cell towers) Varies (700 MHz to 2.6 GHz+) Mobile data, voice calls, IoT Smartphones, mobile broadband
    Satellite Communication Global (via orbiting satellites) Varies (GHz range) Remote connectivity, broadcasting GPS, satellite TV, weather reports
    Reference website chatgpt

    First, I found the MAC address of the device to connect it with another device and enable communication between them. I searched online for a suitable code to detect the MAC address. After implementing and testing the code, I successfully obtained the board's MAC address.


    MAC_Address_Code
    
      
    #include WiFi.h
    
    void setup() {
        Serial.begin(115200);
        delay(1000);
    
        WiFi.mode(WIFI_STA); // Set ESP32 to Station mode
        delay(100); // Small delay to ensure mode is set
    
        // Get MAC address
        Serial.print("ESP32-C3 MAC Address: ");
        Serial.println(WiFi.macAddress());
    }
    
    void loop() {
        // Do nothing
    }
      
      

    Once I found the MAC address, I searched for the transmitter and receiver codes on the internet and found them. Using these, I will be able to send and receive data between board A and board B


    Testing_transmiter_Code
    
    	
    	
    #include WiFi.h
    #include esp_now.h
    
    
    uint8_t receiverMAC[] = {0xD4, 0xF9, 0x8D, 0x04, 0x42, 0x64}; // Change to actual receiver MAC
    
    // Data structure to send
    typedef struct struct_message {
        int value;
    } struct_message;
    
    struct_message myData;
    
    // Callback when data is sent
    void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
        Serial.print("Send Status: ");
        Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
    }
    
    void setup() {
        Serial.begin(115200);
        WiFi.mode(WIFI_STA); // Set ESP32 to Station mode
    
        // Initialize ESP-NOW
        if (esp_now_init() != ESP_OK) {
            Serial.println("ESP-NOW Init Failed!");
            return;
        }
    
        esp_now_register_send_cb(onDataSent);
    
        // Register peer
        esp_now_peer_info_t peerInfo = {};
        memcpy(peerInfo.peer_addr, receiverMAC, 6);
        peerInfo.channel = 0;
        peerInfo.encrypt = false;
    
        if (esp_now_add_peer(&peerInfo) != ESP_OK) {
            Serial.println("Failed to add peer");
            return;
        }
    }
    
    void loop() {
        myData.value = random(1, 100);;
    
        // Send data
        esp_err_t result = esp_now_send(receiverMAC, (uint8_t *)&myData, sizeof(myData));
    
        if (result == ESP_OK) {
            Serial.println("Sent successfully");
        } else {
            Serial.println("Error sending data");
        }
    
        delay(2000); // Send every 2 seconds
    }
    	
    	
    	
    	
    
    Testing_reciver_Code
    
    	
    	
    #include WiFi.h
    #include esp_now.h
    
    
    uint8_t receiverMAC[] = {0xD4, 0xF9, 0x8D, 0x04, 0x42, 0x64}; // Change to actual receiver MAC
    
    // Data structure to send
    typedef struct struct_message {
        int value;
    } struct_message;
    
    struct_message myData;
    
    // Callback when data is sent
    void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
        Serial.print("Send Status: ");
        Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
    }
    
    void setup() {
        Serial.begin(115200);
        WiFi.mode(WIFI_STA); // Set ESP32 to Station mode
    
        // Initialize ESP-NOW
        if (esp_now_init() != ESP_OK) {
            Serial.println("ESP-NOW Init Failed!");
            return;
        }
    
        esp_now_register_send_cb(onDataSent);
    
        // Register peer
        esp_now_peer_info_t peerInfo = {};
        memcpy(peerInfo.peer_addr, receiverMAC, 6);
        peerInfo.channel = 0;
        peerInfo.encrypt = false;
    
        if (esp_now_add_peer(&peerInfo) != ESP_OK) {
            Serial.println("Failed to add peer");
            return;
        }
    }
    
    void loop() {
        myData.value = random(1, 100);;
    
        // Send data
        esp_err_t result = esp_now_send(receiverMAC, (uint8_t *)&myData, sizeof(myData));
    
        if (result == ESP_OK) {
            Serial.println("Sent successfully");
        } else {
            Serial.println("Error sending data");
        }
    
        delay(2000); // Send every 2 seconds
    }
    	
    	
    	
    


    I successfully verified and uploaded the code. Both devices are now able to send random data to each other. Now, I can also send my sensor data from one device to another.

    Testing the Current Sensor

    First, I tested the current sensor to verify whether it was measuring the current accurately or not.

    Current sensor testing setup

    I connected the sensor with a power supply and added a 3.3V LED to help visualize the current flow.

    Circuit pinout with LED

    I verified the code successfully:

    Code verification

    Then, I uploaded the code to the board:

    Code upload process

    Once the code was uploaded, the current readings began to appear on the Serial Monitor. Initially, the current sensor did not provide accurate readings. I made some modifications in the code, which significantly improved the accuracy of the measurements.

    Current_Code
    #define SENSOR_PIN 4   // ADC GPIO4
    #define SENSITIVITY 185  // 185mV/A for 5A module (Change for your module)
    #define ADC_RESOLUTION 4096  // 12-bit ADC (ESP32)
    #define V_REF 3300  // ESP32 ADC Reference Voltage (mV)
    
    const int numSamples = 100;  
    float zeroPoint;  
    
    void setup() {
        Serial.begin(115200);
        pinMode(SENSOR_PIN, INPUT);
        delay(2000);
    
        // Measure idle voltage (zero current)
        long sum = 0;
        for (int i = 0; i < numSamples; i++) {
            sum += analogReadMilliVolts(SENSOR_PIN);
            delay(10);
        }
        zeroPoint = sum / numSamples;
        Serial.print("Zero Point (No Current): ");
        Serial.print(zeroPoint);
        Serial.println(" mV");
    }
    
    float readACCurrent() {
        float sumSquared = 0;
    
        for (int i = 0; i < numSamples; i++) {
            float voltage = analogReadMilliVolts(SENSOR_PIN);  
            float current = (voltage - zeroPoint) / SENSITIVITY;  
            sumSquared += current * current;
            delay(1);
        }
    
        return sqrt(sumSquared / numSamples);  
    }
    
    void loop() {
        float acCurrent = readACCurrent();
        Serial.print("AC Current RMS: ");
        Serial.print(acCurrent, 3);
        Serial.println(" A");
        delay(1000);
    }
    	
    	
    
    Wireless Communication using Current Sensor and OLED with Xiao ESP32-C3

    For this assignment, I worked on wireless communication using the xiao ESP32-C3 microcontroller. My goal was to send current sensor data from one board to another using basic wireless communication. I also displayed the received data on an OLED screen and checked the response of the current sensor.

    Components Used:

    • 2x Xiao ESP32-C3 Boards
    • 1x Current Sensor (D2)
    • 1x OLED Display (SDA, SCL)
    • Power Supply (for Current Sensor)
    S.No Component Pin on Component (Board A) Pin on Xiao ESP32-C3 (Board A) Description
    1 Current Sensor VCC 3.3V or 5V Power supply to current sensor on Board A
    2 Current Sensor GND GND Common ground for Board A
    3 Current Sensor OUT A2 Signal pin from current sensor to analog input (A2) on Board A
    4 Wi-Fi Communication - - Wireless communication via Wi-Fi (sends current sensor data)

    S.No Component Pin on Component (Board B) Pin on Xiao ESP32-C3 (Board B) Description
    1 OLED Display (I2C) SDA D4 I2C data line for OLED on Board B
    2 OLED Display (I2C) SCL D5 I2C clock line for OLED on Board B
    3 OLED Display (I2C) VCC 3.3V Power to OLED on Board B
    4 OLED Display (I2C) GND GND Common ground for Board B
    5 Wi-Fi Communication - - Wireless communication via Wi-Fi (receives current sensor data)



    I connected two Xiao ESP32-C3 boards as per the provided connection table. The current sensor and OLED display were connected using the SDA and SCL pins. To test the system, a 3-watt LED was used. The current sensor was powered through the power supply.



    I included my current sensor and OLED code within the existing transmit and receive code. After adding the code, I verified and uploaded it to the board



    The current sensor data started transferring successfully to the other board, and the OLED indicated that the communication was working properly.





    To check the current sensor readings, I used a 3-watt LED to measure the current flowing through it. This setup is shown in the video. The data is successfully transmitted from one device to another, and the LED output also reflects the data transfer.


    Transmeter_Code
    
      
    #include WiFi.h
    #include esp_now.h
    
    
    #define SENSOR_PIN 4   // ADC GPIO4
    #define SENSITIVITY 185  // 185mV/A for 5A module (Change for your module)
    #define ADC_RESOLUTION 4096  // 12-bit ADC (ESP32)
    #define V_REF 3300  // ESP32 ADC Reference Voltage (mV)
    
    const int numSamples = 100;  
    float zeroPoint;  
    
    uint8_t receiverMAC[] = {0xD4, 0xF9, 0x8D, 0x04, 0x42, 0x64}; // Change to actual receiver MAC
    
    // Data structure to send
    typedef struct struct_message {
         float value;
    } struct_message;
    
    struct_message myData;
    
    // Callback when data is sent
    void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
        Serial.print("Send Status: ");
        Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
    }
    
    void setup() {
        Serial.begin(115200);
      pinMode(SENSOR_PIN, INPUT);
        delay(500);
    
        // Measure idle voltage (zero current)
        long sum = 0;
        for (int i = 0; i < numSamples; i++) {
            sum += analogReadMilliVolts(SENSOR_PIN);
            delay(10);
        }
        zeroPoint = sum / numSamples;
        Serial.print("Zero Point (No Current): ");
        Serial.print(zeroPoint);
        Serial.println(" mV");    
        WiFi.mode(WIFI_STA); // Set ESP32 to Station mode
    
        // Initialize ESP-NOW
        if (esp_now_init() != ESP_OK) {
            Serial.println("ESP-NOW Init Failed!");
            return;
        }
    
        esp_now_register_send_cb(onDataSent);
    
        // Register peer
        esp_now_peer_info_t peerInfo = {};
        memcpy(peerInfo.peer_addr, receiverMAC, 6);
        peerInfo.channel = 0;
        peerInfo.encrypt = false;
    
        if (esp_now_add_peer(&peerInfo) != ESP_OK) {
            Serial.println("Failed to add peer");
            return;
        }
    }
    
    float readACCurrent() {
        float sumSquared = 0;
    
        for (int i = 0; i < numSamples; i++) {
            float voltage = analogReadMilliVolts(SENSOR_PIN);  
            float current = (voltage - zeroPoint) / SENSITIVITY;  
            sumSquared += current * current;
            delay(1);
        }
    
        return sqrt(sumSquared / numSamples);  
    }
    
    void loop() {
        float acCurrent = readACCurrent();
        Serial.print("Current R
        MS: ");
        Serial.print(acCurrent, 3);
        Serial.println(" A");
        myData.value =acCurrent;
    
        // Send data
        esp_err_t result = esp_now_send(receiverMAC, (uint8_t *)&myData, sizeof(myData));
    
        if (result == ESP_OK) {
            Serial.println("Sent successfully");
        } else {
            Serial.println("Error sending data");
        }
    
        delay(200); // Send every 2 seconds
    }
    
      
      
    Reciver_Code
    
      
    #include WiFi.h
    #include esp_now.h
    #include Wire.h
    #include Adafruit_GFX.h
    #include Adafruit_SSD1306.h
    
    // OLED display width and height
    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 64
    
    // Create display object
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
    
    // Structure to receive data
    typedef struct struct_message {
         float value;
    } struct_message;
    
    struct_message myData;
    
    // New ESP-IDF v5.x compatible callback
    void onDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingData, int len) {
        memcpy(&myData, incomingData, sizeof(myData));
        Serial.print("Received Value: ");
        Serial.print(myData.value);
        Serial.println(" A");
       
    }
    
    void setup() {
        Serial.begin(115200);
     // Initialize OLED display
      if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 0x3C is the I2C address
        Serial.println(F("SSD1306 allocation failed"));
        while (1); // Halt execution
      }
    
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(SSD1306_WHITE);
        WiFi.mode(WIFI_STA); // Set ESP32 to Station mode
    
        // Initialize ESP-NOW
        if (esp_now_init() != ESP_OK) {
            Serial.println("ESP-NOW Init Failed!");
            return;
        }
    
        esp_now_register_recv_cb(onDataRecv); // Register new ESP-NOW receive callback
    }
    
    void loop() {
    display.clearDisplay();
      display.setCursor(0, 0);
      display.print("Pradeep");
        display.setCursor(0, 18);
      display.print("CurrentRMS");
          display.setCursor(10, 40);
      display.print(myData.value);
            display.setCursor(60, 40);
      display.print("A");
      display.display();
        // Do nothing, waiting for ESP-NOW messages
    }
    
      
      
    IoT Communication

    IoT communication refers to the exchange of data between smart devices that are connected to a local network or the internet. These devices send and receive data using different wired and wireless technologies such as Ethernet, Wi-Fi, Bluetooth, Zigbee, and LoRa.
    IoT connectivity enables automation, remote monitoring, and control in various fields like industrial systems, smart homes, healthcare, and agriculture. It focuses on scalability, real-time data transfer, and low power usage. However, challenges like device compatibility, data security, and network congestion can arise.




    Types of IoT Communication Models
    Type Medium/Technology Key Features Common Use Cases
    Device-to-Device (D2D) Bluetooth, Zigbee, Wi-Fi Direct Direct local communication, low latency, energy-efficient Smart lighting, motion-based automation
    Device-to-Gateway Wi-Fi Router, Mobile Phone, Smart Hub Local filtering, protocol translation, enhanced security Smart homes, industrial monitoring
    Device-to-Cloud Wi-Fi, Cellular (4G/5G), NB-IoT, LPWAN Remote access, real-time data processing, high scalability GPS tracking, remote health monitoring
    Gateway-to-Cloud Ethernet, Wi-Fi, Cellular Aggregated data transmission, local decision-making Smart agriculture, industrial IoT, smart cities
    Back-End Communication Cloud APIs, Analytics Platforms Big data processing, visualization, ML integration Alerts, insights, dashboards, system integration

    About the ThingSpeak

    ThingSpeak is an IoT analytics platform that allows you to collect, visualize, and analyze live data online. You can send data from devices like the ESP32 to the cloud, see real-time graphs, and get alerts.
    To enable cloud communication, I used the ThingSpeak platform.
    I created an account on ThingSpeak. The account details are shown in the table below.
    I also generated a Write API Key – this key is important because it helps send data from the microcontroller to the cloud securely.
    This key is used to identify your channel and to upload data to ThingSpeak.

    Open the official website of ThingsGive. Create a new account and fill in your account details. Then verify your email via the link received.
    Click “Add Channel” to create a new channel in your dashboard. Fill in the Name, Description, and Fields for your channel.
    Save the channel after filling in all required details. Go to the Private View tab of your channel to access the dashboard.
    Click on the API section and copy the API Key for use in your project.

    Testing-IOT_Code
    
      #include WiFi.h
    #include HTTPClient.h
    
    // Replace with your WiFi credentials
    const char* ssid = "FABLAB";
    const char* password = "12345678";
    
    // Replace with your ThingSpeak Write API Key
    const char* apiKey = "15DBNHTNHL25YMYN";
    
    // ThingSpeak API URL
    const char* server = "http://api.thingspeak.com/update";
    
    void setup() {
        Serial.begin(115200);
        WiFi.begin(ssid, password);
        
        Serial.print("Connecting to WiFi...");
        while (WiFi.status() != WL_CONNECTED) {
            Serial.print(".");
            delay(1000);
        }
        Serial.println("\nConnected to WiFi!");
    }
    
    void loop() {
        if (WiFi.status() == WL_CONNECTED) {
            HTTPClient http;
            
            // Generate random values
            int value1 = random(20, 40);  // Example: Temperature
            int value2 = random(30, 60);  // Example: Humidity
            int value3 = random(100, 500); // Example: Light Intensity
    
            // Construct the request URL
            String url = String(server) + "?api_key=" + apiKey + 
                         "&field1=" + String(value1) + 
                         "&field2=" + String(value2) + 
                         "&field3=" + String(value3);
    
            Serial.println("Sending data to ThingSpeak...");
            Serial.println(url);
    
            // Send data to ThingSpeak
            http.begin(url);
            int httpCode = http.GET();
            
            if (httpCode > 0) {
                Serial.println("Data sent successfully!");
            } else {
                Serial.println("Failed to send data.");
            }
            
            http.end();
        } else {
            Serial.println("WiFi Disconnected!");
        }
    
        delay(15000); // ThingSpeak allows updates every 15 seconds
    }
    



    I am ready for the sending data on the cloud

    Verified the code successfully in Arduino IDE.



    Entered the API Key, SSID, and Password in the code before uploading.



    Board successfully connected to the internet and cloud server.


    IoT Communication using Voltage Sensor + Current Sensor and OLED with Xiao ESP32-C3

    "For my IoT communication project, I plan to combine both the voltage and current sensors to create a formula that will calculate the power. This will help me determine the power rating of both the system and the OLED, as well as measure how much power is being generated. I also want to display this data on my IoT cloud platform, where I can visualize it through graphs."

    Components Used:

  • Voltage Sensor
  • Current Sensor
  • Power Supply
  • Xiao ESP32-C3 Board
  • OLED Display
  • Connection
    S.No Component Pin on Component (Board A) Pin on Xiao ESP32-C3 (Board A) Description
    1 Voltage Sensor VCC 3.3V or 5V Power supply for voltage sensor
    2 Voltage Sensor GND GND Common ground for Board A
    3 Voltage Sensor OUT A2 Signal pin from voltage sensor to A2
    4 Current Sensor VCC 3.3V or 5V Power supply for current sensor
    5 Current Sensor GND GND Common ground for Board A
    6 Current Sensor OUT A0 Signal pin from current sensor to A0
    7 Power Supply - + (Power) and - (Ground) Power supply for both sensors

    S.No Component Pin on Component (Board B) Pin on Xiao ESP32-C3 (Board B) Description
    1 OLED Display (I2C) SDA D4 I2C data line for OLED
    2 OLED Display (I2C) SCL D5 I2C clock line for OLED
    3 OLED Display (I2C) VCC 3.3V Power supply for OLED
    4 OLED Display (I2C) GND GND Common ground for Board B

    I created this code to monitor power generation by connecting both current and voltage sensors. This allowed me to display voltage, current, and power values on my dashboard to track energy consumption. Similarly, I used another code in which I included my Wi-Fi SSID, password, and API key to enable wireless data transmission to the cloud. With this setup, I can also view the main voltage, current, and power directly on the OLED display connected to the device

    "According to the table, I have properly fixed the connections for both my boards. To run the project, I included the API key generated by ThingSpeak in my code."

    Code Verification and Upload:

    Figure 1: Code successfully verified and uploaded to the board

    After writing and verifying the code, I uploaded it to the ESP32-C3 board. The compilation was successful, and the code was uploaded without any errors.

    Wi-Fi Connection Established:

    Figure 2: Device connecting to Wi-Fi as shown in the Serial Monitor

    The Serial Monitor showed that the device was successfully connecting to my Wi-Fi network using the SSID and password provided in the code.

    Cloud Connection:

    Figure 3: Device successfully connected to the cloud platform

    Along with the Wi-Fi connection, the device also connected to the cloud platform using the API key, confirming that the cloud communication setup was working properly.

    Data Transmission Success:

    Figure 4: Real-time data monitoring and successful communication

    The code was successfully transmitting data such as voltage, current, and power values, which were visible both on the OLED display and on the cloud dashboard.


    Data is also going in the cloud dashboard.


    Data is also going in the cloud dashboard.


    ThingSpeak – Cloud Communication


    IOT_Code
      
    #include WiFi.h
    #include HTTPClient.h
    #include Wire.h
    #include Adafruit_GFX.h
    #include Adafruit_SSD1306.h
    
    // OLED display width and height
    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 64
    
    // Create display object
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
    #define VOLTAGE_SENSOR_PIN A2   // ADC pin for voltage sensor
    #define CURRENT_SENSOR_PIN A0  // ADC pin for ACS712 current sensor
    
    #define REF_VOLTAGE 3.3  // ESP32-C3 operates on 3.3V
    #define ADC_RESOLUTION 4095  // 12-bit ADC (0-4095)
    
    #define SENSITIVITY 185  // Set this based on your ACS712 module: (5A = 185mV/A, 20A = 100mV/A, 30A = 66mV/A)
    #define VOLTAGE_DIVIDER_FACTOR 4.3  // Adjust based on calibration
    
    const int numSamples = 200;  
    float zeroPoint = 0;  
    
    // Replace with your WiFi credentials
    const char* ssid = "FABLAB";
    const char* password = "12345678";
    
    // Replace with your ThingSpeak Write API Key
    const char* apiKey = "9HO2SSQ4PUUDVWAY";
    
    // ThingSpeak API URL
    const char* server = "http://api.thingspeak.com/update";
    
    void setup() {
    Serial.begin(115200);
    if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 0x3C is the I2C address
    Serial.println(F("SSD1306 allocation failed"));
    while (1); // Halt execution
    }
    
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(SSD1306_WHITE);
    pinMode(VOLTAGE_SENSOR_PIN, INPUT);
    pinMode(CURRENT_SENSOR_PIN, INPUT);
    delay(500);
    
    // Calibrate Zero Point (Idle Voltage when NO Load)
    long sum = 0;
    for (int i = 0; i < numSamples; i++) {
    sum += analogReadMilliVolts(CURRENT_SENSOR_PIN);
    delay(5);
    }
    zeroPoint = sum / numSamples;
    Serial.print("Zero Point (No Load): ");
    Serial.print(zeroPoint);
    Serial.println(" mV");
    
    
    WiFi.begin(ssid, password);
    
    Serial.print("Connecting to WiFi...");
    while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
    }
    Serial.println("\nConnected to WiFi!");
    }
    // Function to measure AC Current RMS correctly
    float readACCurrent() {
    float sumSquared = 0;
    for (int i = 0; i < numSamples; i++) {
    float voltage = analogReadMilliVolts(CURRENT_SENSOR_PIN);  
    float current = (voltage - zeroPoint) / SENSITIVITY;  
    sumSquared += current * current;
    delayMicroseconds(50);  // Sampling rate improvement
    }
    return sqrt(sumSquared / numSamples);  // RMS Current Calculation
    }
    
    // Function to measure Voltage
    float readVoltage() {
    int adcValue = analogRead(VOLTAGE_SENSOR_PIN);
    float voltage = (adcValue * REF_VOLTAGE) / ADC_RESOLUTION;  
    return voltage * VOLTAGE_DIVIDER_FACTOR;  // Adjust with divider factor
    }
    void loop() {
    if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    float voltage = readVoltage();  
    float current = readACCurrent();  
    float power = voltage * current;  // Power Calculation: P = V * I
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("volt=");
    display.setCursor(70, 0);
    display.print(voltage);
    display.setCursor(0, 18);
    display.print("Amp=");
    display.setCursor(60, 18);
    display.print(current);
    display.setCursor(0, 40);
    display.print("power=");
    display.setCursor(80, 40);
    display.print(power);
    display.display();
    Serial.print("Voltage: ");
    Serial.print(voltage);
    Serial.print(" V  |  AC Current: ");
    Serial.print(current, 3);
    Serial.print(" A  |  Power: ");
    Serial.print(power, 3);
    Serial.println(" W");
    // Generate random values
    float value1 = voltage;  // Example: Temperature
    float value2 = current;  // Example: Humidity
    float value3 =power; // Example: Light Intensity
    
    // Construct the request URL
    String url = String(server) + "?api_key=" + apiKey + 
                "&field1=" + String(value1) + 
                "&field2=" + String(value2) + 
                "&field3=" + String(value3);
    
    Serial.println("Sending data to ThingSpeak...");
    Serial.println(url);
    
    // Send data to ThingSpeak
    http.begin(url);
    int httpCode = http.GET();
    
    if (httpCode > 0) {
      Serial.println("Data sent successfully!");
    } else {
      Serial.println("Failed to send data.");
    }
    
    http.end();
    } else {
    Serial.println("WiFi Disconnected!");
    }
    
    delay(500); // ThingSpeak allows updates every 15 seconds
    }
    
      
      

    I worked with all three types of communication, and I really enjoyed it. I was able to send the data successfully. I got help from a person named Ramesh, who supported me with the coding. Because of his help, there were very few errors. I also learned a lot from him. Now, I have completed 50% of the coding for my final project.

    All Communication Codes is Below

    🔌Wired Communication

    📶WiFi Communication

    ☁️Cloud Communication

    • Testing Main Code for ThingSpeak Download
    • Fainal Main Code for ThingSpeak Download