Task: Embedded Networking and Communications
Individual project:
Individual project:
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.
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 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.
In embedded systems, wired communication means transferring data between devices using physical wires. Common protocols include UART, I2C, and SPI.
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 |
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.
#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);
}
#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);
}
}
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.
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.
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,.
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.
#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
}
#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);
}
#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);
}
}
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.
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 |
![]() | ![]() |
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.
#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
#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
}
#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.
First, I tested the current sensor to verify whether it was measuring the current accurately or not.
I connected the sensor with a power supply and added a 3.3V LED to help visualize the current flow.
I verified the code successfully:
Then, I uploaded the code to the board:
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.
#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);
}
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.
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.
#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
}
#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 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.
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 |
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. |
#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
}
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.
"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."
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."
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.
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.
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.
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
#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.