<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.cognifront.com/docs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=CogWikiEditor</id>
	<title>cognifront - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.cognifront.com/docs/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=CogWikiEditor"/>
	<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php/Special:Contributions/CogWikiEditor"/>
	<updated>2026-11-11T22:43:04Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=Experiment_1:_Introduction_to_Arduino_and_Digital_I/O_Control&amp;diff=1392</id>
		<title>Experiment 1: Introduction to Arduino and Digital I/O Control</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=Experiment_1:_Introduction_to_Arduino_and_Digital_I/O_Control&amp;diff=1392"/>
		<updated>2026-10-19T03:21:40Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Circuit Connections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Experiment 1: Introduction to Arduino and Digital I/O Control ==&lt;br /&gt;
&lt;br /&gt;
=== Objective ===&lt;br /&gt;
To understand digital input/output operations by interfacing LEDs and push buttons with Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Task ===&lt;br /&gt;
# Connect LEDs and push buttons to Arduino.  &lt;br /&gt;
# Write a program to turn LEDs ON/OFF based on button press.  &lt;br /&gt;
# Observe the response on the Serial Monitor. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your Arduino from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Circuit Diagram ===&lt;br /&gt;
[[File:Eecit-kit-01-circuit.png|center|thumb|400px|Circuit Diagram]]&lt;br /&gt;
&lt;br /&gt;
=== Board Connections ===&lt;br /&gt;
[[File:Eecit-kit-01-board-connection.png|center|thumb|400px|Board Connections]]&lt;br /&gt;
&lt;br /&gt;
=== Circuit Connections (Simple)===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Push Button !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 1 || 5&lt;br /&gt;
|-&lt;br /&gt;
| Push Button GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| Push Button VCC || 5V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! LED Bar !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| LED 1 || 7&lt;br /&gt;
|-&lt;br /&gt;
|LED GND || GND&lt;br /&gt;
|}&lt;br /&gt;
* &#039;&#039;&#039;Serial Communication:&#039;&#039;&#039; 9600 baud rate&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Circuit Connections (Advanced)===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Push Button !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 1 || 5&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 2 || 4&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 3 || 2&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 4 || 3&lt;br /&gt;
|-&lt;br /&gt;
| Push Button GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| Push Button VCC || 5V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! LED Bar !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| LED 1 || 7&lt;br /&gt;
|-&lt;br /&gt;
| LED 2 || 8&lt;br /&gt;
|-&lt;br /&gt;
| LED 3 || 9&lt;br /&gt;
|-&lt;br /&gt;
| LED 4 || 10&lt;br /&gt;
|-&lt;br /&gt;
|LED GND || GND&lt;br /&gt;
|}&lt;br /&gt;
* &#039;&#039;&#039;Serial Communication:&#039;&#039;&#039; 9600 baud rate&lt;br /&gt;
&lt;br /&gt;
=== Arduino Code (Simple)===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2025, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
// Experiment 1: Introduction to Arduino and Digital I/O Control&lt;br /&gt;
// Define push button input pins&lt;br /&gt;
int push1Pin = 5;&lt;br /&gt;
&lt;br /&gt;
// Variables to store button states&lt;br /&gt;
int push1Value;&lt;br /&gt;
&lt;br /&gt;
// Define LED output pins&lt;br /&gt;
int ledPin1 = 7;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // Start serial communication at 9600 baud for debugging&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
&lt;br /&gt;
  // Set push button pins as inputs&lt;br /&gt;
  pinMode(push1Pin, INPUT);&lt;br /&gt;
  // Set LED pins as outputs&lt;br /&gt;
  pinMode(ledPin1, OUTPUT);&lt;br /&gt;
  Serial.println(&amp;quot;System Initialized: Monitoring Push Buttons and LEDs...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Read the state of each push button (HIGH = pressed, LOW = not pressed)&lt;br /&gt;
  push1Value = digitalRead(push1Pin);&lt;br /&gt;
&lt;br /&gt;
  // Determine LED states and print to Serial Monitor&lt;br /&gt;
  if(push1Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, HIGH);&lt;br /&gt;
    Serial.println(&amp;quot;Button1 PRESSED → LED1 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  else {&lt;br /&gt;
    // If no button is pressed, turn OFF all LEDs&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;No button pressed → All LEDs OFF&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  // Print raw pushbutton states for debugging&lt;br /&gt;
  Serial.print(&amp;quot;Buttons: &amp;quot;);&lt;br /&gt;
  Serial.print(push1Value);&lt;br /&gt;
  delay(500); // Small delay for better readability in Serial Monitor&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Arduino Code (Advanced)===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2025, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
&lt;br /&gt;
// Experiment 1: Introduction to Arduino and Digital I/O Control&lt;br /&gt;
&lt;br /&gt;
// Define push button input pins&lt;br /&gt;
int push1Pin = 5;&lt;br /&gt;
int push2Pin = 4;&lt;br /&gt;
int push3Pin = 2;&lt;br /&gt;
int push4Pin = 3;&lt;br /&gt;
&lt;br /&gt;
// Variables to store button states&lt;br /&gt;
int push1Value;&lt;br /&gt;
int push2Value;&lt;br /&gt;
int push3Value;&lt;br /&gt;
int push4Value;&lt;br /&gt;
&lt;br /&gt;
// Define LED output pins&lt;br /&gt;
int ledPin1 = 7;&lt;br /&gt;
int ledPin2 = 8;&lt;br /&gt;
int ledPin3 = 9;&lt;br /&gt;
int ledPin4 = 10;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // Start serial communication at 9600 baud for debugging&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
&lt;br /&gt;
  // Set push button pins as inputs&lt;br /&gt;
  pinMode(push1Pin, INPUT);&lt;br /&gt;
  pinMode(push2Pin, INPUT);&lt;br /&gt;
  pinMode(push3Pin, INPUT);&lt;br /&gt;
  pinMode(push4Pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  // Set LED pins as outputs&lt;br /&gt;
  pinMode(ledPin1, OUTPUT);&lt;br /&gt;
  pinMode(ledPin2, OUTPUT);&lt;br /&gt;
  pinMode(ledPin3, OUTPUT);&lt;br /&gt;
  pinMode(ledPin4, OUTPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;System Initialized: Monitoring Push Buttons and LEDs...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Read the state of each push button (HIGH = pressed, LOW = not pressed)&lt;br /&gt;
  push1Value = digitalRead(push1Pin);&lt;br /&gt;
  push2Value = digitalRead(push2Pin);&lt;br /&gt;
  push3Value = digitalRead(push3Pin);&lt;br /&gt;
  push4Value = digitalRead(push4Pin);&lt;br /&gt;
&lt;br /&gt;
  // Determine LED states and print to Serial Monitor&lt;br /&gt;
  if(push1Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, HIGH);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button1 PRESSED → LED1 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push2Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, HIGH);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button2 PRESSED → LED2 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push3Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, HIGH);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button3 PRESSED → LED3 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push4Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, HIGH);&lt;br /&gt;
    Serial.println(&amp;quot;Button4 PRESSED → LED4 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // If no button is pressed, turn OFF all LEDs&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;No button pressed → All LEDs OFF&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Print raw pushbutton states for debugging&lt;br /&gt;
  Serial.print(&amp;quot;Buttons: &amp;quot;);&lt;br /&gt;
  Serial.print(push1Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.print(push2Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.print(push3Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.println(push4Value);&lt;br /&gt;
&lt;br /&gt;
  delay(500); // Small delay for better readability in Serial Monitor&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Observation ===&lt;br /&gt;
* Pressing any button will turn ON the corresponding LED.  &lt;br /&gt;
* Only one LED lights up at a time because of the &#039;&#039;else-if&#039;&#039; structure.  &lt;br /&gt;
* Serial Monitor can be used to confirm button press readings.  &lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
This experiment demonstrates basic digital input and output control using Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Real Life Examples ===&lt;br /&gt;
Automated Assembly Line Control: Digital I/O is used to operate actuators, solenoids, and indicator lamps. For example, pressing a start button activates a conveyor motor, demonstrating machine automation control in manufacturing lines.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=Experiment_1:_Introduction_to_Arduino_and_Digital_I/O_Control&amp;diff=1391</id>
		<title>Experiment 1: Introduction to Arduino and Digital I/O Control</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=Experiment_1:_Introduction_to_Arduino_and_Digital_I/O_Control&amp;diff=1391"/>
		<updated>2026-10-19T03:20:40Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Arduino Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Experiment 1: Introduction to Arduino and Digital I/O Control ==&lt;br /&gt;
&lt;br /&gt;
=== Objective ===&lt;br /&gt;
To understand digital input/output operations by interfacing LEDs and push buttons with Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Task ===&lt;br /&gt;
# Connect LEDs and push buttons to Arduino.  &lt;br /&gt;
# Write a program to turn LEDs ON/OFF based on button press.  &lt;br /&gt;
# Observe the response on the Serial Monitor. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your Arduino from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Circuit Diagram ===&lt;br /&gt;
[[File:Eecit-kit-01-circuit.png|center|thumb|400px|Circuit Diagram]]&lt;br /&gt;
&lt;br /&gt;
=== Board Connections ===&lt;br /&gt;
[[File:Eecit-kit-01-board-connection.png|center|thumb|400px|Board Connections]]&lt;br /&gt;
&lt;br /&gt;
=== Circuit Connections ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! Push Button !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 1 || 5&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 2 || 4&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 3 || 2&lt;br /&gt;
|-&lt;br /&gt;
| Push Button 4 || 3&lt;br /&gt;
|-&lt;br /&gt;
| Push Button GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| Push Button VCC || 5V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center;&amp;quot;&lt;br /&gt;
! LED Bar !! Arduino Pin&lt;br /&gt;
|-&lt;br /&gt;
| LED 1 || 7&lt;br /&gt;
|-&lt;br /&gt;
| LED 2 || 8&lt;br /&gt;
|-&lt;br /&gt;
| LED 3 || 9&lt;br /&gt;
|-&lt;br /&gt;
| LED 4 || 10&lt;br /&gt;
|-&lt;br /&gt;
|LED GND || GND&lt;br /&gt;
|}&lt;br /&gt;
* &#039;&#039;&#039;Serial Communication:&#039;&#039;&#039; 9600 baud rate&lt;br /&gt;
&lt;br /&gt;
=== Arduino Code (Simple)===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2025, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
// Experiment 1: Introduction to Arduino and Digital I/O Control&lt;br /&gt;
// Define push button input pins&lt;br /&gt;
int push1Pin = 5;&lt;br /&gt;
&lt;br /&gt;
// Variables to store button states&lt;br /&gt;
int push1Value;&lt;br /&gt;
&lt;br /&gt;
// Define LED output pins&lt;br /&gt;
int ledPin1 = 7;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // Start serial communication at 9600 baud for debugging&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
&lt;br /&gt;
  // Set push button pins as inputs&lt;br /&gt;
  pinMode(push1Pin, INPUT);&lt;br /&gt;
  // Set LED pins as outputs&lt;br /&gt;
  pinMode(ledPin1, OUTPUT);&lt;br /&gt;
  Serial.println(&amp;quot;System Initialized: Monitoring Push Buttons and LEDs...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Read the state of each push button (HIGH = pressed, LOW = not pressed)&lt;br /&gt;
  push1Value = digitalRead(push1Pin);&lt;br /&gt;
&lt;br /&gt;
  // Determine LED states and print to Serial Monitor&lt;br /&gt;
  if(push1Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, HIGH);&lt;br /&gt;
    Serial.println(&amp;quot;Button1 PRESSED → LED1 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
  else {&lt;br /&gt;
    // If no button is pressed, turn OFF all LEDs&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;No button pressed → All LEDs OFF&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  // Print raw pushbutton states for debugging&lt;br /&gt;
  Serial.print(&amp;quot;Buttons: &amp;quot;);&lt;br /&gt;
  Serial.print(push1Value);&lt;br /&gt;
  delay(500); // Small delay for better readability in Serial Monitor&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Arduino Code (Advanced)===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2025, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
&lt;br /&gt;
// Experiment 1: Introduction to Arduino and Digital I/O Control&lt;br /&gt;
&lt;br /&gt;
// Define push button input pins&lt;br /&gt;
int push1Pin = 5;&lt;br /&gt;
int push2Pin = 4;&lt;br /&gt;
int push3Pin = 2;&lt;br /&gt;
int push4Pin = 3;&lt;br /&gt;
&lt;br /&gt;
// Variables to store button states&lt;br /&gt;
int push1Value;&lt;br /&gt;
int push2Value;&lt;br /&gt;
int push3Value;&lt;br /&gt;
int push4Value;&lt;br /&gt;
&lt;br /&gt;
// Define LED output pins&lt;br /&gt;
int ledPin1 = 7;&lt;br /&gt;
int ledPin2 = 8;&lt;br /&gt;
int ledPin3 = 9;&lt;br /&gt;
int ledPin4 = 10;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  // Start serial communication at 9600 baud for debugging&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
&lt;br /&gt;
  // Set push button pins as inputs&lt;br /&gt;
  pinMode(push1Pin, INPUT);&lt;br /&gt;
  pinMode(push2Pin, INPUT);&lt;br /&gt;
  pinMode(push3Pin, INPUT);&lt;br /&gt;
  pinMode(push4Pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  // Set LED pins as outputs&lt;br /&gt;
  pinMode(ledPin1, OUTPUT);&lt;br /&gt;
  pinMode(ledPin2, OUTPUT);&lt;br /&gt;
  pinMode(ledPin3, OUTPUT);&lt;br /&gt;
  pinMode(ledPin4, OUTPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;System Initialized: Monitoring Push Buttons and LEDs...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Read the state of each push button (HIGH = pressed, LOW = not pressed)&lt;br /&gt;
  push1Value = digitalRead(push1Pin);&lt;br /&gt;
  push2Value = digitalRead(push2Pin);&lt;br /&gt;
  push3Value = digitalRead(push3Pin);&lt;br /&gt;
  push4Value = digitalRead(push4Pin);&lt;br /&gt;
&lt;br /&gt;
  // Determine LED states and print to Serial Monitor&lt;br /&gt;
  if(push1Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, HIGH);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button1 PRESSED → LED1 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push2Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, HIGH);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button2 PRESSED → LED2 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push3Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, HIGH);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Button3 PRESSED → LED3 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else if(push4Value == HIGH) {&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, HIGH);&lt;br /&gt;
    Serial.println(&amp;quot;Button4 PRESSED → LED4 ON&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else {&lt;br /&gt;
    // If no button is pressed, turn OFF all LEDs&lt;br /&gt;
    digitalWrite(ledPin1, LOW);&lt;br /&gt;
    digitalWrite(ledPin2, LOW);&lt;br /&gt;
    digitalWrite(ledPin3, LOW);&lt;br /&gt;
    digitalWrite(ledPin4, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;No button pressed → All LEDs OFF&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // Print raw pushbutton states for debugging&lt;br /&gt;
  Serial.print(&amp;quot;Buttons: &amp;quot;);&lt;br /&gt;
  Serial.print(push1Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.print(push2Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.print(push3Value);&lt;br /&gt;
  Serial.print(&amp;quot; &amp;quot;);&lt;br /&gt;
  Serial.println(push4Value);&lt;br /&gt;
&lt;br /&gt;
  delay(500); // Small delay for better readability in Serial Monitor&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Observation ===&lt;br /&gt;
* Pressing any button will turn ON the corresponding LED.  &lt;br /&gt;
* Only one LED lights up at a time because of the &#039;&#039;else-if&#039;&#039; structure.  &lt;br /&gt;
* Serial Monitor can be used to confirm button press readings.  &lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
This experiment demonstrates basic digital input and output control using Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Real Life Examples ===&lt;br /&gt;
Automated Assembly Line Control: Digital I/O is used to operate actuators, solenoids, and indicator lamps. For example, pressing a start button activates a conveyor motor, demonstrating machine automation control in manufacturing lines.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1390</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1390"/>
		<updated>2026-10-08T10:17:37Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* ESP32 Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| VIN (5V supply)&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
// DHT11 Temperature Data Logging Using ESP32 and Cognifront Cloud&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;;                 // Wi-Fi / hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;;                 // Wi-Fi / hotspot password&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;;      // API key from Cognifront Cloud&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
    dht.begin();&lt;br /&gt;
&lt;br /&gt;
    // Initialize Cognifront Cloud&lt;br /&gt;
    cogInitCloud(ssid, pass, apikey);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 Temperature Monitoring Started&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    // Handle cloud communication&lt;br /&gt;
    cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
    // Read temperature in Celsius&lt;br /&gt;
    float temperature = dht.readTemperature();&lt;br /&gt;
&lt;br /&gt;
    // Check for sensor reading failure&lt;br /&gt;
    if (isnan(temperature))&lt;br /&gt;
    {&lt;br /&gt;
        Serial.println(&amp;quot;Failed to read temperature from DHT11&amp;quot;);&lt;br /&gt;
        delay(2000);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Display temperature on Serial Monitor&lt;br /&gt;
    Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
    Serial.print(temperature);&lt;br /&gt;
    Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    // Send temperature to Cognifront Cloud&lt;br /&gt;
    cogStoreCloudVariable(&amp;quot;DHT11&amp;quot;, String(temperature, 2));&lt;br /&gt;
&lt;br /&gt;
    delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the DHT11 sensor.&lt;br /&gt;
* Data is properly being logged in CSV file, and file is downloaded successfully.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1389</id>
		<title>MDM331AID/Experiment 14</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1389"/>
		<updated>2026-10-08T03:50:49Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Working Principle */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Smart Threshold Alerts for Data Minimization using Privacy-by-Design =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To design and implement a Privacy-by-Design IoT system using a vibration sensor and ESP32 that detects excessive vibration using a predefined threshold and generates an alert only when the threshold condition is reached, thereby minimizing unnecessary sensor data transmission.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
# To understand Privacy-by-Design in an IoT system.&lt;br /&gt;
# To understand the concept of data minimization.&lt;br /&gt;
# To interface a vibration sensor with ESP32.&lt;br /&gt;
# To detect vibration activity using the sensor.&lt;br /&gt;
# To define a threshold for excessive vibration.&lt;br /&gt;
# To generate an EXCESSIVE VIBRATION alert when the threshold is crossed.&lt;br /&gt;
# To process vibration data locally on the ESP32.&lt;br /&gt;
# To avoid continuously transmitting raw vibration readings.&lt;br /&gt;
# To expose only the required alert information.&lt;br /&gt;
# To demonstrate data minimization through a simple web-based monitoring system.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| Reads the vibration sensor and hosts the web server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Vibration Sensor Module&lt;br /&gt;
| 1&lt;br /&gt;
| Detects vibration activity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Breadboard&lt;br /&gt;
| 1&lt;br /&gt;
| Circuit connections&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| Accesses the ESP32 web page&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and powering ESP32&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| Programming the ESP32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things ===&lt;br /&gt;
&lt;br /&gt;
The Internet of Things, or IoT, is a system in which physical devices use sensors and communication technologies to collect and exchange information.&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, sensor readings may be continuously transmitted even when the application does not require all of the readings.&lt;br /&gt;
&lt;br /&gt;
For example, a vibration monitoring system may continuously generate sensor readings.&lt;br /&gt;
&lt;br /&gt;
If the purpose of the application is only to detect excessive vibration, the application does not necessarily need every individual sensor reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 can instead process the vibration activity locally and generate an alert only when the required condition occurs.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design ===&lt;br /&gt;
&lt;br /&gt;
Privacy-by-Design means that privacy considerations are incorporated into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
One important approach related to Privacy-by-Design is data minimization.&lt;br /&gt;
&lt;br /&gt;
Data minimization means collecting, processing, transmitting, and storing only the information that is necessary for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the purpose is to detect excessive vibration.&lt;br /&gt;
&lt;br /&gt;
Therefore, the system does not need to continuously expose every raw vibration reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 processes the vibration activity locally and generates an alert only when the predefined threshold condition is reached.&lt;br /&gt;
&lt;br /&gt;
=== Smart Threshold Alert ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to determine when a particular condition has occurred.&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor and keeps track of vibration activity.&lt;br /&gt;
&lt;br /&gt;
When the number of detected vibration events reaches the selected threshold within the monitoring period, the ESP32 considers the vibration level excessive.&lt;br /&gt;
&lt;br /&gt;
The operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
     ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Monitor vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Normal vibration       Excessive vibration&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The threshold can be adjusted according to the sensor and the required application.&lt;br /&gt;
&lt;br /&gt;
=== Data Minimization ===&lt;br /&gt;
&lt;br /&gt;
In a conventional system, raw vibration readings may be continuously sent to another device or server.&lt;br /&gt;
&lt;br /&gt;
In the proposed system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing on ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Below threshold         Threshold reached&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally for decision making.&lt;br /&gt;
&lt;br /&gt;
Unnecessary continuous sensor data is therefore not exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
== Sensor Connection ==&lt;br /&gt;
&lt;br /&gt;
The vibration sensor module normally provides VCC, GND, and a digital output pin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vibration Sensor Pin&lt;br /&gt;
! ESP32&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| DO or OUT&lt;br /&gt;
| GPIO 27&lt;br /&gt;
| Digital vibration signal&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The exact pin names may vary between vibration sensor modules. Verify the labels on the actual sensor before making the connections.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             Vibration Sensor&lt;br /&gt;
             +-------------+&lt;br /&gt;
             |             |&lt;br /&gt;
     3.3V ---| VCC         |&lt;br /&gt;
             |             |&lt;br /&gt;
 GPIO 27 &amp;amp;lt;---| DO / OUT    |&lt;br /&gt;
             |             |&lt;br /&gt;
     GND ----| GND         |&lt;br /&gt;
             +-------------+&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
                  ESP32&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Wi-Fi Access Point&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Smartphone Browser&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
              192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Working Principle ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 works as a Wi-Fi Access Point and hosts a simple web server.&lt;br /&gt;
&lt;br /&gt;
The smartphone connects directly to the Wi-Fi network created by the ESP32.&lt;br /&gt;
&lt;br /&gt;
The student then opens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor.&lt;br /&gt;
&lt;br /&gt;
Each detected vibration event increases the vibration count during the monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the vibration count reaches the predefined threshold, the ESP32 generates an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The web page displays the current status.&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds so that the latest status can be observed.&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally on the ESP32.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const int VIBRATION_PIN=27;&lt;br /&gt;
const char* ap_ssid=&amp;quot;ESP32-Vibration-Monitor&amp;quot;;&lt;br /&gt;
const char* ap_password=&amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
const int VIBRATION_THRESHOLD=100;&lt;br /&gt;
const unsigned long MONITOR_PERIOD=10000;&lt;br /&gt;
&lt;br /&gt;
int vibrationCount=0;&lt;br /&gt;
bool excessiveVibration=false;&lt;br /&gt;
unsigned long periodStart=0;&lt;br /&gt;
int lastSensorState=LOW;&lt;br /&gt;
&lt;br /&gt;
void updateVibration()&lt;br /&gt;
{&lt;br /&gt;
  int sensorState=digitalRead(VIBRATION_PIN);&lt;br /&gt;
&lt;br /&gt;
  if(sensorState==HIGH &amp;amp;&amp;amp; lastSensorState==LOW)&lt;br /&gt;
  {&lt;br /&gt;
    vibrationCount++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  lastSensorState=sensorState;&lt;br /&gt;
&lt;br /&gt;
  if(millis()-periodStart&amp;gt;=MONITOR_PERIOD)&lt;br /&gt;
  {&lt;br /&gt;
    if(vibrationCount&amp;gt;=VIBRATION_THRESHOLD)&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration=true;&lt;br /&gt;
      Serial.println(&amp;quot;EXCESSIVE VIBRATION&amp;quot;);&lt;br /&gt;
      Serial.println(&amp;quot;Alert generated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration=false;&lt;br /&gt;
      Serial.println(&amp;quot;NORMAL&amp;quot;);&lt;br /&gt;
      Serial.println(&amp;quot;Vibration level is within the normal range.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Vibration events: &amp;quot;);&lt;br /&gt;
    Serial.println(vibrationCount);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;--------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    vibrationCount=0;&lt;br /&gt;
    periodStart=millis();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
&lt;br /&gt;
  String page=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  char lt=60;&lt;br /&gt;
  char gt=62;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;html&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;head&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1&#039;&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;meta http-equiv=&#039;refresh&#039; content=&#039;5&#039;&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;title&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Vibration Monitor&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/title&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/head&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;body&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;h1&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Smart Vibration Monitor&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/h1&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  if(excessiveVibration)&lt;br /&gt;
  {&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;EXCESSIVE VIBRATION&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;Threshold crossed. Alert generated.&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;NORMAL&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;Vibration level is within the normal range.&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Page refreshes every 5 seconds.&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/body&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/html&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  server.send(200,&amp;quot;text/html&amp;quot;,page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  pinMode(VIBRATION_PIN,INPUT);&lt;br /&gt;
&lt;br /&gt;
  periodStart=millis();&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAPConfig(&lt;br /&gt;
    IPAddress(192,168,1,4),&lt;br /&gt;
    IPAddress(192,168,1,1),&lt;br /&gt;
    IPAddress(255,255,255,0)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(ap_ssid,ap_password);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Access Point started&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.softAPIP());&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;,handleRoot);&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;--------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code or Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.h&lt;br /&gt;
| Provides ESP32 Wi-Fi functionality.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer.h&lt;br /&gt;
| Provides web server functionality.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_PIN&lt;br /&gt;
| Defines GPIO 27 as the vibration sensor input.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAP&lt;br /&gt;
| Creates a Wi-Fi Access Point using the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAPConfig&lt;br /&gt;
| Sets the Access Point IP address to 192.168.1.4.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer server(80)&lt;br /&gt;
| Creates an HTTP web server on port 80.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_THRESHOLD&lt;br /&gt;
| Defines the number of vibration events required to generate an alert.&lt;br /&gt;
|-&lt;br /&gt;
| MONITOR_PERIOD&lt;br /&gt;
| Defines the time interval over which vibration events are counted.&lt;br /&gt;
|-&lt;br /&gt;
| vibrationCount&lt;br /&gt;
| Stores the number of detected vibration events.&lt;br /&gt;
|-&lt;br /&gt;
| excessiveVibration&lt;br /&gt;
| Stores whether the excessive-vibration condition has been detected.&lt;br /&gt;
|-&lt;br /&gt;
| digitalRead&lt;br /&gt;
| Reads the digital output of the vibration sensor.&lt;br /&gt;
|-&lt;br /&gt;
| updateVibration&lt;br /&gt;
| Detects vibration events and checks the threshold.&lt;br /&gt;
|-&lt;br /&gt;
| handleRoot&lt;br /&gt;
| Generates the web page displayed on the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| server.send&lt;br /&gt;
| Sends the web page to the browser.&lt;br /&gt;
|-&lt;br /&gt;
| server.handleClient&lt;br /&gt;
| Processes browser requests.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Access Point ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 creates its own Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
The network name is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Vibration-Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP address is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The smartphone can therefore access the web page using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vibration Detection ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the digital output of the vibration sensor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int sensorState = digitalRead(VIBRATION_PIN);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a vibration event causes the sensor output to change from LOW to HIGH, the vibration count is increased.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (sensorState == HIGH &amp;amp;&amp;amp; lastSensorState == LOW)&lt;br /&gt;
{&lt;br /&gt;
  vibrationCount++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows the ESP32 to count vibration events locally.&lt;br /&gt;
&lt;br /&gt;
=== Threshold Detection ===&lt;br /&gt;
&lt;br /&gt;
The program uses a vibration threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int VIBRATION_THRESHOLD = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The monitoring period is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const unsigned long MONITOR_PERIOD = 10000;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that the ESP32 counts vibration events during a 10 second period.&lt;br /&gt;
&lt;br /&gt;
If the number of detected events is 5 or more, the system generates the excessive vibration alert.&lt;br /&gt;
&lt;br /&gt;
The threshold can be changed depending on the sensor and demonstration requirements.&lt;br /&gt;
&lt;br /&gt;
== Calibration of Vibration Threshold ==&lt;br /&gt;
&lt;br /&gt;
The threshold should be tested before performing the main experiment.&lt;br /&gt;
&lt;br /&gt;
# Upload the program to the ESP32.&lt;br /&gt;
# Open the Arduino IDE Serial Monitor.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Observe the system under normal conditions.&lt;br /&gt;
# Tap or shake the vibration sensor several times.&lt;br /&gt;
# Observe how the sensor responds.&lt;br /&gt;
# Select a suitable vibration threshold.&lt;br /&gt;
# Change the VIBRATION_THRESHOLD value if required.&lt;br /&gt;
# Upload the program again.&lt;br /&gt;
# Verify that normal vibration does not unnecessarily generate an alert.&lt;br /&gt;
# Verify that repeated vibration generates the alert.&lt;br /&gt;
&lt;br /&gt;
For a simple classroom demonstration, the threshold can be kept low so that students can easily trigger the alert by tapping or shaking the sensor.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the vibration sensor to the ESP32.&lt;br /&gt;
# Connect VCC to 3.3V.&lt;br /&gt;
# Connect GND to GND.&lt;br /&gt;
# Connect the digital output of the vibration sensor to GPIO 27.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Select the appropriate ESP32 board.&lt;br /&gt;
# Select the appropriate COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor.&lt;br /&gt;
# Verify that the ESP32 Access Point has started.&lt;br /&gt;
# Connect the smartphone to ESP32-Vibration-Monitor.&lt;br /&gt;
# Open the smartphone browser.&lt;br /&gt;
# Enter http://192.168.1.4.&lt;br /&gt;
# Observe the NORMAL status.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Tap or shake the sensor repeatedly.&lt;br /&gt;
# Generate several vibration events within the monitoring period.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Wait for the next monitoring period and observe the status.&lt;br /&gt;
# Verify that the web page refreshes automatically every 5 seconds.&lt;br /&gt;
# Perform the data minimization demonstration.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Normal Condition ===&lt;br /&gt;
&lt;br /&gt;
When the vibration sensor is stationary or experiences only minor vibration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Normal&lt;br /&gt;
System Status    : NORMAL&lt;br /&gt;
Alert            : None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system does not generate an alert.&lt;br /&gt;
&lt;br /&gt;
=== Excessive Vibration Condition ===&lt;br /&gt;
&lt;br /&gt;
When repeated vibration events cross the predefined threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Excessive vibration&lt;br /&gt;
System Status    : ALERT&lt;br /&gt;
Alert            : EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 generates the alert locally.&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Output ===&lt;br /&gt;
&lt;br /&gt;
Normal condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
NORMAL&lt;br /&gt;
&lt;br /&gt;
Vibration level is within&lt;br /&gt;
the normal range.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Excessive vibration condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&lt;br /&gt;
Threshold crossed.&lt;br /&gt;
Alert generated.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demonstration of Data Minimization ==&lt;br /&gt;
&lt;br /&gt;
The main purpose of this experiment is to demonstrate that unnecessary raw sensor information does not need to be continuously transmitted.&lt;br /&gt;
&lt;br /&gt;
=== Conventional System ===&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, every sensor event or sensor reading could be transmitted to a server.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The server would receive a continuous stream of sensor information.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design System ===&lt;br /&gt;
&lt;br /&gt;
In the proposed system, the ESP32 processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
The ESP32 counts the vibration events and compares the count with the threshold.&lt;br /&gt;
&lt;br /&gt;
The process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count events&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +---------------------+&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
Below threshold        Threshold reached&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is not required outside the ESP32 for the basic application.&lt;br /&gt;
&lt;br /&gt;
Only the required alert needs to be exposed.&lt;br /&gt;
&lt;br /&gt;
== Data Inspection Demonstration ==&lt;br /&gt;
&lt;br /&gt;
The data inspection demonstration is used to compare the amount of information exposed by two system designs.&lt;br /&gt;
&lt;br /&gt;
The demonstration is educational and is intended to show the effect of data minimization.&lt;br /&gt;
&lt;br /&gt;
=== Conventional Design ===&lt;br /&gt;
&lt;br /&gt;
A conventional system may continuously expose individual vibration events:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An observer can therefore obtain detailed information about the vibration activity.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design Design ===&lt;br /&gt;
&lt;br /&gt;
The Privacy-by-Design system processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
When the vibration count is below the threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
No alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the threshold is reached:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application therefore exposes only the information required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
=== Demonstration Steps ===&lt;br /&gt;
&lt;br /&gt;
# Connect the smartphone to the ESP32 Access Point.&lt;br /&gt;
# Open the ESP32 web page.&lt;br /&gt;
# Observe the NORMAL condition.&lt;br /&gt;
# Tap or shake the vibration sensor repeatedly.&lt;br /&gt;
# Generate enough vibration events to cross the threshold.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Inspect the application data using an appropriate network inspection or server logging method.&lt;br /&gt;
# Observe that the application does not need to continuously expose every vibration event.&lt;br /&gt;
# Explain that the ESP32 processes the vibration activity locally before generating the alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This demonstration is about data minimization. It does not claim that HTTP communication is encrypted or completely secure.&lt;br /&gt;
&lt;br /&gt;
== Conventional System vs Privacy-by-Design System ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Feature&lt;br /&gt;
! Conventional System&lt;br /&gt;
! Privacy-by-Design System&lt;br /&gt;
|-&lt;br /&gt;
| Sensor processing&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed locally on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Vibration events&lt;br /&gt;
| May be continuously transmitted&lt;br /&gt;
| Processed locally&lt;br /&gt;
|-&lt;br /&gt;
| Normal activity&lt;br /&gt;
| May be transmitted&lt;br /&gt;
| No unnecessary transmission&lt;br /&gt;
|-&lt;br /&gt;
| Threshold detection&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Alert&lt;br /&gt;
| May contain detailed sensor information&lt;br /&gt;
| Only required alert is exposed&lt;br /&gt;
|-&lt;br /&gt;
| Data volume&lt;br /&gt;
| Higher&lt;br /&gt;
| Lower&lt;br /&gt;
|-&lt;br /&gt;
| Data exposure&lt;br /&gt;
| Higher&lt;br /&gt;
| Minimized&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Why This is Privacy-by-Design ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates Privacy-by-Design through the following design decisions:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local Processing:&#039;&#039;&#039; Vibration activity is processed on the ESP32.&lt;br /&gt;
# &#039;&#039;&#039;Data Minimization:&#039;&#039;&#039; Individual vibration events do not need to be continuously transmitted.&lt;br /&gt;
# &#039;&#039;&#039;Purpose Limitation:&#039;&#039;&#039; The system only needs to detect excessive vibration.&lt;br /&gt;
# &#039;&#039;&#039;Smart Thresholding:&#039;&#039;&#039; An alert is generated only when the vibration threshold is crossed.&lt;br /&gt;
# &#039;&#039;&#039;Reduced Data Exposure:&#039;&#039;&#039; Unnecessary sensor information is not exposed.&lt;br /&gt;
# &#039;&#039;&#039;Privacy by Default:&#039;&#039;&#039; The system is designed to minimize data exposure from the beginning.&lt;br /&gt;
&lt;br /&gt;
The main principle demonstrated is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Do not transmit unnecessary information&lt;br /&gt;
when the application does not require it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Automatic Page Refresh ==&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
This is implemented using the page refresh setting in the generated web page.&lt;br /&gt;
&lt;br /&gt;
The refresh interval allows the student to observe the latest vibration status without manually refreshing the browser.&lt;br /&gt;
&lt;br /&gt;
The refresh interval is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
5 seconds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Therefore, after generating vibration activity, the student can wait for the next page refresh to observe the updated alert status.&lt;br /&gt;
&lt;br /&gt;
== Advantages ==&lt;br /&gt;
&lt;br /&gt;
# Reduces unnecessary sensor data transmission.&lt;br /&gt;
# Processes vibration information locally.&lt;br /&gt;
# Reduces the amount of sensor information exposed outside the device.&lt;br /&gt;
# Allows fast local decision making.&lt;br /&gt;
# Demonstrates data minimization clearly.&lt;br /&gt;
# Does not require an external cloud server.&lt;br /&gt;
# Can be demonstrated easily using a smartphone.&lt;br /&gt;
# Vibration can be generated manually by tapping or shaking the sensor.&lt;br /&gt;
# The web page automatically refreshes every 5 seconds.&lt;br /&gt;
# Can be extended to industrial machine monitoring applications.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
# The vibration sensor module provides a simple indication of vibration and may not provide precise vibration measurements.&lt;br /&gt;
# The sensor may respond differently depending on the strength and duration of vibration.&lt;br /&gt;
# The threshold must be calibrated for the actual sensor and application.&lt;br /&gt;
# Environmental vibration may cause unwanted detections.&lt;br /&gt;
# The HTTP communication used in this experiment is not encrypted.&lt;br /&gt;
# This experiment demonstrates data minimization and not complete IoT security.&lt;br /&gt;
# A real industrial vibration monitoring system would normally use a more precise vibration sensor and appropriate signal processing.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The smart threshold alert system was successfully implemented using a vibration sensor and ESP32.&lt;br /&gt;
&lt;br /&gt;
The ESP32 locally monitored vibration activity and counted vibration events during a predefined monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the number of vibration events reached the selected threshold, the system generated an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The alert was displayed on a smartphone through the ESP32 web server using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshed every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrated that raw vibration activity does not need to be continuously exposed when the application only requires an excessive-vibration alert.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated data minimization through local processing and smart threshold alerts as a practical Privacy-by-Design approach.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is Privacy-by-Design?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Privacy-by-Design means incorporating privacy considerations into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. What is data minimization?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Data minimization means collecting, processing, transmitting, and storing only the data required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. Why is a vibration sensor used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A vibration sensor is used because vibration can be generated manually by tapping or shaking the sensor, making the alert easy to demonstrate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What does excessive vibration represent in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Excessive vibration represents a condition in which the number of vibration events has crossed the predefined threshold.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. Why is the raw vibration activity not continuously transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The application only needs to know whether excessive vibration has occurred. Therefore, continuously transmitting every vibration event is unnecessary.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. Where is the vibration threshold checked?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The threshold is checked locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What happens when the threshold is not crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No excessive-vibration alert is generated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What happens when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The ESP32 detects excessive vibration and generates the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is the purpose of the data inspection demonstration?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; It demonstrates how data minimization reduces the amount of unnecessary sensor information exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What information is required when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The required information is the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why does the web page refresh every 5 seconds?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The page refreshes every 5 seconds so that the smartphone can display the latest system status automatically.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Is the system completely secure?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. The main purpose is to demonstrate data minimization and Privacy-by-Design. The HTTP communication used here is not encrypted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. Does data minimization mean that no data is transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. It means that only the data necessary for the intended purpose should be transmitted or exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. Why is local processing useful?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Local processing allows the ESP32 to make decisions using sensor data without unnecessarily exposing the raw sensor activity.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. What is a smart threshold alert?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A smart threshold alert is generated when sensor activity crosses a predefined threshold representing a meaningful condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q16. What is the main principle demonstrated by this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The main principle is data minimization. Sensor activity is processed locally and only the required alert is exposed.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1388</id>
		<title>MDM331AID/Experiment 14</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1388"/>
		<updated>2026-10-08T03:49:55Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Smart Threshold Alerts for Data Minimization using Privacy-by-Design =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To design and implement a Privacy-by-Design IoT system using a vibration sensor and ESP32 that detects excessive vibration using a predefined threshold and generates an alert only when the threshold condition is reached, thereby minimizing unnecessary sensor data transmission.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
# To understand Privacy-by-Design in an IoT system.&lt;br /&gt;
# To understand the concept of data minimization.&lt;br /&gt;
# To interface a vibration sensor with ESP32.&lt;br /&gt;
# To detect vibration activity using the sensor.&lt;br /&gt;
# To define a threshold for excessive vibration.&lt;br /&gt;
# To generate an EXCESSIVE VIBRATION alert when the threshold is crossed.&lt;br /&gt;
# To process vibration data locally on the ESP32.&lt;br /&gt;
# To avoid continuously transmitting raw vibration readings.&lt;br /&gt;
# To expose only the required alert information.&lt;br /&gt;
# To demonstrate data minimization through a simple web-based monitoring system.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| Reads the vibration sensor and hosts the web server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Vibration Sensor Module&lt;br /&gt;
| 1&lt;br /&gt;
| Detects vibration activity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Breadboard&lt;br /&gt;
| 1&lt;br /&gt;
| Circuit connections&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| Accesses the ESP32 web page&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and powering ESP32&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| Programming the ESP32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things ===&lt;br /&gt;
&lt;br /&gt;
The Internet of Things, or IoT, is a system in which physical devices use sensors and communication technologies to collect and exchange information.&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, sensor readings may be continuously transmitted even when the application does not require all of the readings.&lt;br /&gt;
&lt;br /&gt;
For example, a vibration monitoring system may continuously generate sensor readings.&lt;br /&gt;
&lt;br /&gt;
If the purpose of the application is only to detect excessive vibration, the application does not necessarily need every individual sensor reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 can instead process the vibration activity locally and generate an alert only when the required condition occurs.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design ===&lt;br /&gt;
&lt;br /&gt;
Privacy-by-Design means that privacy considerations are incorporated into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
One important approach related to Privacy-by-Design is data minimization.&lt;br /&gt;
&lt;br /&gt;
Data minimization means collecting, processing, transmitting, and storing only the information that is necessary for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the purpose is to detect excessive vibration.&lt;br /&gt;
&lt;br /&gt;
Therefore, the system does not need to continuously expose every raw vibration reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 processes the vibration activity locally and generates an alert only when the predefined threshold condition is reached.&lt;br /&gt;
&lt;br /&gt;
=== Smart Threshold Alert ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to determine when a particular condition has occurred.&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor and keeps track of vibration activity.&lt;br /&gt;
&lt;br /&gt;
When the number of detected vibration events reaches the selected threshold within the monitoring period, the ESP32 considers the vibration level excessive.&lt;br /&gt;
&lt;br /&gt;
The operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
     ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Monitor vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Normal vibration       Excessive vibration&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The threshold can be adjusted according to the sensor and the required application.&lt;br /&gt;
&lt;br /&gt;
=== Data Minimization ===&lt;br /&gt;
&lt;br /&gt;
In a conventional system, raw vibration readings may be continuously sent to another device or server.&lt;br /&gt;
&lt;br /&gt;
In the proposed system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing on ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Below threshold         Threshold reached&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally for decision making.&lt;br /&gt;
&lt;br /&gt;
Unnecessary continuous sensor data is therefore not exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
== Sensor Connection ==&lt;br /&gt;
&lt;br /&gt;
The vibration sensor module normally provides VCC, GND, and a digital output pin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vibration Sensor Pin&lt;br /&gt;
! ESP32&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| DO or OUT&lt;br /&gt;
| GPIO 27&lt;br /&gt;
| Digital vibration signal&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The exact pin names may vary between vibration sensor modules. Verify the labels on the actual sensor before making the connections.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             Vibration Sensor&lt;br /&gt;
             +-------------+&lt;br /&gt;
             |             |&lt;br /&gt;
     3.3V ---| VCC         |&lt;br /&gt;
             |             |&lt;br /&gt;
 GPIO 27 &amp;amp;lt;---| DO / OUT    |&lt;br /&gt;
             |             |&lt;br /&gt;
     GND ----| GND         |&lt;br /&gt;
             +-------------+&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
                  ESP32&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Wi-Fi Access Point&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Smartphone Browser&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
              192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Working Principle ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 works as a Wi-Fi Access Point and hosts a simple web server.&lt;br /&gt;
&lt;br /&gt;
The smartphone connects directly to the Wi-Fi network created by the ESP32.&lt;br /&gt;
&lt;br /&gt;
The student then opens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor.&lt;br /&gt;
&lt;br /&gt;
Each detected vibration event increases the vibration count during the monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the vibration count reaches the predefined threshold, the ESP32 generates an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The web page displays the current status.&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds so that the latest status can be observed.&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const int VIBRATION_PIN=27;&lt;br /&gt;
const char* ap_ssid=&amp;quot;ESP32-Vibration-Monitor&amp;quot;;&lt;br /&gt;
const char* ap_password=&amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
const int VIBRATION_THRESHOLD=100;&lt;br /&gt;
const unsigned long MONITOR_PERIOD=10000;&lt;br /&gt;
&lt;br /&gt;
int vibrationCount=0;&lt;br /&gt;
bool excessiveVibration=false;&lt;br /&gt;
unsigned long periodStart=0;&lt;br /&gt;
int lastSensorState=LOW;&lt;br /&gt;
&lt;br /&gt;
void updateVibration()&lt;br /&gt;
{&lt;br /&gt;
  int sensorState=digitalRead(VIBRATION_PIN);&lt;br /&gt;
&lt;br /&gt;
  if(sensorState==HIGH &amp;amp;&amp;amp; lastSensorState==LOW)&lt;br /&gt;
  {&lt;br /&gt;
    vibrationCount++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  lastSensorState=sensorState;&lt;br /&gt;
&lt;br /&gt;
  if(millis()-periodStart&amp;gt;=MONITOR_PERIOD)&lt;br /&gt;
  {&lt;br /&gt;
    if(vibrationCount&amp;gt;=VIBRATION_THRESHOLD)&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration=true;&lt;br /&gt;
      Serial.println(&amp;quot;EXCESSIVE VIBRATION&amp;quot;);&lt;br /&gt;
      Serial.println(&amp;quot;Alert generated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration=false;&lt;br /&gt;
      Serial.println(&amp;quot;NORMAL&amp;quot;);&lt;br /&gt;
      Serial.println(&amp;quot;Vibration level is within the normal range.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Vibration events: &amp;quot;);&lt;br /&gt;
    Serial.println(vibrationCount);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;--------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    vibrationCount=0;&lt;br /&gt;
    periodStart=millis();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
&lt;br /&gt;
  String page=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  char lt=60;&lt;br /&gt;
  char gt=62;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;html&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;head&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1&#039;&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;meta http-equiv=&#039;refresh&#039; content=&#039;5&#039;&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;title&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Vibration Monitor&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/title&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/head&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;body&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;h1&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Smart Vibration Monitor&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/h1&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  if(excessiveVibration)&lt;br /&gt;
  {&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;EXCESSIVE VIBRATION&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;Threshold crossed. Alert generated.&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;NORMAL&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
    page+=&amp;quot;Vibration level is within the normal range.&amp;quot;;&lt;br /&gt;
    page+=lt;&lt;br /&gt;
    page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
    page+=gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;p&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
  page+=&amp;quot;Page refreshes every 5 seconds.&amp;quot;;&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/p&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/body&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  page+=lt;&lt;br /&gt;
  page+=&amp;quot;/html&amp;quot;;&lt;br /&gt;
  page+=gt;&lt;br /&gt;
&lt;br /&gt;
  server.send(200,&amp;quot;text/html&amp;quot;,page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  pinMode(VIBRATION_PIN,INPUT);&lt;br /&gt;
&lt;br /&gt;
  periodStart=millis();&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAPConfig(&lt;br /&gt;
    IPAddress(192,168,1,4),&lt;br /&gt;
    IPAddress(192,168,1,1),&lt;br /&gt;
    IPAddress(255,255,255,0)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(ap_ssid,ap_password);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Access Point started&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.softAPIP());&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;,handleRoot);&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;--------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code or Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.h&lt;br /&gt;
| Provides ESP32 Wi-Fi functionality.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer.h&lt;br /&gt;
| Provides web server functionality.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_PIN&lt;br /&gt;
| Defines GPIO 27 as the vibration sensor input.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAP&lt;br /&gt;
| Creates a Wi-Fi Access Point using the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAPConfig&lt;br /&gt;
| Sets the Access Point IP address to 192.168.1.4.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer server(80)&lt;br /&gt;
| Creates an HTTP web server on port 80.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_THRESHOLD&lt;br /&gt;
| Defines the number of vibration events required to generate an alert.&lt;br /&gt;
|-&lt;br /&gt;
| MONITOR_PERIOD&lt;br /&gt;
| Defines the time interval over which vibration events are counted.&lt;br /&gt;
|-&lt;br /&gt;
| vibrationCount&lt;br /&gt;
| Stores the number of detected vibration events.&lt;br /&gt;
|-&lt;br /&gt;
| excessiveVibration&lt;br /&gt;
| Stores whether the excessive-vibration condition has been detected.&lt;br /&gt;
|-&lt;br /&gt;
| digitalRead&lt;br /&gt;
| Reads the digital output of the vibration sensor.&lt;br /&gt;
|-&lt;br /&gt;
| updateVibration&lt;br /&gt;
| Detects vibration events and checks the threshold.&lt;br /&gt;
|-&lt;br /&gt;
| handleRoot&lt;br /&gt;
| Generates the web page displayed on the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| server.send&lt;br /&gt;
| Sends the web page to the browser.&lt;br /&gt;
|-&lt;br /&gt;
| server.handleClient&lt;br /&gt;
| Processes browser requests.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Access Point ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 creates its own Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
The network name is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Vibration-Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP address is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The smartphone can therefore access the web page using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vibration Detection ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the digital output of the vibration sensor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int sensorState = digitalRead(VIBRATION_PIN);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a vibration event causes the sensor output to change from LOW to HIGH, the vibration count is increased.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (sensorState == HIGH &amp;amp;&amp;amp; lastSensorState == LOW)&lt;br /&gt;
{&lt;br /&gt;
  vibrationCount++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows the ESP32 to count vibration events locally.&lt;br /&gt;
&lt;br /&gt;
=== Threshold Detection ===&lt;br /&gt;
&lt;br /&gt;
The program uses a vibration threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int VIBRATION_THRESHOLD = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The monitoring period is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const unsigned long MONITOR_PERIOD = 10000;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that the ESP32 counts vibration events during a 10 second period.&lt;br /&gt;
&lt;br /&gt;
If the number of detected events is 5 or more, the system generates the excessive vibration alert.&lt;br /&gt;
&lt;br /&gt;
The threshold can be changed depending on the sensor and demonstration requirements.&lt;br /&gt;
&lt;br /&gt;
== Calibration of Vibration Threshold ==&lt;br /&gt;
&lt;br /&gt;
The threshold should be tested before performing the main experiment.&lt;br /&gt;
&lt;br /&gt;
# Upload the program to the ESP32.&lt;br /&gt;
# Open the Arduino IDE Serial Monitor.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Observe the system under normal conditions.&lt;br /&gt;
# Tap or shake the vibration sensor several times.&lt;br /&gt;
# Observe how the sensor responds.&lt;br /&gt;
# Select a suitable vibration threshold.&lt;br /&gt;
# Change the VIBRATION_THRESHOLD value if required.&lt;br /&gt;
# Upload the program again.&lt;br /&gt;
# Verify that normal vibration does not unnecessarily generate an alert.&lt;br /&gt;
# Verify that repeated vibration generates the alert.&lt;br /&gt;
&lt;br /&gt;
For a simple classroom demonstration, the threshold can be kept low so that students can easily trigger the alert by tapping or shaking the sensor.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the vibration sensor to the ESP32.&lt;br /&gt;
# Connect VCC to 3.3V.&lt;br /&gt;
# Connect GND to GND.&lt;br /&gt;
# Connect the digital output of the vibration sensor to GPIO 27.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Select the appropriate ESP32 board.&lt;br /&gt;
# Select the appropriate COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor.&lt;br /&gt;
# Verify that the ESP32 Access Point has started.&lt;br /&gt;
# Connect the smartphone to ESP32-Vibration-Monitor.&lt;br /&gt;
# Open the smartphone browser.&lt;br /&gt;
# Enter http://192.168.1.4.&lt;br /&gt;
# Observe the NORMAL status.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Tap or shake the sensor repeatedly.&lt;br /&gt;
# Generate several vibration events within the monitoring period.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Wait for the next monitoring period and observe the status.&lt;br /&gt;
# Verify that the web page refreshes automatically every 5 seconds.&lt;br /&gt;
# Perform the data minimization demonstration.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Normal Condition ===&lt;br /&gt;
&lt;br /&gt;
When the vibration sensor is stationary or experiences only minor vibration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Normal&lt;br /&gt;
System Status    : NORMAL&lt;br /&gt;
Alert            : None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system does not generate an alert.&lt;br /&gt;
&lt;br /&gt;
=== Excessive Vibration Condition ===&lt;br /&gt;
&lt;br /&gt;
When repeated vibration events cross the predefined threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Excessive vibration&lt;br /&gt;
System Status    : ALERT&lt;br /&gt;
Alert            : EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 generates the alert locally.&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Output ===&lt;br /&gt;
&lt;br /&gt;
Normal condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
NORMAL&lt;br /&gt;
&lt;br /&gt;
Vibration level is within&lt;br /&gt;
the normal range.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Excessive vibration condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&lt;br /&gt;
Threshold crossed.&lt;br /&gt;
Alert generated.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demonstration of Data Minimization ==&lt;br /&gt;
&lt;br /&gt;
The main purpose of this experiment is to demonstrate that unnecessary raw sensor information does not need to be continuously transmitted.&lt;br /&gt;
&lt;br /&gt;
=== Conventional System ===&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, every sensor event or sensor reading could be transmitted to a server.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The server would receive a continuous stream of sensor information.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design System ===&lt;br /&gt;
&lt;br /&gt;
In the proposed system, the ESP32 processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
The ESP32 counts the vibration events and compares the count with the threshold.&lt;br /&gt;
&lt;br /&gt;
The process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count events&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +---------------------+&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
Below threshold        Threshold reached&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is not required outside the ESP32 for the basic application.&lt;br /&gt;
&lt;br /&gt;
Only the required alert needs to be exposed.&lt;br /&gt;
&lt;br /&gt;
== Data Inspection Demonstration ==&lt;br /&gt;
&lt;br /&gt;
The data inspection demonstration is used to compare the amount of information exposed by two system designs.&lt;br /&gt;
&lt;br /&gt;
The demonstration is educational and is intended to show the effect of data minimization.&lt;br /&gt;
&lt;br /&gt;
=== Conventional Design ===&lt;br /&gt;
&lt;br /&gt;
A conventional system may continuously expose individual vibration events:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An observer can therefore obtain detailed information about the vibration activity.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design Design ===&lt;br /&gt;
&lt;br /&gt;
The Privacy-by-Design system processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
When the vibration count is below the threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
No alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the threshold is reached:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application therefore exposes only the information required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
=== Demonstration Steps ===&lt;br /&gt;
&lt;br /&gt;
# Connect the smartphone to the ESP32 Access Point.&lt;br /&gt;
# Open the ESP32 web page.&lt;br /&gt;
# Observe the NORMAL condition.&lt;br /&gt;
# Tap or shake the vibration sensor repeatedly.&lt;br /&gt;
# Generate enough vibration events to cross the threshold.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Inspect the application data using an appropriate network inspection or server logging method.&lt;br /&gt;
# Observe that the application does not need to continuously expose every vibration event.&lt;br /&gt;
# Explain that the ESP32 processes the vibration activity locally before generating the alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This demonstration is about data minimization. It does not claim that HTTP communication is encrypted or completely secure.&lt;br /&gt;
&lt;br /&gt;
== Conventional System vs Privacy-by-Design System ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Feature&lt;br /&gt;
! Conventional System&lt;br /&gt;
! Privacy-by-Design System&lt;br /&gt;
|-&lt;br /&gt;
| Sensor processing&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed locally on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Vibration events&lt;br /&gt;
| May be continuously transmitted&lt;br /&gt;
| Processed locally&lt;br /&gt;
|-&lt;br /&gt;
| Normal activity&lt;br /&gt;
| May be transmitted&lt;br /&gt;
| No unnecessary transmission&lt;br /&gt;
|-&lt;br /&gt;
| Threshold detection&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Alert&lt;br /&gt;
| May contain detailed sensor information&lt;br /&gt;
| Only required alert is exposed&lt;br /&gt;
|-&lt;br /&gt;
| Data volume&lt;br /&gt;
| Higher&lt;br /&gt;
| Lower&lt;br /&gt;
|-&lt;br /&gt;
| Data exposure&lt;br /&gt;
| Higher&lt;br /&gt;
| Minimized&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Why This is Privacy-by-Design ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates Privacy-by-Design through the following design decisions:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local Processing:&#039;&#039;&#039; Vibration activity is processed on the ESP32.&lt;br /&gt;
# &#039;&#039;&#039;Data Minimization:&#039;&#039;&#039; Individual vibration events do not need to be continuously transmitted.&lt;br /&gt;
# &#039;&#039;&#039;Purpose Limitation:&#039;&#039;&#039; The system only needs to detect excessive vibration.&lt;br /&gt;
# &#039;&#039;&#039;Smart Thresholding:&#039;&#039;&#039; An alert is generated only when the vibration threshold is crossed.&lt;br /&gt;
# &#039;&#039;&#039;Reduced Data Exposure:&#039;&#039;&#039; Unnecessary sensor information is not exposed.&lt;br /&gt;
# &#039;&#039;&#039;Privacy by Default:&#039;&#039;&#039; The system is designed to minimize data exposure from the beginning.&lt;br /&gt;
&lt;br /&gt;
The main principle demonstrated is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Do not transmit unnecessary information&lt;br /&gt;
when the application does not require it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Automatic Page Refresh ==&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
This is implemented using the page refresh setting in the generated web page.&lt;br /&gt;
&lt;br /&gt;
The refresh interval allows the student to observe the latest vibration status without manually refreshing the browser.&lt;br /&gt;
&lt;br /&gt;
The refresh interval is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
5 seconds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Therefore, after generating vibration activity, the student can wait for the next page refresh to observe the updated alert status.&lt;br /&gt;
&lt;br /&gt;
== Advantages ==&lt;br /&gt;
&lt;br /&gt;
# Reduces unnecessary sensor data transmission.&lt;br /&gt;
# Processes vibration information locally.&lt;br /&gt;
# Reduces the amount of sensor information exposed outside the device.&lt;br /&gt;
# Allows fast local decision making.&lt;br /&gt;
# Demonstrates data minimization clearly.&lt;br /&gt;
# Does not require an external cloud server.&lt;br /&gt;
# Can be demonstrated easily using a smartphone.&lt;br /&gt;
# Vibration can be generated manually by tapping or shaking the sensor.&lt;br /&gt;
# The web page automatically refreshes every 5 seconds.&lt;br /&gt;
# Can be extended to industrial machine monitoring applications.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
# The vibration sensor module provides a simple indication of vibration and may not provide precise vibration measurements.&lt;br /&gt;
# The sensor may respond differently depending on the strength and duration of vibration.&lt;br /&gt;
# The threshold must be calibrated for the actual sensor and application.&lt;br /&gt;
# Environmental vibration may cause unwanted detections.&lt;br /&gt;
# The HTTP communication used in this experiment is not encrypted.&lt;br /&gt;
# This experiment demonstrates data minimization and not complete IoT security.&lt;br /&gt;
# A real industrial vibration monitoring system would normally use a more precise vibration sensor and appropriate signal processing.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The smart threshold alert system was successfully implemented using a vibration sensor and ESP32.&lt;br /&gt;
&lt;br /&gt;
The ESP32 locally monitored vibration activity and counted vibration events during a predefined monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the number of vibration events reached the selected threshold, the system generated an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The alert was displayed on a smartphone through the ESP32 web server using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshed every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrated that raw vibration activity does not need to be continuously exposed when the application only requires an excessive-vibration alert.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated data minimization through local processing and smart threshold alerts as a practical Privacy-by-Design approach.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is Privacy-by-Design?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Privacy-by-Design means incorporating privacy considerations into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. What is data minimization?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Data minimization means collecting, processing, transmitting, and storing only the data required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. Why is a vibration sensor used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A vibration sensor is used because vibration can be generated manually by tapping or shaking the sensor, making the alert easy to demonstrate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What does excessive vibration represent in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Excessive vibration represents a condition in which the number of vibration events has crossed the predefined threshold.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. Why is the raw vibration activity not continuously transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The application only needs to know whether excessive vibration has occurred. Therefore, continuously transmitting every vibration event is unnecessary.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. Where is the vibration threshold checked?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The threshold is checked locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What happens when the threshold is not crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No excessive-vibration alert is generated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What happens when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The ESP32 detects excessive vibration and generates the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is the purpose of the data inspection demonstration?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; It demonstrates how data minimization reduces the amount of unnecessary sensor information exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What information is required when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The required information is the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why does the web page refresh every 5 seconds?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The page refreshes every 5 seconds so that the smartphone can display the latest system status automatically.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Is the system completely secure?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. The main purpose is to demonstrate data minimization and Privacy-by-Design. The HTTP communication used here is not encrypted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. Does data minimization mean that no data is transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. It means that only the data necessary for the intended purpose should be transmitted or exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. Why is local processing useful?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Local processing allows the ESP32 to make decisions using sensor data without unnecessarily exposing the raw sensor activity.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. What is a smart threshold alert?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A smart threshold alert is generated when sensor activity crosses a predefined threshold representing a meaningful condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q16. What is the main principle demonstrated by this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The main principle is data minimization. Sensor activity is processed locally and only the required alert is exposed.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1387</id>
		<title>MDM331AID/Experiment 14</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1387"/>
		<updated>2026-10-08T03:32:37Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Smart Threshold Alerts for Data Minimization using Privacy-by-Design =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To design and implement a Privacy-by-Design IoT system using a vibration sensor and ESP32 that detects excessive vibration using a predefined threshold and generates an alert only when the threshold condition is reached, thereby minimizing unnecessary sensor data transmission.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
# To understand Privacy-by-Design in an IoT system.&lt;br /&gt;
# To understand the concept of data minimization.&lt;br /&gt;
# To interface a vibration sensor with ESP32.&lt;br /&gt;
# To detect vibration activity using the sensor.&lt;br /&gt;
# To define a threshold for excessive vibration.&lt;br /&gt;
# To generate an EXCESSIVE VIBRATION alert when the threshold is crossed.&lt;br /&gt;
# To process vibration data locally on the ESP32.&lt;br /&gt;
# To avoid continuously transmitting raw vibration readings.&lt;br /&gt;
# To expose only the required alert information.&lt;br /&gt;
# To demonstrate data minimization through a simple web-based monitoring system.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| Reads the vibration sensor and hosts the web server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Vibration Sensor Module&lt;br /&gt;
| 1&lt;br /&gt;
| Detects vibration activity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Breadboard&lt;br /&gt;
| 1&lt;br /&gt;
| Circuit connections&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| Accesses the ESP32 web page&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and powering ESP32&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| Programming the ESP32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things ===&lt;br /&gt;
&lt;br /&gt;
The Internet of Things, or IoT, is a system in which physical devices use sensors and communication technologies to collect and exchange information.&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, sensor readings may be continuously transmitted even when the application does not require all of the readings.&lt;br /&gt;
&lt;br /&gt;
For example, a vibration monitoring system may continuously generate sensor readings.&lt;br /&gt;
&lt;br /&gt;
If the purpose of the application is only to detect excessive vibration, the application does not necessarily need every individual sensor reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 can instead process the vibration activity locally and generate an alert only when the required condition occurs.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design ===&lt;br /&gt;
&lt;br /&gt;
Privacy-by-Design means that privacy considerations are incorporated into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
One important approach related to Privacy-by-Design is data minimization.&lt;br /&gt;
&lt;br /&gt;
Data minimization means collecting, processing, transmitting, and storing only the information that is necessary for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the purpose is to detect excessive vibration.&lt;br /&gt;
&lt;br /&gt;
Therefore, the system does not need to continuously expose every raw vibration reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 processes the vibration activity locally and generates an alert only when the predefined threshold condition is reached.&lt;br /&gt;
&lt;br /&gt;
=== Smart Threshold Alert ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to determine when a particular condition has occurred.&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor and keeps track of vibration activity.&lt;br /&gt;
&lt;br /&gt;
When the number of detected vibration events reaches the selected threshold within the monitoring period, the ESP32 considers the vibration level excessive.&lt;br /&gt;
&lt;br /&gt;
The operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
     ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Monitor vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Normal vibration       Excessive vibration&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The threshold can be adjusted according to the sensor and the required application.&lt;br /&gt;
&lt;br /&gt;
=== Data Minimization ===&lt;br /&gt;
&lt;br /&gt;
In a conventional system, raw vibration readings may be continuously sent to another device or server.&lt;br /&gt;
&lt;br /&gt;
In the proposed system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration Sensor&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing on ESP32&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +----------------------+&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
Below threshold         Threshold reached&lt;br /&gt;
       |                      |&lt;br /&gt;
       v                      v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally for decision making.&lt;br /&gt;
&lt;br /&gt;
Unnecessary continuous sensor data is therefore not exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
== Sensor Connection ==&lt;br /&gt;
&lt;br /&gt;
The vibration sensor module normally provides VCC, GND, and a digital output pin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Vibration Sensor Pin&lt;br /&gt;
! ESP32&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| DO or OUT&lt;br /&gt;
| GPIO 27&lt;br /&gt;
| Digital vibration signal&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The exact pin names may vary between vibration sensor modules. Verify the labels on the actual sensor before making the connections.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             Vibration Sensor&lt;br /&gt;
             +-------------+&lt;br /&gt;
             |             |&lt;br /&gt;
     3.3V ---| VCC         |&lt;br /&gt;
             |             |&lt;br /&gt;
 GPIO 27 &amp;amp;lt;---| DO / OUT    |&lt;br /&gt;
             |             |&lt;br /&gt;
     GND ----| GND         |&lt;br /&gt;
             +-------------+&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
                  ESP32&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Wi-Fi Access Point&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Smartphone Browser&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
              192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Working Principle ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 works as a Wi-Fi Access Point and hosts a simple web server.&lt;br /&gt;
&lt;br /&gt;
The smartphone connects directly to the Wi-Fi network created by the ESP32.&lt;br /&gt;
&lt;br /&gt;
The student then opens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 monitors the vibration sensor.&lt;br /&gt;
&lt;br /&gt;
Each detected vibration event increases the vibration count during the monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the vibration count reaches the predefined threshold, the ESP32 generates an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The web page displays the current status.&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds so that the latest status can be observed.&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is processed locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WiFi.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WebServer.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
const int VIBRATION_PIN = 27;&lt;br /&gt;
&lt;br /&gt;
const char* ap_ssid = &amp;quot;ESP32-Vibration-Monitor&amp;quot;;&lt;br /&gt;
const char* ap_password = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Number of vibration events required&lt;br /&gt;
   to generate an alert.&lt;br /&gt;
*/&lt;br /&gt;
const int VIBRATION_THRESHOLD = 5;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Monitoring period in milliseconds.&lt;br /&gt;
*/&lt;br /&gt;
const unsigned long MONITOR_PERIOD = 10000;&lt;br /&gt;
&lt;br /&gt;
int vibrationCount = 0;&lt;br /&gt;
bool excessiveVibration = false;&lt;br /&gt;
&lt;br /&gt;
unsigned long periodStart = 0;&lt;br /&gt;
&lt;br /&gt;
int lastSensorState = LOW;&lt;br /&gt;
&lt;br /&gt;
void updateVibration()&lt;br /&gt;
{&lt;br /&gt;
  int sensorState = digitalRead(VIBRATION_PIN);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Count a vibration when the sensor&lt;br /&gt;
     changes from LOW to HIGH.&lt;br /&gt;
  */&lt;br /&gt;
  if (sensorState == HIGH &amp;amp;&amp;amp; lastSensorState == LOW)&lt;br /&gt;
  {&lt;br /&gt;
    vibrationCount++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  lastSensorState = sensorState;&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether the monitoring period&lt;br /&gt;
     has ended.&lt;br /&gt;
  */&lt;br /&gt;
  if (millis() - periodStart &amp;gt;= MONITOR_PERIOD)&lt;br /&gt;
  {&lt;br /&gt;
    if (vibrationCount &amp;gt;= VIBRATION_THRESHOLD)&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration = true;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      excessiveVibration = false;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /*&lt;br /&gt;
       Start a new monitoring period.&lt;br /&gt;
    */&lt;br /&gt;
    vibrationCount = 0;&lt;br /&gt;
    periodStart = millis();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
&lt;br /&gt;
  String page = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  char lt = 60;&lt;br /&gt;
  char gt = 62;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;html&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;head&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1&#039;&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;meta http-equiv=&#039;refresh&#039; content=&#039;5&#039;&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;title&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
  page += &amp;quot;Vibration Monitor&amp;quot;;&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/title&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/head&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;body&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;h1&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
  page += &amp;quot;Smart Vibration Monitor&amp;quot;;&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/h1&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  if (excessiveVibration)&lt;br /&gt;
  {&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;EXCESSIVE VIBRATION&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;Threshold crossed. Alert generated.&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;NORMAL&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;Vibration level is within the normal range.&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;p&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
  page += &amp;quot;Page refreshes every 5 seconds.&amp;quot;;&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/p&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/body&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/html&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  pinMode(VIBRATION_PIN, INPUT);&lt;br /&gt;
&lt;br /&gt;
  periodStart = millis();&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAPConfig(&lt;br /&gt;
    IPAddress(192,168,1,4),&lt;br /&gt;
    IPAddress(192,168,1,1),&lt;br /&gt;
    IPAddress(255,255,255,0)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(ap_ssid, ap_password);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Access Point started&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.softAPIP());&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  updateVibration();&lt;br /&gt;
&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code or Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.h&lt;br /&gt;
| Provides ESP32 Wi-Fi functionality.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer.h&lt;br /&gt;
| Provides web server functionality.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_PIN&lt;br /&gt;
| Defines GPIO 27 as the vibration sensor input.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAP&lt;br /&gt;
| Creates a Wi-Fi Access Point using the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAPConfig&lt;br /&gt;
| Sets the Access Point IP address to 192.168.1.4.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer server(80)&lt;br /&gt;
| Creates an HTTP web server on port 80.&lt;br /&gt;
|-&lt;br /&gt;
| VIBRATION_THRESHOLD&lt;br /&gt;
| Defines the number of vibration events required to generate an alert.&lt;br /&gt;
|-&lt;br /&gt;
| MONITOR_PERIOD&lt;br /&gt;
| Defines the time interval over which vibration events are counted.&lt;br /&gt;
|-&lt;br /&gt;
| vibrationCount&lt;br /&gt;
| Stores the number of detected vibration events.&lt;br /&gt;
|-&lt;br /&gt;
| excessiveVibration&lt;br /&gt;
| Stores whether the excessive-vibration condition has been detected.&lt;br /&gt;
|-&lt;br /&gt;
| digitalRead&lt;br /&gt;
| Reads the digital output of the vibration sensor.&lt;br /&gt;
|-&lt;br /&gt;
| updateVibration&lt;br /&gt;
| Detects vibration events and checks the threshold.&lt;br /&gt;
|-&lt;br /&gt;
| handleRoot&lt;br /&gt;
| Generates the web page displayed on the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| server.send&lt;br /&gt;
| Sends the web page to the browser.&lt;br /&gt;
|-&lt;br /&gt;
| server.handleClient&lt;br /&gt;
| Processes browser requests.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Access Point ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 creates its own Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
The network name is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Vibration-Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP address is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The smartphone can therefore access the web page using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vibration Detection ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the digital output of the vibration sensor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int sensorState = digitalRead(VIBRATION_PIN);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When a vibration event causes the sensor output to change from LOW to HIGH, the vibration count is increased.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (sensorState == HIGH &amp;amp;&amp;amp; lastSensorState == LOW)&lt;br /&gt;
{&lt;br /&gt;
  vibrationCount++;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows the ESP32 to count vibration events locally.&lt;br /&gt;
&lt;br /&gt;
=== Threshold Detection ===&lt;br /&gt;
&lt;br /&gt;
The program uses a vibration threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int VIBRATION_THRESHOLD = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The monitoring period is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const unsigned long MONITOR_PERIOD = 10000;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that the ESP32 counts vibration events during a 10 second period.&lt;br /&gt;
&lt;br /&gt;
If the number of detected events is 5 or more, the system generates the excessive vibration alert.&lt;br /&gt;
&lt;br /&gt;
The threshold can be changed depending on the sensor and demonstration requirements.&lt;br /&gt;
&lt;br /&gt;
== Calibration of Vibration Threshold ==&lt;br /&gt;
&lt;br /&gt;
The threshold should be tested before performing the main experiment.&lt;br /&gt;
&lt;br /&gt;
# Upload the program to the ESP32.&lt;br /&gt;
# Open the Arduino IDE Serial Monitor.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Observe the system under normal conditions.&lt;br /&gt;
# Tap or shake the vibration sensor several times.&lt;br /&gt;
# Observe how the sensor responds.&lt;br /&gt;
# Select a suitable vibration threshold.&lt;br /&gt;
# Change the VIBRATION_THRESHOLD value if required.&lt;br /&gt;
# Upload the program again.&lt;br /&gt;
# Verify that normal vibration does not unnecessarily generate an alert.&lt;br /&gt;
# Verify that repeated vibration generates the alert.&lt;br /&gt;
&lt;br /&gt;
For a simple classroom demonstration, the threshold can be kept low so that students can easily trigger the alert by tapping or shaking the sensor.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the vibration sensor to the ESP32.&lt;br /&gt;
# Connect VCC to 3.3V.&lt;br /&gt;
# Connect GND to GND.&lt;br /&gt;
# Connect the digital output of the vibration sensor to GPIO 27.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Select the appropriate ESP32 board.&lt;br /&gt;
# Select the appropriate COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor.&lt;br /&gt;
# Verify that the ESP32 Access Point has started.&lt;br /&gt;
# Connect the smartphone to ESP32-Vibration-Monitor.&lt;br /&gt;
# Open the smartphone browser.&lt;br /&gt;
# Enter http://192.168.1.4.&lt;br /&gt;
# Observe the NORMAL status.&lt;br /&gt;
# Keep the vibration sensor stationary.&lt;br /&gt;
# Tap or shake the sensor repeatedly.&lt;br /&gt;
# Generate several vibration events within the monitoring period.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Wait for the next monitoring period and observe the status.&lt;br /&gt;
# Verify that the web page refreshes automatically every 5 seconds.&lt;br /&gt;
# Perform the data minimization demonstration.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Normal Condition ===&lt;br /&gt;
&lt;br /&gt;
When the vibration sensor is stationary or experiences only minor vibration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Normal&lt;br /&gt;
System Status    : NORMAL&lt;br /&gt;
Alert            : None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The system does not generate an alert.&lt;br /&gt;
&lt;br /&gt;
=== Excessive Vibration Condition ===&lt;br /&gt;
&lt;br /&gt;
When repeated vibration events cross the predefined threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Condition : Excessive vibration&lt;br /&gt;
System Status    : ALERT&lt;br /&gt;
Alert            : EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 generates the alert locally.&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Output ===&lt;br /&gt;
&lt;br /&gt;
Normal condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
NORMAL&lt;br /&gt;
&lt;br /&gt;
Vibration level is within&lt;br /&gt;
the normal range.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Excessive vibration condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART VIBRATION MONITOR&lt;br /&gt;
&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&lt;br /&gt;
Threshold crossed.&lt;br /&gt;
Alert generated.&lt;br /&gt;
&lt;br /&gt;
Page refreshes every 5 seconds.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demonstration of Data Minimization ==&lt;br /&gt;
&lt;br /&gt;
The main purpose of this experiment is to demonstrate that unnecessary raw sensor information does not need to be continuously transmitted.&lt;br /&gt;
&lt;br /&gt;
=== Conventional System ===&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, every sensor event or sensor reading could be transmitted to a server.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
Vibration event detected&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The server would receive a continuous stream of sensor information.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design System ===&lt;br /&gt;
&lt;br /&gt;
In the proposed system, the ESP32 processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
The ESP32 counts the vibration events and compares the count with the threshold.&lt;br /&gt;
&lt;br /&gt;
The process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration activity&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Local processing&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Count events&lt;br /&gt;
       |&lt;br /&gt;
       v&lt;br /&gt;
Check threshold&lt;br /&gt;
       |&lt;br /&gt;
       +---------------------+&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
Below threshold        Threshold reached&lt;br /&gt;
       |                     |&lt;br /&gt;
       v                     v&lt;br /&gt;
   No alert          EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw vibration activity is not required outside the ESP32 for the basic application.&lt;br /&gt;
&lt;br /&gt;
Only the required alert needs to be exposed.&lt;br /&gt;
&lt;br /&gt;
== Data Inspection Demonstration ==&lt;br /&gt;
&lt;br /&gt;
The data inspection demonstration is used to compare the amount of information exposed by two system designs.&lt;br /&gt;
&lt;br /&gt;
The demonstration is educational and is intended to show the effect of data minimization.&lt;br /&gt;
&lt;br /&gt;
=== Conventional Design ===&lt;br /&gt;
&lt;br /&gt;
A conventional system may continuously expose individual vibration events:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
Vibration event&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An observer can therefore obtain detailed information about the vibration activity.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design Design ===&lt;br /&gt;
&lt;br /&gt;
The Privacy-by-Design system processes the vibration activity locally.&lt;br /&gt;
&lt;br /&gt;
When the vibration count is below the threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
No alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the threshold is reached:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
EXCESSIVE VIBRATION&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application therefore exposes only the information required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
=== Demonstration Steps ===&lt;br /&gt;
&lt;br /&gt;
# Connect the smartphone to the ESP32 Access Point.&lt;br /&gt;
# Open the ESP32 web page.&lt;br /&gt;
# Observe the NORMAL condition.&lt;br /&gt;
# Tap or shake the vibration sensor repeatedly.&lt;br /&gt;
# Generate enough vibration events to cross the threshold.&lt;br /&gt;
# Observe the EXCESSIVE VIBRATION alert.&lt;br /&gt;
# Inspect the application data using an appropriate network inspection or server logging method.&lt;br /&gt;
# Observe that the application does not need to continuously expose every vibration event.&lt;br /&gt;
# Explain that the ESP32 processes the vibration activity locally before generating the alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This demonstration is about data minimization. It does not claim that HTTP communication is encrypted or completely secure.&lt;br /&gt;
&lt;br /&gt;
== Conventional System vs Privacy-by-Design System ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Feature&lt;br /&gt;
! Conventional System&lt;br /&gt;
! Privacy-by-Design System&lt;br /&gt;
|-&lt;br /&gt;
| Sensor processing&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed locally on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Vibration events&lt;br /&gt;
| May be continuously transmitted&lt;br /&gt;
| Processed locally&lt;br /&gt;
|-&lt;br /&gt;
| Normal activity&lt;br /&gt;
| May be transmitted&lt;br /&gt;
| No unnecessary transmission&lt;br /&gt;
|-&lt;br /&gt;
| Threshold detection&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Alert&lt;br /&gt;
| May contain detailed sensor information&lt;br /&gt;
| Only required alert is exposed&lt;br /&gt;
|-&lt;br /&gt;
| Data volume&lt;br /&gt;
| Higher&lt;br /&gt;
| Lower&lt;br /&gt;
|-&lt;br /&gt;
| Data exposure&lt;br /&gt;
| Higher&lt;br /&gt;
| Minimized&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Why This is Privacy-by-Design ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates Privacy-by-Design through the following design decisions:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local Processing:&#039;&#039;&#039; Vibration activity is processed on the ESP32.&lt;br /&gt;
# &#039;&#039;&#039;Data Minimization:&#039;&#039;&#039; Individual vibration events do not need to be continuously transmitted.&lt;br /&gt;
# &#039;&#039;&#039;Purpose Limitation:&#039;&#039;&#039; The system only needs to detect excessive vibration.&lt;br /&gt;
# &#039;&#039;&#039;Smart Thresholding:&#039;&#039;&#039; An alert is generated only when the vibration threshold is crossed.&lt;br /&gt;
# &#039;&#039;&#039;Reduced Data Exposure:&#039;&#039;&#039; Unnecessary sensor information is not exposed.&lt;br /&gt;
# &#039;&#039;&#039;Privacy by Default:&#039;&#039;&#039; The system is designed to minimize data exposure from the beginning.&lt;br /&gt;
&lt;br /&gt;
The main principle demonstrated is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Do not transmit unnecessary information&lt;br /&gt;
when the application does not require it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Automatic Page Refresh ==&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshes every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
This is implemented using the page refresh setting in the generated web page.&lt;br /&gt;
&lt;br /&gt;
The refresh interval allows the student to observe the latest vibration status without manually refreshing the browser.&lt;br /&gt;
&lt;br /&gt;
The refresh interval is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
5 seconds&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Therefore, after generating vibration activity, the student can wait for the next page refresh to observe the updated alert status.&lt;br /&gt;
&lt;br /&gt;
== Advantages ==&lt;br /&gt;
&lt;br /&gt;
# Reduces unnecessary sensor data transmission.&lt;br /&gt;
# Processes vibration information locally.&lt;br /&gt;
# Reduces the amount of sensor information exposed outside the device.&lt;br /&gt;
# Allows fast local decision making.&lt;br /&gt;
# Demonstrates data minimization clearly.&lt;br /&gt;
# Does not require an external cloud server.&lt;br /&gt;
# Can be demonstrated easily using a smartphone.&lt;br /&gt;
# Vibration can be generated manually by tapping or shaking the sensor.&lt;br /&gt;
# The web page automatically refreshes every 5 seconds.&lt;br /&gt;
# Can be extended to industrial machine monitoring applications.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
# The vibration sensor module provides a simple indication of vibration and may not provide precise vibration measurements.&lt;br /&gt;
# The sensor may respond differently depending on the strength and duration of vibration.&lt;br /&gt;
# The threshold must be calibrated for the actual sensor and application.&lt;br /&gt;
# Environmental vibration may cause unwanted detections.&lt;br /&gt;
# The HTTP communication used in this experiment is not encrypted.&lt;br /&gt;
# This experiment demonstrates data minimization and not complete IoT security.&lt;br /&gt;
# A real industrial vibration monitoring system would normally use a more precise vibration sensor and appropriate signal processing.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The smart threshold alert system was successfully implemented using a vibration sensor and ESP32.&lt;br /&gt;
&lt;br /&gt;
The ESP32 locally monitored vibration activity and counted vibration events during a predefined monitoring period.&lt;br /&gt;
&lt;br /&gt;
When the number of vibration events reached the selected threshold, the system generated an EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
The alert was displayed on a smartphone through the ESP32 web server using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The web page automatically refreshed every 5 seconds.&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrated that raw vibration activity does not need to be continuously exposed when the application only requires an excessive-vibration alert.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated data minimization through local processing and smart threshold alerts as a practical Privacy-by-Design approach.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is Privacy-by-Design?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Privacy-by-Design means incorporating privacy considerations into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. What is data minimization?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Data minimization means collecting, processing, transmitting, and storing only the data required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. Why is a vibration sensor used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A vibration sensor is used because vibration can be generated manually by tapping or shaking the sensor, making the alert easy to demonstrate.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What does excessive vibration represent in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Excessive vibration represents a condition in which the number of vibration events has crossed the predefined threshold.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. Why is the raw vibration activity not continuously transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The application only needs to know whether excessive vibration has occurred. Therefore, continuously transmitting every vibration event is unnecessary.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. Where is the vibration threshold checked?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The threshold is checked locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What happens when the threshold is not crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No excessive-vibration alert is generated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What happens when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The ESP32 detects excessive vibration and generates the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is the purpose of the data inspection demonstration?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; It demonstrates how data minimization reduces the amount of unnecessary sensor information exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What information is required when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The required information is the EXCESSIVE VIBRATION alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why does the web page refresh every 5 seconds?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The page refreshes every 5 seconds so that the smartphone can display the latest system status automatically.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Is the system completely secure?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. The main purpose is to demonstrate data minimization and Privacy-by-Design. The HTTP communication used here is not encrypted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. Does data minimization mean that no data is transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. It means that only the data necessary for the intended purpose should be transmitted or exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. Why is local processing useful?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Local processing allows the ESP32 to make decisions using sensor data without unnecessarily exposing the raw sensor activity.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. What is a smart threshold alert?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A smart threshold alert is generated when sensor activity crosses a predefined threshold representing a meaningful condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q16. What is the main principle demonstrated by this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The main principle is data minimization. Sensor activity is processed locally and only the required alert is exposed.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1386</id>
		<title>AIDS IoT Kits User Manuals</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1386"/>
		<updated>2026-10-08T03:20:42Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Laboratory Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sppu-logo.jpg|200px|SPPU Logo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:200%; font-weight:bold;&amp;quot;&amp;gt;TE AIDS MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:120%;&amp;quot;&amp;gt;Cognifront IoT Kit for MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About the Laboratory ==&lt;br /&gt;
&lt;br /&gt;
The Internet of Things (IoT) laboratory provides hands-on experience in connecting physical devices, sensors, microcontrollers and cloud platforms to develop intelligent, connected systems.&lt;br /&gt;
&lt;br /&gt;
This laboratory manual is designed for students of Third Year B.E. Artificial Intelligence and Data Science Engineering, covering fundamental IoT concepts, embedded programming, sensor interfacing, network communication and cloud-based applications.&lt;br /&gt;
&lt;br /&gt;
== Laboratory Objectives ==&lt;br /&gt;
&lt;br /&gt;
* Understand the architecture and fundamental concepts of the Internet of Things.&lt;br /&gt;
* Interface sensors and actuators with embedded development boards.&lt;br /&gt;
* Develop programs for acquiring and processing sensor data.&lt;br /&gt;
* Implement communication protocols used in IoT systems.&lt;br /&gt;
* Connect IoT devices with cloud platforms for data visualization and monitoring.&lt;br /&gt;
* Design and implement real-world IoT applications.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #&lt;br /&gt;
! Experiment Title&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part A&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| [[MDM331AID/Experiment 1|Develop an application for the connectivity of the Arduino UNO/Raspberry Pi circuit with sensors.]]&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[MDM331AID/Experiment 2|Implement an application to detect obstacles and notify users using LEDs to understand the connectivity of Raspberry Pi / Arduino with IR sensor.]]&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| [[MDM331AID/Experiment 3|Implement a simple IoT application using an Arduino board to control an LED through GPIO pins in order to understand the physical design of IoT devices and device actuation.]]&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| [[MDM331AID/Experiment 4|Develop a program to detect gas leakage in the surrounding environment.]]&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| [[MDM331AID/Experiment 5|Configure and implement an IoT device (Arduino UNO/ESP module/Raspberry Pi) to connect to a Wi-Fi network and transmit sensor data to a remote computer using TCP/IP communication.]]&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| [[MDM331AID/Experiment 6|Implement an edge computing model where sensor data is processed locally on an edge device (Raspberry Pi) before being transmitted to the cloud to reduce latency and bandwidth usage.]]&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[MDM331AID/Experiment 7|Design an RFID-based identification system that reads tag information and displays the ID on a monitoring system to demonstrate short-range communication technologies in IoT.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part B&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| [[MDM331AID/Experiment 8|Develop an IoT application that uses a communication protocol to transmit sensor data between an IoT device and a server.]]&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| [[MDM331AID/Experiment 9|Perform data cleaning, normalization, and visualization on an IoT sensor dataset (any dataset can be considered).]]&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| [[MDM331AID/Experiment 10|Implement an IoT application to collect real-time temperature data using an IoT sensor and apply a machine learning model to predict future temperature values (any machine learning model).]]&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| [[MDM331AID/Experiment 11|Design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts (any security algorithm can be used).]]&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| [[MDM331AID/Experiment 12|Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
| 12/1&lt;br /&gt;
| [[MDM331AID/Experiment 12_BLE|(BLE)Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/2&lt;br /&gt;
| [[MDM331AID/Experiment 12_ESPNOW|(ESPNOW) Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
| 13&lt;br /&gt;
| [[MDM331AID/Experiment 13|Develop and implement a machine learning model to perform classification (e.g., activity recognition or device state detection) and anomaly detection (e.g., fault detection in industrial IoT sensors).]]&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| [[MDM331AID/Experiment 14|Case study for data minimization using smart threshold alerts by providing Privacy-by-Design.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part C&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| [[MDM331AID/Experiment 15|Develop a Privacy-Aware Intelligent Smart IoT Application: Design and implementation of an AIoT-based smart sensor system with cloud-based data preprocessing and intelligent decision-making using machine learning techniques, incorporating secure communication protocols with built-in security and privacy mechanisms, with complete deliverables including a working demonstration and technical report.]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12&amp;diff=1385</id>
		<title>MDM331AID/Experiment 12</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12&amp;diff=1385"/>
		<updated>2026-10-08T03:20:11Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To configure the ESP32 as a BLE server.&lt;br /&gt;
* To transmit real-time sensor data from the ESP32 to a smartphone using BLE.&lt;br /&gt;
* To understand BLE services and characteristics.&lt;br /&gt;
* To implement BLE pairing and authentication using a passkey.&lt;br /&gt;
* To understand how BLE encryption protects transmitted sensor data.&lt;br /&gt;
* To verify secure sensor-data communication using a smartphone BLE application.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| IoT controller and BLE server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and power supply&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| BLE client for receiving sensor data&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| LightBlue® BLE Application&lt;br /&gt;
| 1&lt;br /&gt;
| Scanning, connecting and monitoring BLE data&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Application ===&lt;br /&gt;
&lt;br /&gt;
The recommended application for this experiment is **LightBlue® by Punch Through**.&lt;br /&gt;
&lt;br /&gt;
LightBlue is a BLE debugging and development application that is available for both Android and iOS. It can scan for BLE peripherals, connect to them, display their services and characteristics, and read or subscribe to characteristic values.&lt;br /&gt;
&lt;br /&gt;
The application can be installed from:&lt;br /&gt;
&lt;br /&gt;
* Android: [LightBlue® on Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
* iPhone/iPad: [LightBlue® on the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth Low Energy ===&lt;br /&gt;
&lt;br /&gt;
Bluetooth Low Energy (BLE) is a wireless communication technology designed for low-power communication between devices. It is widely used in IoT sensors, wearable devices, smart-home devices and other embedded systems.&lt;br /&gt;
&lt;br /&gt;
An ESP32 can operate as a BLE device and communicate with smartphones and other BLE-enabled devices. The Arduino ESP32 framework provides a BLE library for creating BLE servers, services and characteristics.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 operates as a &#039;&#039;&#039;BLE GATT server&#039;&#039;&#039;, while the smartphone operates as the &#039;&#039;&#039;BLE client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The communication structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     ↓&lt;br /&gt;
   ESP32&lt;br /&gt;
     ↓&lt;br /&gt;
 BLE GATT Server&lt;br /&gt;
     ↓&lt;br /&gt;
 Secure BLE Connection&lt;br /&gt;
     ↓&lt;br /&gt;
 Smartphone&lt;br /&gt;
     ↓&lt;br /&gt;
 LightBlue Application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BLE GATT ===&lt;br /&gt;
&lt;br /&gt;
BLE devices commonly organize application data using the Generic Attribute Profile (GATT).&lt;br /&gt;
&lt;br /&gt;
The main components used in this experiment are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Service:&#039;&#039;&#039;  &lt;br /&gt;
A service groups related functionality of a BLE device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Characteristic:&#039;&#039;&#039;  &lt;br /&gt;
A characteristic contains a particular piece of data that can be read, written or notified.&lt;br /&gt;
&lt;br /&gt;
For this experiment, one BLE service is created containing two characteristics:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Characteristic&lt;br /&gt;
! Data&lt;br /&gt;
! Operation&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature in °C&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity in %&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The smartphone can connect to the ESP32 and subscribe to notifications so that updated sensor values are received automatically.&lt;br /&gt;
&lt;br /&gt;
=== BLE Security ===&lt;br /&gt;
&lt;br /&gt;
BLE provides security mechanisms for authentication, pairing, bonding and encrypted communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, BLE security is configured using:&lt;br /&gt;
&lt;br /&gt;
* Pairing&lt;br /&gt;
* Bonding&lt;br /&gt;
* MITM (Man-in-the-Middle) protection&lt;br /&gt;
* Secure Connections&lt;br /&gt;
* Passkey authentication&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s ESP32 BLE security documentation supports authentication modes combining bonding, MITM protection and Secure Connections.&lt;br /&gt;
&lt;br /&gt;
=== Pairing ===&lt;br /&gt;
&lt;br /&gt;
Pairing is the process by which two Bluetooth devices establish the information required to create a trusted secure relationship.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the smartphone and ESP32 are paired using a passkey.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32&lt;br /&gt;
  ↓&lt;br /&gt;
BLE connection request&lt;br /&gt;
  ↓&lt;br /&gt;
Pairing request&lt;br /&gt;
  ↓&lt;br /&gt;
Passkey authentication&lt;br /&gt;
  ↓&lt;br /&gt;
Secure key establishment&lt;br /&gt;
  ↓&lt;br /&gt;
Encrypted BLE communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bonding ===&lt;br /&gt;
&lt;br /&gt;
Bonding allows the security information established during pairing to be stored so that the devices can recognize each other during future connections.&lt;br /&gt;
&lt;br /&gt;
Espressif distinguishes bonding from encryption: bonding stores long-term keys after successful encryption, while encryption protects the communication link.&lt;br /&gt;
&lt;br /&gt;
=== BLE Encryption ===&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE link can be encrypted.&lt;br /&gt;
&lt;br /&gt;
Therefore, the sensor data transmitted over the BLE connection is protected from simple interception of the communication.&lt;br /&gt;
&lt;br /&gt;
The security flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
    ↓&lt;br /&gt;
BLE Security / Pairing&lt;br /&gt;
    ↓&lt;br /&gt;
Authentication&lt;br /&gt;
    ↓&lt;br /&gt;
Encryption&lt;br /&gt;
    ↓&lt;br /&gt;
Secure BLE Transmission&lt;br /&gt;
    ↓&lt;br /&gt;
Smartphone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              +----------------+&lt;br /&gt;
              |     DHT11      |&lt;br /&gt;
              |                |&lt;br /&gt;
              | VCC  DATA  GND |&lt;br /&gt;
              +--+----+-----+--+&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                3.3V GPIO4 GND&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                 |    |     |&lt;br /&gt;
          +------+----+-----+------+&lt;br /&gt;
          |          ESP32         |&lt;br /&gt;
          |                        |&lt;br /&gt;
          |       BLE Server       |&lt;br /&gt;
          |          ))))          |&lt;br /&gt;
          +------------))----------+&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                Secure BLE Link&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                 +-----------+&lt;br /&gt;
                 | Smartphone|&lt;br /&gt;
                 |           |&lt;br /&gt;
                 | LightBlue |&lt;br /&gt;
                 +-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Arduino Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEDevice.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEUtils.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLESecurity.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define DEVICE_NAME &amp;quot;ESP32-Secure-Sensor&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define SERVICE_UUID \&lt;br /&gt;
&amp;quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define TEMP_UUID \&lt;br /&gt;
&amp;quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define HUMIDITY_UUID \&lt;br /&gt;
&amp;quot;cba1d466-344c-4be3-ab3f-189f80dd7518&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BLE_PASSKEY 123456&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
BLECharacteristic *temperatureCharacteristic;&lt;br /&gt;
BLECharacteristic *humidityCharacteristic;&lt;br /&gt;
&lt;br /&gt;
class SecurityCallbacks : public BLESecurityCallbacks&lt;br /&gt;
{&lt;br /&gt;
  uint32_t onPassKeyRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Passkey requested&amp;quot;);&lt;br /&gt;
    return BLE_PASSKEY;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onPassKeyNotify(uint32_t passkey)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Passkey: &amp;quot;);&lt;br /&gt;
    Serial.println(passkey);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onConfirmPIN(uint32_t pin)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Confirm PIN: &amp;quot;);&lt;br /&gt;
    Serial.println(pin);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onSecurityRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Security request received&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onAuthenticationComplete(esp_ble_auth_cmpl_t desc)&lt;br /&gt;
  {&lt;br /&gt;
    if (desc.success)&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication successful&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::init(DEVICE_NAME);&lt;br /&gt;
&lt;br /&gt;
  BLESecurity *security = new BLESecurity();&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setCapability(ESP_IO_CAP_OUT);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setAuthenticationMode(&lt;br /&gt;
    ESP_LE_AUTH_REQ_SC_MITM_BOND&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::setSecurityCallbacks(&lt;br /&gt;
    new SecurityCallbacks()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEServer *server = BLEDevice::createServer();&lt;br /&gt;
&lt;br /&gt;
  BLEService *service =&lt;br /&gt;
    server-&amp;gt;createService(SERVICE_UUID);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      TEMP_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      HUMIDITY_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  service-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
  BLEAdvertising *advertising =&lt;br /&gt;
    BLEDevice::getAdvertising();&lt;br /&gt;
&lt;br /&gt;
  advertising-&amp;gt;addServiceUUID(SERVICE_UUID);&lt;br /&gt;
  advertising-&amp;gt;setScanResponse(true);&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::startAdvertising();&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Secure BLE Sensor Started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Device Name: ESP32-Secure-Sensor&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Passkey: 123456&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Waiting for BLE connection...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  char temperatureValue[10];&lt;br /&gt;
  char humidityValue[10];&lt;br /&gt;
&lt;br /&gt;
  dtostrf(temperature, 1, 2, temperatureValue);&lt;br /&gt;
  dtostrf(humidity, 1, 2, humidityValue);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    temperatureValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    humidityValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;notify();&lt;br /&gt;
  humidityCharacteristic-&amp;gt;notify();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Sensor data sent using secure BLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;`&lt;br /&gt;
| Provides the main BLE device functionality.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEServer.h&amp;amp;gt;`&lt;br /&gt;
| Provides functionality for creating a BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;`&lt;br /&gt;
| Provides BLE pairing and security configuration.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;DHT.h&amp;amp;gt;`&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `DHTPIN 4`&lt;br /&gt;
| Defines GPIO 4 as the DHT11 data pin.&lt;br /&gt;
|-&lt;br /&gt;
| `DEVICE_NAME`&lt;br /&gt;
| Defines the name advertised by the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| `SERVICE_UUID`&lt;br /&gt;
| Uniquely identifies the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `TEMP_UUID`&lt;br /&gt;
| Identifies the temperature characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `HUMIDITY_UUID`&lt;br /&gt;
| Identifies the humidity characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `BLE_PASSKEY 123456`&lt;br /&gt;
| Defines the passkey used for BLE authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.begin()`&lt;br /&gt;
| Initializes the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `BLEDevice::init()`&lt;br /&gt;
| Initializes BLE and assigns the device name.&lt;br /&gt;
|-&lt;br /&gt;
| `setPassKey()`&lt;br /&gt;
| Configures the BLE passkey.&lt;br /&gt;
|-&lt;br /&gt;
| `setCapability()`&lt;br /&gt;
| Defines the input/output capability used during authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `setAuthenticationMode(true, true, true)`&lt;br /&gt;
| Enables bonding, MITM protection and Secure Connections.&lt;br /&gt;
|-&lt;br /&gt;
| `createServer()`&lt;br /&gt;
| Creates the ESP32 BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `createService()`&lt;br /&gt;
| Creates the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `createCharacteristic()`&lt;br /&gt;
| Creates temperature and humidity characteristics.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_READ`&lt;br /&gt;
| Allows the smartphone to read the sensor value.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_NOTIFY`&lt;br /&gt;
| Allows the ESP32 to send updated sensor values to the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| `service-&amp;gt;start()`&lt;br /&gt;
| Starts the BLE service.&lt;br /&gt;
|-&lt;br /&gt;
| `startAdvertising()`&lt;br /&gt;
| Makes the ESP32 discoverable by BLE clients.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `setValue()`&lt;br /&gt;
| Updates the BLE characteristic value.&lt;br /&gt;
|-&lt;br /&gt;
| `notify()`&lt;br /&gt;
| Sends the updated value to subscribed BLE clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following security settings are used in the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Security Feature&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Passkey&lt;br /&gt;
| Provides authentication during pairing.&lt;br /&gt;
|-&lt;br /&gt;
| MITM Protection&lt;br /&gt;
| Provides protection against certain man-in-the-middle attacks during authenticated pairing.&lt;br /&gt;
|-&lt;br /&gt;
| Secure Connections&lt;br /&gt;
| Uses the BLE Secure Connections pairing mechanism.&lt;br /&gt;
|-&lt;br /&gt;
| Bonding&lt;br /&gt;
| Allows security information to be retained for future connections.&lt;br /&gt;
|-&lt;br /&gt;
| Encryption&lt;br /&gt;
| Protects data transmitted over the established BLE link.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Espressif documents BLE security configurations including bonding, MITM protection and Secure Connections, and provides dedicated BLE security examples.&lt;br /&gt;
&lt;br /&gt;
== Smartphone Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install LightBlue ===&lt;br /&gt;
&lt;br /&gt;
Install &#039;&#039;&#039;LightBlue® by Punch Through&#039;&#039;&#039; on the smartphone.&lt;br /&gt;
&lt;br /&gt;
For Android:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
For iPhone/iPad:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
The same application is available on both platforms.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Upload the Program ===&lt;br /&gt;
&lt;br /&gt;
1. Connect the ESP32 to the computer using the USB cable.&lt;br /&gt;
2. Open Arduino IDE.&lt;br /&gt;
3. Select the appropriate ESP32 board.&lt;br /&gt;
4. Select the correct COM port.&lt;br /&gt;
5. Upload the program.&lt;br /&gt;
6. Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Start LightBlue ===&lt;br /&gt;
&lt;br /&gt;
1. Enable Bluetooth on the smartphone.&lt;br /&gt;
2. Open the LightBlue application.&lt;br /&gt;
3. Allow the required Bluetooth permissions.&lt;br /&gt;
4. Start scanning for nearby BLE devices.&lt;br /&gt;
5. Locate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Select the device and tap &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LightBlue supports BLE scanning, connection, service/characteristic inspection, reading, writing and notifications.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Pair the Device ===&lt;br /&gt;
&lt;br /&gt;
When the ESP32 requests secure pairing, the smartphone will display the BLE pairing/passkey interaction.&lt;br /&gt;
&lt;br /&gt;
Enter or confirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
123456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE connection becomes secured.&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s BLE documentation demonstrates pairing between an ESP32 BLE server and a mobile phone using LightBlue, including passkey-based pairing.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: View Sensor Data ===&lt;br /&gt;
&lt;br /&gt;
After connecting, LightBlue displays the BLE service and its characteristics.&lt;br /&gt;
&lt;br /&gt;
The structure will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&lt;br /&gt;
↓↓ Scroll to bottom&lt;br /&gt;
&lt;br /&gt;
beb5483e-36e1-4688-b7f5-ea07361b26a8 (This is Temperature)&lt;br /&gt;
&lt;br /&gt;
cba1d466-344c-4be3-ab3f-189f80dd7518 (This is Humidity)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can change the name of the above services and set them to Temperature and Humidity respectively for easy access.&lt;br /&gt;
&lt;br /&gt;
The exact appearance of the LightBlue interface may vary between Android and iOS versions.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Enable Notifications ===&lt;br /&gt;
&lt;br /&gt;
The temperature and humidity characteristics support notifications.&lt;br /&gt;
&lt;br /&gt;
Enable notifications for the characteristics in LightBlue.&lt;br /&gt;
&lt;br /&gt;
The ESP32 will then periodically send updated sensor readings.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 62.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete data flow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             DHT11 Sensor&lt;br /&gt;
                  ↓&lt;br /&gt;
          Temperature / Humidity&lt;br /&gt;
                  ↓&lt;br /&gt;
                ESP32&lt;br /&gt;
                  ↓&lt;br /&gt;
            BLE GATT Server&lt;br /&gt;
                  ↓&lt;br /&gt;
       BLE Pairing &amp;amp; Authentication&lt;br /&gt;
                  ↓&lt;br /&gt;
          Encrypted BLE Link&lt;br /&gt;
                  ↓&lt;br /&gt;
             Smartphone&lt;br /&gt;
                  ↓&lt;br /&gt;
           LightBlue Application&lt;br /&gt;
                  ↓&lt;br /&gt;
       Temperature / Humidity Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the given pin connections.&lt;br /&gt;
# Install the DHT sensor library in Arduino IDE if required.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the LightBlue BLE application on an Android or iOS smartphone.&lt;br /&gt;
# Enter the BLE program into Arduino IDE.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Select the correct ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that the ESP32 starts BLE advertising.&lt;br /&gt;
# Open LightBlue on the smartphone.&lt;br /&gt;
# Scan for nearby BLE devices.&lt;br /&gt;
# Select `ESP32-Secure-Sensor`.&lt;br /&gt;
# Establish the BLE connection.&lt;br /&gt;
# Complete the passkey authentication using `123456`.&lt;br /&gt;
# Verify that the BLE connection is authenticated and secured.&lt;br /&gt;
# Open the sensor service in LightBlue.&lt;br /&gt;
# Locate the temperature and humidity characteristics.&lt;br /&gt;
# Enable notifications for the characteristics.&lt;br /&gt;
# Observe the temperature and humidity values received from the ESP32.&lt;br /&gt;
# Compare the displayed values with the DHT11 readings shown in the Serial Monitor.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor displays information similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smartphone ===&lt;br /&gt;
&lt;br /&gt;
The LightBlue application should show:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Example Observation&lt;br /&gt;
|-&lt;br /&gt;
| BLE Device&lt;br /&gt;
| ESP32-Secure-Sensor&lt;br /&gt;
|-&lt;br /&gt;
| BLE Service&lt;br /&gt;
| Sensor Service&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| 61.00 %&lt;br /&gt;
|-&lt;br /&gt;
| Authentication&lt;br /&gt;
| Successful&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Secure BLE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual temperature and humidity values will depend on the environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32, and temperature and humidity data were transmitted to a smartphone using Bluetooth Low Energy. BLE pairing and security mechanisms were configured to authenticate the smartphone and establish a protected communication link. The sensor values were successfully observed using the LightBlue BLE application.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The BLE passkey used in this experiment is intended for educational demonstration.&lt;br /&gt;
* A fixed passkey such as `123456` should not be used in a real security-sensitive product.&lt;br /&gt;
* Production IoT systems should use appropriate device-specific credentials and security policies.&lt;br /&gt;
* Secure Connections and MITM protection improve the security of BLE pairing, but the overall security of an IoT product also depends on its firmware, credential management and application design.&lt;br /&gt;
* The experiment demonstrates BLE link security; it should not be interpreted as complete end-to-end IoT security.&lt;br /&gt;
* The LightBlue application is being used as a BLE debugging/client tool rather than as a custom end-user IoT application.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE stands for Bluetooth Low Energy. It is a wireless communication technology designed for low-power communication between devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Why is BLE suitable for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE provides short-range wireless communication with relatively low power consumption, making it suitable for sensors and other IoT devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. What is GATT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
GATT stands for Generic Attribute Profile. It defines how BLE devices organize and exchange application data using services and characteristics.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is a BLE service?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A service is a collection of related BLE characteristics that represents a particular function of the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is a BLE characteristic?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A characteristic represents a specific piece of data or functionality and can support operations such as read, write and notify.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is pairing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pairing is the process of establishing security information between two Bluetooth devices so that a secure relationship can be created.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What is BLE encryption?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE encryption protects data exchanged over an established secure BLE connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is a passkey used for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A passkey is used as part of the authentication process during BLE pairing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is MITM protection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MITM stands for Man-in-the-Middle. MITM protection helps prevent an attacker from impersonating one of the devices during the authentication process.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What is bonding?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bonding is the process of storing security information after pairing so that the devices can establish trusted connections again later.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why is LightBlue used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LightBlue provides a convenient BLE client interface for discovering the ESP32, connecting to it, inspecting services and characteristics, and receiving notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Can the same application be used on Android and iOS?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. LightBlue is available for both Android and iOS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the role of the ESP32 in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the DHT11 sensor and acts as a BLE GATT server that provides the sensor data to the smartphone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is the difference between `READ` and `NOTIFY` in BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
`READ` allows the client to request the current value. `NOTIFY` allows the server to send updated values automatically when the client subscribes to notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. How is this experiment different from HTTPS-based cloud communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS protects communication between an IoT device and a web/cloud server over a network. This experiment demonstrates secure short-range BLE communication directly between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates how Bluetooth Low Energy can be used for secure IoT sensor-data transmission. The ESP32 reads temperature and humidity from the DHT11 sensor and exposes the readings through BLE characteristics. The smartphone connects using the LightBlue application, performs secure pairing, and receives the sensor data through an authenticated and encrypted BLE connection.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1384</id>
		<title>MDM331AID/Experiment 12 BLE</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1384"/>
		<updated>2026-10-08T03:05:45Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Step 5: View Sensor Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To configure the ESP32 as a BLE server.&lt;br /&gt;
* To transmit real-time sensor data from the ESP32 to a smartphone using BLE.&lt;br /&gt;
* To understand BLE services and characteristics.&lt;br /&gt;
* To implement BLE pairing and authentication using a passkey.&lt;br /&gt;
* To understand how BLE encryption protects transmitted sensor data.&lt;br /&gt;
* To verify secure sensor-data communication using a smartphone BLE application.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| IoT controller and BLE server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and power supply&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| BLE client for receiving sensor data&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| LightBlue® BLE Application&lt;br /&gt;
| 1&lt;br /&gt;
| Scanning, connecting and monitoring BLE data&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Application ===&lt;br /&gt;
&lt;br /&gt;
The recommended application for this experiment is **LightBlue® by Punch Through**.&lt;br /&gt;
&lt;br /&gt;
LightBlue is a BLE debugging and development application that is available for both Android and iOS. It can scan for BLE peripherals, connect to them, display their services and characteristics, and read or subscribe to characteristic values.&lt;br /&gt;
&lt;br /&gt;
The application can be installed from:&lt;br /&gt;
&lt;br /&gt;
* Android: [LightBlue® on Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
* iPhone/iPad: [LightBlue® on the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth Low Energy ===&lt;br /&gt;
&lt;br /&gt;
Bluetooth Low Energy (BLE) is a wireless communication technology designed for low-power communication between devices. It is widely used in IoT sensors, wearable devices, smart-home devices and other embedded systems.&lt;br /&gt;
&lt;br /&gt;
An ESP32 can operate as a BLE device and communicate with smartphones and other BLE-enabled devices. The Arduino ESP32 framework provides a BLE library for creating BLE servers, services and characteristics.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 operates as a &#039;&#039;&#039;BLE GATT server&#039;&#039;&#039;, while the smartphone operates as the &#039;&#039;&#039;BLE client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The communication structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     ↓&lt;br /&gt;
   ESP32&lt;br /&gt;
     ↓&lt;br /&gt;
 BLE GATT Server&lt;br /&gt;
     ↓&lt;br /&gt;
 Secure BLE Connection&lt;br /&gt;
     ↓&lt;br /&gt;
 Smartphone&lt;br /&gt;
     ↓&lt;br /&gt;
 LightBlue Application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BLE GATT ===&lt;br /&gt;
&lt;br /&gt;
BLE devices commonly organize application data using the Generic Attribute Profile (GATT).&lt;br /&gt;
&lt;br /&gt;
The main components used in this experiment are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Service:&#039;&#039;&#039;  &lt;br /&gt;
A service groups related functionality of a BLE device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Characteristic:&#039;&#039;&#039;  &lt;br /&gt;
A characteristic contains a particular piece of data that can be read, written or notified.&lt;br /&gt;
&lt;br /&gt;
For this experiment, one BLE service is created containing two characteristics:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Characteristic&lt;br /&gt;
! Data&lt;br /&gt;
! Operation&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature in °C&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity in %&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The smartphone can connect to the ESP32 and subscribe to notifications so that updated sensor values are received automatically.&lt;br /&gt;
&lt;br /&gt;
=== BLE Security ===&lt;br /&gt;
&lt;br /&gt;
BLE provides security mechanisms for authentication, pairing, bonding and encrypted communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, BLE security is configured using:&lt;br /&gt;
&lt;br /&gt;
* Pairing&lt;br /&gt;
* Bonding&lt;br /&gt;
* MITM (Man-in-the-Middle) protection&lt;br /&gt;
* Secure Connections&lt;br /&gt;
* Passkey authentication&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s ESP32 BLE security documentation supports authentication modes combining bonding, MITM protection and Secure Connections.&lt;br /&gt;
&lt;br /&gt;
=== Pairing ===&lt;br /&gt;
&lt;br /&gt;
Pairing is the process by which two Bluetooth devices establish the information required to create a trusted secure relationship.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the smartphone and ESP32 are paired using a passkey.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32&lt;br /&gt;
  ↓&lt;br /&gt;
BLE connection request&lt;br /&gt;
  ↓&lt;br /&gt;
Pairing request&lt;br /&gt;
  ↓&lt;br /&gt;
Passkey authentication&lt;br /&gt;
  ↓&lt;br /&gt;
Secure key establishment&lt;br /&gt;
  ↓&lt;br /&gt;
Encrypted BLE communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bonding ===&lt;br /&gt;
&lt;br /&gt;
Bonding allows the security information established during pairing to be stored so that the devices can recognize each other during future connections.&lt;br /&gt;
&lt;br /&gt;
Espressif distinguishes bonding from encryption: bonding stores long-term keys after successful encryption, while encryption protects the communication link.&lt;br /&gt;
&lt;br /&gt;
=== BLE Encryption ===&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE link can be encrypted.&lt;br /&gt;
&lt;br /&gt;
Therefore, the sensor data transmitted over the BLE connection is protected from simple interception of the communication.&lt;br /&gt;
&lt;br /&gt;
The security flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
    ↓&lt;br /&gt;
BLE Security / Pairing&lt;br /&gt;
    ↓&lt;br /&gt;
Authentication&lt;br /&gt;
    ↓&lt;br /&gt;
Encryption&lt;br /&gt;
    ↓&lt;br /&gt;
Secure BLE Transmission&lt;br /&gt;
    ↓&lt;br /&gt;
Smartphone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              +----------------+&lt;br /&gt;
              |     DHT11      |&lt;br /&gt;
              |                |&lt;br /&gt;
              | VCC  DATA  GND |&lt;br /&gt;
              +--+----+-----+--+&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                3.3V GPIO4 GND&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                 |    |     |&lt;br /&gt;
          +------+----+-----+------+&lt;br /&gt;
          |          ESP32         |&lt;br /&gt;
          |                        |&lt;br /&gt;
          |       BLE Server       |&lt;br /&gt;
          |          ))))          |&lt;br /&gt;
          +------------))----------+&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                Secure BLE Link&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                 +-----------+&lt;br /&gt;
                 | Smartphone|&lt;br /&gt;
                 |           |&lt;br /&gt;
                 | LightBlue |&lt;br /&gt;
                 +-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Arduino Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEDevice.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEUtils.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLESecurity.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define DEVICE_NAME &amp;quot;ESP32-Secure-Sensor&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define SERVICE_UUID \&lt;br /&gt;
&amp;quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define TEMP_UUID \&lt;br /&gt;
&amp;quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define HUMIDITY_UUID \&lt;br /&gt;
&amp;quot;cba1d466-344c-4be3-ab3f-189f80dd7518&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BLE_PASSKEY 123456&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
BLECharacteristic *temperatureCharacteristic;&lt;br /&gt;
BLECharacteristic *humidityCharacteristic;&lt;br /&gt;
&lt;br /&gt;
class SecurityCallbacks : public BLESecurityCallbacks&lt;br /&gt;
{&lt;br /&gt;
  uint32_t onPassKeyRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Passkey requested&amp;quot;);&lt;br /&gt;
    return BLE_PASSKEY;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onPassKeyNotify(uint32_t passkey)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Passkey: &amp;quot;);&lt;br /&gt;
    Serial.println(passkey);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onConfirmPIN(uint32_t pin)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Confirm PIN: &amp;quot;);&lt;br /&gt;
    Serial.println(pin);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onSecurityRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Security request received&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onAuthenticationComplete(esp_ble_auth_cmpl_t desc)&lt;br /&gt;
  {&lt;br /&gt;
    if (desc.success)&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication successful&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::init(DEVICE_NAME);&lt;br /&gt;
&lt;br /&gt;
  BLESecurity *security = new BLESecurity();&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setCapability(ESP_IO_CAP_OUT);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setAuthenticationMode(&lt;br /&gt;
    ESP_LE_AUTH_REQ_SC_MITM_BOND&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::setSecurityCallbacks(&lt;br /&gt;
    new SecurityCallbacks()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEServer *server = BLEDevice::createServer();&lt;br /&gt;
&lt;br /&gt;
  BLEService *service =&lt;br /&gt;
    server-&amp;gt;createService(SERVICE_UUID);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      TEMP_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      HUMIDITY_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  service-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
  BLEAdvertising *advertising =&lt;br /&gt;
    BLEDevice::getAdvertising();&lt;br /&gt;
&lt;br /&gt;
  advertising-&amp;gt;addServiceUUID(SERVICE_UUID);&lt;br /&gt;
  advertising-&amp;gt;setScanResponse(true);&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::startAdvertising();&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Secure BLE Sensor Started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Device Name: ESP32-Secure-Sensor&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Passkey: 123456&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Waiting for BLE connection...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  char temperatureValue[10];&lt;br /&gt;
  char humidityValue[10];&lt;br /&gt;
&lt;br /&gt;
  dtostrf(temperature, 1, 2, temperatureValue);&lt;br /&gt;
  dtostrf(humidity, 1, 2, humidityValue);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    temperatureValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    humidityValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;notify();&lt;br /&gt;
  humidityCharacteristic-&amp;gt;notify();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Sensor data sent using secure BLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;`&lt;br /&gt;
| Provides the main BLE device functionality.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEServer.h&amp;amp;gt;`&lt;br /&gt;
| Provides functionality for creating a BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;`&lt;br /&gt;
| Provides BLE pairing and security configuration.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;DHT.h&amp;amp;gt;`&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `DHTPIN 4`&lt;br /&gt;
| Defines GPIO 4 as the DHT11 data pin.&lt;br /&gt;
|-&lt;br /&gt;
| `DEVICE_NAME`&lt;br /&gt;
| Defines the name advertised by the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| `SERVICE_UUID`&lt;br /&gt;
| Uniquely identifies the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `TEMP_UUID`&lt;br /&gt;
| Identifies the temperature characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `HUMIDITY_UUID`&lt;br /&gt;
| Identifies the humidity characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `BLE_PASSKEY 123456`&lt;br /&gt;
| Defines the passkey used for BLE authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.begin()`&lt;br /&gt;
| Initializes the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `BLEDevice::init()`&lt;br /&gt;
| Initializes BLE and assigns the device name.&lt;br /&gt;
|-&lt;br /&gt;
| `setPassKey()`&lt;br /&gt;
| Configures the BLE passkey.&lt;br /&gt;
|-&lt;br /&gt;
| `setCapability()`&lt;br /&gt;
| Defines the input/output capability used during authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `setAuthenticationMode(true, true, true)`&lt;br /&gt;
| Enables bonding, MITM protection and Secure Connections.&lt;br /&gt;
|-&lt;br /&gt;
| `createServer()`&lt;br /&gt;
| Creates the ESP32 BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `createService()`&lt;br /&gt;
| Creates the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `createCharacteristic()`&lt;br /&gt;
| Creates temperature and humidity characteristics.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_READ`&lt;br /&gt;
| Allows the smartphone to read the sensor value.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_NOTIFY`&lt;br /&gt;
| Allows the ESP32 to send updated sensor values to the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| `service-&amp;gt;start()`&lt;br /&gt;
| Starts the BLE service.&lt;br /&gt;
|-&lt;br /&gt;
| `startAdvertising()`&lt;br /&gt;
| Makes the ESP32 discoverable by BLE clients.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `setValue()`&lt;br /&gt;
| Updates the BLE characteristic value.&lt;br /&gt;
|-&lt;br /&gt;
| `notify()`&lt;br /&gt;
| Sends the updated value to subscribed BLE clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following security settings are used in the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Security Feature&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Passkey&lt;br /&gt;
| Provides authentication during pairing.&lt;br /&gt;
|-&lt;br /&gt;
| MITM Protection&lt;br /&gt;
| Provides protection against certain man-in-the-middle attacks during authenticated pairing.&lt;br /&gt;
|-&lt;br /&gt;
| Secure Connections&lt;br /&gt;
| Uses the BLE Secure Connections pairing mechanism.&lt;br /&gt;
|-&lt;br /&gt;
| Bonding&lt;br /&gt;
| Allows security information to be retained for future connections.&lt;br /&gt;
|-&lt;br /&gt;
| Encryption&lt;br /&gt;
| Protects data transmitted over the established BLE link.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Espressif documents BLE security configurations including bonding, MITM protection and Secure Connections, and provides dedicated BLE security examples.&lt;br /&gt;
&lt;br /&gt;
== Smartphone Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install LightBlue ===&lt;br /&gt;
&lt;br /&gt;
Install &#039;&#039;&#039;LightBlue® by Punch Through&#039;&#039;&#039; on the smartphone.&lt;br /&gt;
&lt;br /&gt;
For Android:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
For iPhone/iPad:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
The same application is available on both platforms.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Upload the Program ===&lt;br /&gt;
&lt;br /&gt;
1. Connect the ESP32 to the computer using the USB cable.&lt;br /&gt;
2. Open Arduino IDE.&lt;br /&gt;
3. Select the appropriate ESP32 board.&lt;br /&gt;
4. Select the correct COM port.&lt;br /&gt;
5. Upload the program.&lt;br /&gt;
6. Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Start LightBlue ===&lt;br /&gt;
&lt;br /&gt;
1. Enable Bluetooth on the smartphone.&lt;br /&gt;
2. Open the LightBlue application.&lt;br /&gt;
3. Allow the required Bluetooth permissions.&lt;br /&gt;
4. Start scanning for nearby BLE devices.&lt;br /&gt;
5. Locate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Select the device and tap &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LightBlue supports BLE scanning, connection, service/characteristic inspection, reading, writing and notifications.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Pair the Device ===&lt;br /&gt;
&lt;br /&gt;
When the ESP32 requests secure pairing, the smartphone will display the BLE pairing/passkey interaction.&lt;br /&gt;
&lt;br /&gt;
Enter or confirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
123456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE connection becomes secured.&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s BLE documentation demonstrates pairing between an ESP32 BLE server and a mobile phone using LightBlue, including passkey-based pairing.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: View Sensor Data ===&lt;br /&gt;
&lt;br /&gt;
After connecting, LightBlue displays the BLE service and its characteristics.&lt;br /&gt;
&lt;br /&gt;
The structure will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&lt;br /&gt;
↓↓ Scroll to bottom&lt;br /&gt;
&lt;br /&gt;
beb5483e-36e1-4688-b7f5-ea07361b26a8 (This is Temperature)&lt;br /&gt;
&lt;br /&gt;
cba1d466-344c-4be3-ab3f-189f80dd7518 (This is Humidity)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can change the name of the above services and set them to Temperature and Humidity respectively for easy access.&lt;br /&gt;
&lt;br /&gt;
The exact appearance of the LightBlue interface may vary between Android and iOS versions.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Enable Notifications ===&lt;br /&gt;
&lt;br /&gt;
The temperature and humidity characteristics support notifications.&lt;br /&gt;
&lt;br /&gt;
Enable notifications for the characteristics in LightBlue.&lt;br /&gt;
&lt;br /&gt;
The ESP32 will then periodically send updated sensor readings.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 62.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete data flow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             DHT11 Sensor&lt;br /&gt;
                  ↓&lt;br /&gt;
          Temperature / Humidity&lt;br /&gt;
                  ↓&lt;br /&gt;
                ESP32&lt;br /&gt;
                  ↓&lt;br /&gt;
            BLE GATT Server&lt;br /&gt;
                  ↓&lt;br /&gt;
       BLE Pairing &amp;amp; Authentication&lt;br /&gt;
                  ↓&lt;br /&gt;
          Encrypted BLE Link&lt;br /&gt;
                  ↓&lt;br /&gt;
             Smartphone&lt;br /&gt;
                  ↓&lt;br /&gt;
           LightBlue Application&lt;br /&gt;
                  ↓&lt;br /&gt;
       Temperature / Humidity Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the given pin connections.&lt;br /&gt;
# Install the DHT sensor library in Arduino IDE if required.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the LightBlue BLE application on an Android or iOS smartphone.&lt;br /&gt;
# Enter the BLE program into Arduino IDE.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Select the correct ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that the ESP32 starts BLE advertising.&lt;br /&gt;
# Open LightBlue on the smartphone.&lt;br /&gt;
# Scan for nearby BLE devices.&lt;br /&gt;
# Select `ESP32-Secure-Sensor`.&lt;br /&gt;
# Establish the BLE connection.&lt;br /&gt;
# Complete the passkey authentication using `123456`.&lt;br /&gt;
# Verify that the BLE connection is authenticated and secured.&lt;br /&gt;
# Open the sensor service in LightBlue.&lt;br /&gt;
# Locate the temperature and humidity characteristics.&lt;br /&gt;
# Enable notifications for the characteristics.&lt;br /&gt;
# Observe the temperature and humidity values received from the ESP32.&lt;br /&gt;
# Compare the displayed values with the DHT11 readings shown in the Serial Monitor.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor displays information similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smartphone ===&lt;br /&gt;
&lt;br /&gt;
The LightBlue application should show:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Example Observation&lt;br /&gt;
|-&lt;br /&gt;
| BLE Device&lt;br /&gt;
| ESP32-Secure-Sensor&lt;br /&gt;
|-&lt;br /&gt;
| BLE Service&lt;br /&gt;
| Sensor Service&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| 61.00 %&lt;br /&gt;
|-&lt;br /&gt;
| Authentication&lt;br /&gt;
| Successful&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Secure BLE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual temperature and humidity values will depend on the environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32, and temperature and humidity data were transmitted to a smartphone using Bluetooth Low Energy. BLE pairing and security mechanisms were configured to authenticate the smartphone and establish a protected communication link. The sensor values were successfully observed using the LightBlue BLE application.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The BLE passkey used in this experiment is intended for educational demonstration.&lt;br /&gt;
* A fixed passkey such as `123456` should not be used in a real security-sensitive product.&lt;br /&gt;
* Production IoT systems should use appropriate device-specific credentials and security policies.&lt;br /&gt;
* Secure Connections and MITM protection improve the security of BLE pairing, but the overall security of an IoT product also depends on its firmware, credential management and application design.&lt;br /&gt;
* The experiment demonstrates BLE link security; it should not be interpreted as complete end-to-end IoT security.&lt;br /&gt;
* The LightBlue application is being used as a BLE debugging/client tool rather than as a custom end-user IoT application.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE stands for Bluetooth Low Energy. It is a wireless communication technology designed for low-power communication between devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Why is BLE suitable for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE provides short-range wireless communication with relatively low power consumption, making it suitable for sensors and other IoT devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. What is GATT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
GATT stands for Generic Attribute Profile. It defines how BLE devices organize and exchange application data using services and characteristics.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is a BLE service?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A service is a collection of related BLE characteristics that represents a particular function of the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is a BLE characteristic?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A characteristic represents a specific piece of data or functionality and can support operations such as read, write and notify.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is pairing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pairing is the process of establishing security information between two Bluetooth devices so that a secure relationship can be created.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What is BLE encryption?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE encryption protects data exchanged over an established secure BLE connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is a passkey used for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A passkey is used as part of the authentication process during BLE pairing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is MITM protection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MITM stands for Man-in-the-Middle. MITM protection helps prevent an attacker from impersonating one of the devices during the authentication process.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What is bonding?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bonding is the process of storing security information after pairing so that the devices can establish trusted connections again later.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why is LightBlue used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LightBlue provides a convenient BLE client interface for discovering the ESP32, connecting to it, inspecting services and characteristics, and receiving notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Can the same application be used on Android and iOS?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. LightBlue is available for both Android and iOS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the role of the ESP32 in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the DHT11 sensor and acts as a BLE GATT server that provides the sensor data to the smartphone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is the difference between `READ` and `NOTIFY` in BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
`READ` allows the client to request the current value. `NOTIFY` allows the server to send updated values automatically when the client subscribes to notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. How is this experiment different from HTTPS-based cloud communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS protects communication between an IoT device and a web/cloud server over a network. This experiment demonstrates secure short-range BLE communication directly between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates how Bluetooth Low Energy can be used for secure IoT sensor-data transmission. The ESP32 reads temperature and humidity from the DHT11 sensor and exposes the readings through BLE characteristics. The smartphone connects using the LightBlue application, performs secure pairing, and receives the sensor data through an authenticated and encrypted BLE connection.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1383</id>
		<title>MDM331AID/Experiment 12 BLE</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1383"/>
		<updated>2026-10-08T03:00:36Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Arduino Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To configure the ESP32 as a BLE server.&lt;br /&gt;
* To transmit real-time sensor data from the ESP32 to a smartphone using BLE.&lt;br /&gt;
* To understand BLE services and characteristics.&lt;br /&gt;
* To implement BLE pairing and authentication using a passkey.&lt;br /&gt;
* To understand how BLE encryption protects transmitted sensor data.&lt;br /&gt;
* To verify secure sensor-data communication using a smartphone BLE application.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| IoT controller and BLE server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and power supply&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| BLE client for receiving sensor data&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| LightBlue® BLE Application&lt;br /&gt;
| 1&lt;br /&gt;
| Scanning, connecting and monitoring BLE data&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Application ===&lt;br /&gt;
&lt;br /&gt;
The recommended application for this experiment is **LightBlue® by Punch Through**.&lt;br /&gt;
&lt;br /&gt;
LightBlue is a BLE debugging and development application that is available for both Android and iOS. It can scan for BLE peripherals, connect to them, display their services and characteristics, and read or subscribe to characteristic values.&lt;br /&gt;
&lt;br /&gt;
The application can be installed from:&lt;br /&gt;
&lt;br /&gt;
* Android: [LightBlue® on Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
* iPhone/iPad: [LightBlue® on the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth Low Energy ===&lt;br /&gt;
&lt;br /&gt;
Bluetooth Low Energy (BLE) is a wireless communication technology designed for low-power communication between devices. It is widely used in IoT sensors, wearable devices, smart-home devices and other embedded systems.&lt;br /&gt;
&lt;br /&gt;
An ESP32 can operate as a BLE device and communicate with smartphones and other BLE-enabled devices. The Arduino ESP32 framework provides a BLE library for creating BLE servers, services and characteristics.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 operates as a &#039;&#039;&#039;BLE GATT server&#039;&#039;&#039;, while the smartphone operates as the &#039;&#039;&#039;BLE client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The communication structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     ↓&lt;br /&gt;
   ESP32&lt;br /&gt;
     ↓&lt;br /&gt;
 BLE GATT Server&lt;br /&gt;
     ↓&lt;br /&gt;
 Secure BLE Connection&lt;br /&gt;
     ↓&lt;br /&gt;
 Smartphone&lt;br /&gt;
     ↓&lt;br /&gt;
 LightBlue Application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BLE GATT ===&lt;br /&gt;
&lt;br /&gt;
BLE devices commonly organize application data using the Generic Attribute Profile (GATT).&lt;br /&gt;
&lt;br /&gt;
The main components used in this experiment are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Service:&#039;&#039;&#039;  &lt;br /&gt;
A service groups related functionality of a BLE device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Characteristic:&#039;&#039;&#039;  &lt;br /&gt;
A characteristic contains a particular piece of data that can be read, written or notified.&lt;br /&gt;
&lt;br /&gt;
For this experiment, one BLE service is created containing two characteristics:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Characteristic&lt;br /&gt;
! Data&lt;br /&gt;
! Operation&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature in °C&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity in %&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The smartphone can connect to the ESP32 and subscribe to notifications so that updated sensor values are received automatically.&lt;br /&gt;
&lt;br /&gt;
=== BLE Security ===&lt;br /&gt;
&lt;br /&gt;
BLE provides security mechanisms for authentication, pairing, bonding and encrypted communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, BLE security is configured using:&lt;br /&gt;
&lt;br /&gt;
* Pairing&lt;br /&gt;
* Bonding&lt;br /&gt;
* MITM (Man-in-the-Middle) protection&lt;br /&gt;
* Secure Connections&lt;br /&gt;
* Passkey authentication&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s ESP32 BLE security documentation supports authentication modes combining bonding, MITM protection and Secure Connections.&lt;br /&gt;
&lt;br /&gt;
=== Pairing ===&lt;br /&gt;
&lt;br /&gt;
Pairing is the process by which two Bluetooth devices establish the information required to create a trusted secure relationship.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the smartphone and ESP32 are paired using a passkey.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32&lt;br /&gt;
  ↓&lt;br /&gt;
BLE connection request&lt;br /&gt;
  ↓&lt;br /&gt;
Pairing request&lt;br /&gt;
  ↓&lt;br /&gt;
Passkey authentication&lt;br /&gt;
  ↓&lt;br /&gt;
Secure key establishment&lt;br /&gt;
  ↓&lt;br /&gt;
Encrypted BLE communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bonding ===&lt;br /&gt;
&lt;br /&gt;
Bonding allows the security information established during pairing to be stored so that the devices can recognize each other during future connections.&lt;br /&gt;
&lt;br /&gt;
Espressif distinguishes bonding from encryption: bonding stores long-term keys after successful encryption, while encryption protects the communication link.&lt;br /&gt;
&lt;br /&gt;
=== BLE Encryption ===&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE link can be encrypted.&lt;br /&gt;
&lt;br /&gt;
Therefore, the sensor data transmitted over the BLE connection is protected from simple interception of the communication.&lt;br /&gt;
&lt;br /&gt;
The security flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
    ↓&lt;br /&gt;
BLE Security / Pairing&lt;br /&gt;
    ↓&lt;br /&gt;
Authentication&lt;br /&gt;
    ↓&lt;br /&gt;
Encryption&lt;br /&gt;
    ↓&lt;br /&gt;
Secure BLE Transmission&lt;br /&gt;
    ↓&lt;br /&gt;
Smartphone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              +----------------+&lt;br /&gt;
              |     DHT11      |&lt;br /&gt;
              |                |&lt;br /&gt;
              | VCC  DATA  GND |&lt;br /&gt;
              +--+----+-----+--+&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                3.3V GPIO4 GND&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                 |    |     |&lt;br /&gt;
          +------+----+-----+------+&lt;br /&gt;
          |          ESP32         |&lt;br /&gt;
          |                        |&lt;br /&gt;
          |       BLE Server       |&lt;br /&gt;
          |          ))))          |&lt;br /&gt;
          +------------))----------+&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                Secure BLE Link&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                 +-----------+&lt;br /&gt;
                 | Smartphone|&lt;br /&gt;
                 |           |&lt;br /&gt;
                 | LightBlue |&lt;br /&gt;
                 +-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Arduino Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEDevice.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLEUtils.h&amp;gt;&lt;br /&gt;
#include &amp;lt;BLESecurity.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define DEVICE_NAME &amp;quot;ESP32-Secure-Sensor&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define SERVICE_UUID \&lt;br /&gt;
&amp;quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define TEMP_UUID \&lt;br /&gt;
&amp;quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define HUMIDITY_UUID \&lt;br /&gt;
&amp;quot;cba1d466-344c-4be3-ab3f-189f80dd7518&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BLE_PASSKEY 123456&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
BLECharacteristic *temperatureCharacteristic;&lt;br /&gt;
BLECharacteristic *humidityCharacteristic;&lt;br /&gt;
&lt;br /&gt;
class SecurityCallbacks : public BLESecurityCallbacks&lt;br /&gt;
{&lt;br /&gt;
  uint32_t onPassKeyRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Passkey requested&amp;quot;);&lt;br /&gt;
    return BLE_PASSKEY;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onPassKeyNotify(uint32_t passkey)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Passkey: &amp;quot;);&lt;br /&gt;
    Serial.println(passkey);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onConfirmPIN(uint32_t pin)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Confirm PIN: &amp;quot;);&lt;br /&gt;
    Serial.println(pin);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onSecurityRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Security request received&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onAuthenticationComplete(esp_ble_auth_cmpl_t desc)&lt;br /&gt;
  {&lt;br /&gt;
    if (desc.success)&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication successful&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::init(DEVICE_NAME);&lt;br /&gt;
&lt;br /&gt;
  BLESecurity *security = new BLESecurity();&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setCapability(ESP_IO_CAP_OUT);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setAuthenticationMode(&lt;br /&gt;
    ESP_LE_AUTH_REQ_SC_MITM_BOND&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::setSecurityCallbacks(&lt;br /&gt;
    new SecurityCallbacks()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEServer *server = BLEDevice::createServer();&lt;br /&gt;
&lt;br /&gt;
  BLEService *service =&lt;br /&gt;
    server-&amp;gt;createService(SERVICE_UUID);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      TEMP_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      HUMIDITY_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  service-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
  BLEAdvertising *advertising =&lt;br /&gt;
    BLEDevice::getAdvertising();&lt;br /&gt;
&lt;br /&gt;
  advertising-&amp;gt;addServiceUUID(SERVICE_UUID);&lt;br /&gt;
  advertising-&amp;gt;setScanResponse(true);&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::startAdvertising();&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Secure BLE Sensor Started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Device Name: ESP32-Secure-Sensor&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Passkey: 123456&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Waiting for BLE connection...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  char temperatureValue[10];&lt;br /&gt;
  char humidityValue[10];&lt;br /&gt;
&lt;br /&gt;
  dtostrf(temperature, 1, 2, temperatureValue);&lt;br /&gt;
  dtostrf(humidity, 1, 2, humidityValue);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    temperatureValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    humidityValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;notify();&lt;br /&gt;
  humidityCharacteristic-&amp;gt;notify();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Sensor data sent using secure BLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;`&lt;br /&gt;
| Provides the main BLE device functionality.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEServer.h&amp;amp;gt;`&lt;br /&gt;
| Provides functionality for creating a BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;`&lt;br /&gt;
| Provides BLE pairing and security configuration.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;DHT.h&amp;amp;gt;`&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `DHTPIN 4`&lt;br /&gt;
| Defines GPIO 4 as the DHT11 data pin.&lt;br /&gt;
|-&lt;br /&gt;
| `DEVICE_NAME`&lt;br /&gt;
| Defines the name advertised by the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| `SERVICE_UUID`&lt;br /&gt;
| Uniquely identifies the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `TEMP_UUID`&lt;br /&gt;
| Identifies the temperature characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `HUMIDITY_UUID`&lt;br /&gt;
| Identifies the humidity characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `BLE_PASSKEY 123456`&lt;br /&gt;
| Defines the passkey used for BLE authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.begin()`&lt;br /&gt;
| Initializes the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `BLEDevice::init()`&lt;br /&gt;
| Initializes BLE and assigns the device name.&lt;br /&gt;
|-&lt;br /&gt;
| `setPassKey()`&lt;br /&gt;
| Configures the BLE passkey.&lt;br /&gt;
|-&lt;br /&gt;
| `setCapability()`&lt;br /&gt;
| Defines the input/output capability used during authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `setAuthenticationMode(true, true, true)`&lt;br /&gt;
| Enables bonding, MITM protection and Secure Connections.&lt;br /&gt;
|-&lt;br /&gt;
| `createServer()`&lt;br /&gt;
| Creates the ESP32 BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `createService()`&lt;br /&gt;
| Creates the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `createCharacteristic()`&lt;br /&gt;
| Creates temperature and humidity characteristics.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_READ`&lt;br /&gt;
| Allows the smartphone to read the sensor value.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_NOTIFY`&lt;br /&gt;
| Allows the ESP32 to send updated sensor values to the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| `service-&amp;gt;start()`&lt;br /&gt;
| Starts the BLE service.&lt;br /&gt;
|-&lt;br /&gt;
| `startAdvertising()`&lt;br /&gt;
| Makes the ESP32 discoverable by BLE clients.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `setValue()`&lt;br /&gt;
| Updates the BLE characteristic value.&lt;br /&gt;
|-&lt;br /&gt;
| `notify()`&lt;br /&gt;
| Sends the updated value to subscribed BLE clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following security settings are used in the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Security Feature&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Passkey&lt;br /&gt;
| Provides authentication during pairing.&lt;br /&gt;
|-&lt;br /&gt;
| MITM Protection&lt;br /&gt;
| Provides protection against certain man-in-the-middle attacks during authenticated pairing.&lt;br /&gt;
|-&lt;br /&gt;
| Secure Connections&lt;br /&gt;
| Uses the BLE Secure Connections pairing mechanism.&lt;br /&gt;
|-&lt;br /&gt;
| Bonding&lt;br /&gt;
| Allows security information to be retained for future connections.&lt;br /&gt;
|-&lt;br /&gt;
| Encryption&lt;br /&gt;
| Protects data transmitted over the established BLE link.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Espressif documents BLE security configurations including bonding, MITM protection and Secure Connections, and provides dedicated BLE security examples.&lt;br /&gt;
&lt;br /&gt;
== Smartphone Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install LightBlue ===&lt;br /&gt;
&lt;br /&gt;
Install &#039;&#039;&#039;LightBlue® by Punch Through&#039;&#039;&#039; on the smartphone.&lt;br /&gt;
&lt;br /&gt;
For Android:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
For iPhone/iPad:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
The same application is available on both platforms.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Upload the Program ===&lt;br /&gt;
&lt;br /&gt;
1. Connect the ESP32 to the computer using the USB cable.&lt;br /&gt;
2. Open Arduino IDE.&lt;br /&gt;
3. Select the appropriate ESP32 board.&lt;br /&gt;
4. Select the correct COM port.&lt;br /&gt;
5. Upload the program.&lt;br /&gt;
6. Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Start LightBlue ===&lt;br /&gt;
&lt;br /&gt;
1. Enable Bluetooth on the smartphone.&lt;br /&gt;
2. Open the LightBlue application.&lt;br /&gt;
3. Allow the required Bluetooth permissions.&lt;br /&gt;
4. Start scanning for nearby BLE devices.&lt;br /&gt;
5. Locate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Select the device and tap &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LightBlue supports BLE scanning, connection, service/characteristic inspection, reading, writing and notifications.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Pair the Device ===&lt;br /&gt;
&lt;br /&gt;
When the ESP32 requests secure pairing, the smartphone will display the BLE pairing/passkey interaction.&lt;br /&gt;
&lt;br /&gt;
Enter or confirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
123456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE connection becomes secured.&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s BLE documentation demonstrates pairing between an ESP32 BLE server and a mobile phone using LightBlue, including passkey-based pairing.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: View Sensor Data ===&lt;br /&gt;
&lt;br /&gt;
After connecting, LightBlue displays the BLE service and its characteristics.&lt;br /&gt;
&lt;br /&gt;
The structure will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&lt;br /&gt;
Service&lt;br /&gt;
└── Sensor Service&lt;br /&gt;
      │&lt;br /&gt;
      ├── Temperature&lt;br /&gt;
      │      Value: 27.40&lt;br /&gt;
      │&lt;br /&gt;
      └── Humidity&lt;br /&gt;
             Value: 61.00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact appearance of the LightBlue interface may vary between Android and iOS versions.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Enable Notifications ===&lt;br /&gt;
&lt;br /&gt;
The temperature and humidity characteristics support notifications.&lt;br /&gt;
&lt;br /&gt;
Enable notifications for the characteristics in LightBlue.&lt;br /&gt;
&lt;br /&gt;
The ESP32 will then periodically send updated sensor readings.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 62.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete data flow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             DHT11 Sensor&lt;br /&gt;
                  ↓&lt;br /&gt;
          Temperature / Humidity&lt;br /&gt;
                  ↓&lt;br /&gt;
                ESP32&lt;br /&gt;
                  ↓&lt;br /&gt;
            BLE GATT Server&lt;br /&gt;
                  ↓&lt;br /&gt;
       BLE Pairing &amp;amp; Authentication&lt;br /&gt;
                  ↓&lt;br /&gt;
          Encrypted BLE Link&lt;br /&gt;
                  ↓&lt;br /&gt;
             Smartphone&lt;br /&gt;
                  ↓&lt;br /&gt;
           LightBlue Application&lt;br /&gt;
                  ↓&lt;br /&gt;
       Temperature / Humidity Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the given pin connections.&lt;br /&gt;
# Install the DHT sensor library in Arduino IDE if required.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the LightBlue BLE application on an Android or iOS smartphone.&lt;br /&gt;
# Enter the BLE program into Arduino IDE.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Select the correct ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that the ESP32 starts BLE advertising.&lt;br /&gt;
# Open LightBlue on the smartphone.&lt;br /&gt;
# Scan for nearby BLE devices.&lt;br /&gt;
# Select `ESP32-Secure-Sensor`.&lt;br /&gt;
# Establish the BLE connection.&lt;br /&gt;
# Complete the passkey authentication using `123456`.&lt;br /&gt;
# Verify that the BLE connection is authenticated and secured.&lt;br /&gt;
# Open the sensor service in LightBlue.&lt;br /&gt;
# Locate the temperature and humidity characteristics.&lt;br /&gt;
# Enable notifications for the characteristics.&lt;br /&gt;
# Observe the temperature and humidity values received from the ESP32.&lt;br /&gt;
# Compare the displayed values with the DHT11 readings shown in the Serial Monitor.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor displays information similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smartphone ===&lt;br /&gt;
&lt;br /&gt;
The LightBlue application should show:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Example Observation&lt;br /&gt;
|-&lt;br /&gt;
| BLE Device&lt;br /&gt;
| ESP32-Secure-Sensor&lt;br /&gt;
|-&lt;br /&gt;
| BLE Service&lt;br /&gt;
| Sensor Service&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| 61.00 %&lt;br /&gt;
|-&lt;br /&gt;
| Authentication&lt;br /&gt;
| Successful&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Secure BLE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual temperature and humidity values will depend on the environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32, and temperature and humidity data were transmitted to a smartphone using Bluetooth Low Energy. BLE pairing and security mechanisms were configured to authenticate the smartphone and establish a protected communication link. The sensor values were successfully observed using the LightBlue BLE application.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The BLE passkey used in this experiment is intended for educational demonstration.&lt;br /&gt;
* A fixed passkey such as `123456` should not be used in a real security-sensitive product.&lt;br /&gt;
* Production IoT systems should use appropriate device-specific credentials and security policies.&lt;br /&gt;
* Secure Connections and MITM protection improve the security of BLE pairing, but the overall security of an IoT product also depends on its firmware, credential management and application design.&lt;br /&gt;
* The experiment demonstrates BLE link security; it should not be interpreted as complete end-to-end IoT security.&lt;br /&gt;
* The LightBlue application is being used as a BLE debugging/client tool rather than as a custom end-user IoT application.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE stands for Bluetooth Low Energy. It is a wireless communication technology designed for low-power communication between devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Why is BLE suitable for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE provides short-range wireless communication with relatively low power consumption, making it suitable for sensors and other IoT devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. What is GATT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
GATT stands for Generic Attribute Profile. It defines how BLE devices organize and exchange application data using services and characteristics.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is a BLE service?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A service is a collection of related BLE characteristics that represents a particular function of the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is a BLE characteristic?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A characteristic represents a specific piece of data or functionality and can support operations such as read, write and notify.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is pairing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pairing is the process of establishing security information between two Bluetooth devices so that a secure relationship can be created.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What is BLE encryption?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE encryption protects data exchanged over an established secure BLE connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is a passkey used for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A passkey is used as part of the authentication process during BLE pairing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is MITM protection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MITM stands for Man-in-the-Middle. MITM protection helps prevent an attacker from impersonating one of the devices during the authentication process.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What is bonding?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bonding is the process of storing security information after pairing so that the devices can establish trusted connections again later.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why is LightBlue used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LightBlue provides a convenient BLE client interface for discovering the ESP32, connecting to it, inspecting services and characteristics, and receiving notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Can the same application be used on Android and iOS?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. LightBlue is available for both Android and iOS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the role of the ESP32 in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the DHT11 sensor and acts as a BLE GATT server that provides the sensor data to the smartphone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is the difference between `READ` and `NOTIFY` in BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
`READ` allows the client to request the current value. `NOTIFY` allows the server to send updated values automatically when the client subscribes to notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. How is this experiment different from HTTPS-based cloud communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS protects communication between an IoT device and a web/cloud server over a network. This experiment demonstrates secure short-range BLE communication directly between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates how Bluetooth Low Energy can be used for secure IoT sensor-data transmission. The ESP32 reads temperature and humidity from the DHT11 sensor and exposes the readings through BLE characteristics. The smartphone connects using the LightBlue application, performs secure pairing, and receives the sensor data through an authenticated and encrypted BLE connection.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1382</id>
		<title>MDM331AID/Experiment 6</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1382"/>
		<updated>2026-10-08T02:39:01Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Edge Computing Using Raspberry Pi for Local Sensor Data Processing =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement an edge computing model using a Raspberry Pi in which sensor data is processed locally before being transmitted to the cloud, thereby reducing unnecessary data transmission, bandwidth usage, and response latency.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept and architecture of edge computing.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with a Raspberry Pi.&lt;br /&gt;
* To read temperature and humidity data from the DHT11 sensor using Python.&lt;br /&gt;
* To process and aggregate sensor readings locally on the Raspberry Pi.&lt;br /&gt;
* To implement threshold-based temperature event detection at the edge.&lt;br /&gt;
* To transmit processed sensor data to the ThingSpeak cloud platform using HTTP.&lt;br /&gt;
* To understand how edge processing can reduce unnecessary network traffic and improve response time.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Raspberry Pi 4 (4 GB) (COG-RPI4)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Temperature and Humidity Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| MicroSD card with Raspberry Pi OS&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Raspberry Pi power supply&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with internet access&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Wi-Fi network with Internet access&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edge computing&#039;&#039;&#039; is a distributed computing approach in which data is processed close to the source where it is generated instead of sending all raw data to a remote cloud server for processing.&lt;br /&gt;
&lt;br /&gt;
In a conventional cloud-based IoT system, sensor data may be transmitted continuously to a remote server where processing and decision-making are performed. In an edge computing system, a local device such as a Raspberry Pi performs some of the processing near the sensor. Only the required or processed information is then transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Raspberry Pi acts as the &#039;&#039;&#039;edge device&#039;&#039;&#039;. It reads temperature and humidity data from the DHT11 sensor, collects multiple readings, calculates their averages, performs a temperature threshold check, and sends the processed results to ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
=== Need for Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
The major advantages of edge computing include:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Reduced latency:&#039;&#039;&#039; Local processing allows decisions to be made without waiting for remote cloud processing.&lt;br /&gt;
* &#039;&#039;&#039;Reduced bandwidth usage:&#039;&#039;&#039; Processed or aggregated data can be transmitted instead of every raw sensor reading.&lt;br /&gt;
* &#039;&#039;&#039;Reduced cloud workload:&#039;&#039;&#039; Unnecessary raw data processing at the cloud can be reduced.&lt;br /&gt;
* &#039;&#039;&#039;Local decision-making:&#039;&#039;&#039; Conditions such as temperature thresholds can be checked directly on the edge device.&lt;br /&gt;
* &#039;&#039;&#039;Improved scalability:&#039;&#039;&#039; Reducing unnecessary network traffic can be beneficial when many IoT devices are deployed.&lt;br /&gt;
&lt;br /&gt;
=== Role of Raspberry Pi as an Edge Device ===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi acts as the local processing unit in this experiment. It receives temperature and humidity readings from the DHT11 sensor through GPIO4.&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi collects &#039;&#039;&#039;10 valid sensor readings&#039;&#039;&#039; and calculates the average temperature and average humidity locally. It then compares the average temperature with a predefined threshold of &#039;&#039;&#039;30°C&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If the average temperature is greater than or equal to 30°C, an alert condition is generated. The processed temperature, humidity and alert status are then transmitted to ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
=== DHT11 Temperature and Humidity Sensor ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital sensor capable of measuring temperature and relative humidity.&lt;br /&gt;
&lt;br /&gt;
The sensor provides temperature and humidity readings through a digital data interface. In this experiment, the DHT11 is connected to the Raspberry Pi and is read using the Adafruit CircuitPython DHT library.&lt;br /&gt;
&lt;br /&gt;
The DHT11 is suitable for basic environmental monitoring and IoT demonstrations because it provides both temperature and humidity measurements using a single data connection.&lt;br /&gt;
&lt;br /&gt;
=== Local Data Processing ===&lt;br /&gt;
&lt;br /&gt;
In this experiment, sensor data is processed locally on the Raspberry Pi before being transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
The processing sequence is:&lt;br /&gt;
&lt;br /&gt;
# The Raspberry Pi reads temperature and humidity from the DHT11.&lt;br /&gt;
# Valid readings are stored in local lists.&lt;br /&gt;
# The process continues until 10 valid readings are collected.&lt;br /&gt;
# The average temperature is calculated from the collected readings.&lt;br /&gt;
# The average humidity is calculated from the collected readings.&lt;br /&gt;
# The average temperature is compared with the threshold value of 30°C.&lt;br /&gt;
# An alert status is generated based on the threshold condition.&lt;br /&gt;
# The processed values are transmitted to ThingSpeak.&lt;br /&gt;
# The local data lists are cleared and the next batch of readings is collected.&lt;br /&gt;
&lt;br /&gt;
This approach demonstrates how edge computing can reduce the amount of raw sensor data that needs to be transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
=== Threshold-Based Event Detection ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to determine whether a measured parameter has reached a specified condition.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the temperature threshold is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature Threshold = 30°C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi performs the following check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Average Temperature &amp;gt;= 30°C&lt;br /&gt;
        |&lt;br /&gt;
        +---- Yes ----&amp;gt; Temperature Alert&lt;br /&gt;
        |&lt;br /&gt;
        +---- No -----&amp;gt; Normal Status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting alert status is converted into a numerical value before transmission to ThingSpeak:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Condition&lt;br /&gt;
! Alert Value&lt;br /&gt;
|-&lt;br /&gt;
| Average temperature &amp;lt; 30°C&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| Average temperature &amp;gt;= 30°C&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Cloud Communication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ThingSpeak&#039;&#039;&#039; is a cloud-based IoT platform that can be used to collect, store and visualize sensor data.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Raspberry Pi communicates with ThingSpeak using an &#039;&#039;&#039;HTTP POST request&#039;&#039;&#039;. The Python &#039;&#039;&#039;Requests&#039;&#039;&#039; library is used to send the processed sensor values to the ThingSpeak update API.&lt;br /&gt;
&lt;br /&gt;
The three transmitted values are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Field 1:&#039;&#039;&#039; Average Temperature&lt;br /&gt;
* &#039;&#039;&#039;Field 2:&#039;&#039;&#039; Average Humidity&lt;br /&gt;
* &#039;&#039;&#039;Field 3:&#039;&#039;&#039; Temperature Alert&lt;br /&gt;
&lt;br /&gt;
The ThingSpeak channel stores the received values and provides visualization of the uploaded sensor data.&lt;br /&gt;
&lt;br /&gt;
=== System Architecture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       DHT11 Sensor&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +----------------------+&lt;br /&gt;
     |    Raspberry Pi      |&lt;br /&gt;
     |     Edge Device      |&lt;br /&gt;
     |                      |&lt;br /&gt;
     |  Sensor Reading      |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Data Collection     |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Average Calculation |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Threshold Detection |&lt;br /&gt;
     +----------------------+&lt;br /&gt;
            |&lt;br /&gt;
            | Processed Data&lt;br /&gt;
            v&lt;br /&gt;
       Wi-Fi Network&lt;br /&gt;
            |&lt;br /&gt;
            | HTTP POST&lt;br /&gt;
            v&lt;br /&gt;
     +----------------------+&lt;br /&gt;
     |      ThingSpeak      |&lt;br /&gt;
     |    Cloud Platform    |&lt;br /&gt;
     |                      |&lt;br /&gt;
     |   Data Storage       |&lt;br /&gt;
     |   Visualization      |&lt;br /&gt;
     +----------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the Raspberry Pi using the following connections. The program initializes the sensor using &#039;&#039;&#039;board.D4&#039;&#039;&#039;, corresponding to &#039;&#039;&#039;GPIO4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Raspberry Pi Pin&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 1 (3.3V)&lt;br /&gt;
| VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 7 (GPIO4)&lt;br /&gt;
| DATA&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 6 (GND)&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; Raspberry Pi GPIO pins operate at 3.3 V logic and are &#039;&#039;&#039;not 5 V tolerant&#039;&#039;&#039;. Do not apply 5 V signals directly to Raspberry Pi GPIO pins. Verify the DHT11 module pinout before making connections.&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi OS&lt;br /&gt;
* Python 3&lt;br /&gt;
* Adafruit CircuitPython DHT library&lt;br /&gt;
* Adafruit Blinka library&lt;br /&gt;
* Requests Python library&lt;br /&gt;
* ThingSpeak account&lt;br /&gt;
* ThingSpeak channel with three fields&lt;br /&gt;
* Wi-Fi connection with Internet access&lt;br /&gt;
&lt;br /&gt;
=== Install Required Libraries ===&lt;br /&gt;
&lt;br /&gt;
If a Python virtual environment is being used, activate it before installing the required packages.&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install adafruit-circuitpython-dht&lt;br /&gt;
pip install adafruit-blinka&lt;br /&gt;
pip install requests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The required libraries provide the following functionality:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Adafruit CircuitPython DHT:&#039;&#039;&#039; Interfaces with the DHT11 sensor.&lt;br /&gt;
* &#039;&#039;&#039;Adafruit Blinka:&#039;&#039;&#039; Provides compatibility between CircuitPython libraries and Raspberry Pi hardware.&lt;br /&gt;
* &#039;&#039;&#039;Requests:&#039;&#039;&#039; Allows the Raspberry Pi to communicate with the ThingSpeak server using HTTP requests.&lt;br /&gt;
&lt;br /&gt;
== ThingSpeak Cloud Setup ==&lt;br /&gt;
&lt;br /&gt;
Create a ThingSpeak channel before running the program.&lt;br /&gt;
&lt;br /&gt;
Configure the channel with the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Name&lt;br /&gt;
! Data&lt;br /&gt;
|-&lt;br /&gt;
| Field 1&lt;br /&gt;
| Average Temperature&lt;br /&gt;
| Average temperature in °C&lt;br /&gt;
|-&lt;br /&gt;
| Field 2&lt;br /&gt;
| Average Humidity&lt;br /&gt;
| Average relative humidity in %&lt;br /&gt;
|-&lt;br /&gt;
| Field 3&lt;br /&gt;
| Temperature Alert&lt;br /&gt;
| 0 = Normal, 1 = Alert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After creating the channel:&lt;br /&gt;
&lt;br /&gt;
# Open the &#039;&#039;&#039;API Keys&#039;&#039;&#039; section of the ThingSpeak channel.&lt;br /&gt;
# Copy the channel&#039;s &#039;&#039;&#039;Write API Key&#039;&#039;&#039;.&lt;br /&gt;
# Replace the placeholder API key in the program with the actual Write API Key.&lt;br /&gt;
# Save the Python program.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Security Note:&#039;&#039;&#039; Do not publish or share the actual ThingSpeak Write API Key in publicly accessible code or documentation.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
The following Python program performs local sensor data aggregation and threshold detection on the Raspberry Pi. It uploads the processed data to ThingSpeak after every batch of 10 valid sensor readings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# 2026, Cognifront. Member of the IoT Kits family.&lt;br /&gt;
import time&lt;br /&gt;
import board&lt;br /&gt;
import adafruit_dht&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
# Sensor configuration&lt;br /&gt;
# board.D4 sets the pin configuration to BOARD, and uses pin 4&lt;br /&gt;
dht = adafruit_dht.DHT11(board.D4)&lt;br /&gt;
&lt;br /&gt;
# Cloud configuration&lt;br /&gt;
API_KEY = &amp;quot;YOUR_API_KEY_HERE&amp;quot;&lt;br /&gt;
THINGSPEAK_URL = &amp;quot;https://api.thingspeak.com/update&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Edge processing configuration&lt;br /&gt;
SAMPLE_INTERVAL = 2&lt;br /&gt;
SAMPLES_PER_BATCH = 10&lt;br /&gt;
TEMP_THRESHOLD = 30.0&lt;br /&gt;
&lt;br /&gt;
temperature_samples = []&lt;br /&gt;
humidity_samples = []&lt;br /&gt;
&lt;br /&gt;
def upload_to_cloud(avg_temp, avg_humidity, alert):&lt;br /&gt;
    payload = {&lt;br /&gt;
        &amp;quot;api_key&amp;quot;: API_KEY,&lt;br /&gt;
        &amp;quot;field1&amp;quot;: avg_temp,&lt;br /&gt;
        &amp;quot;field2&amp;quot;: avg_humidity,&lt;br /&gt;
        &amp;quot;field3&amp;quot;: int(alert)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        response = requests.post(&lt;br /&gt;
            THINGSPEAK_URL,&lt;br /&gt;
            data=payload,&lt;br /&gt;
            timeout=10&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        if response.status_code == 200 and response.text != &amp;quot;0&amp;quot;:&lt;br /&gt;
            print(&amp;quot;Cloud upload successful&amp;quot;)&lt;br /&gt;
            print(&amp;quot;Entry ID:&amp;quot;, response.text)&lt;br /&gt;
        else:&lt;br /&gt;
            print(&amp;quot;Cloud upload failed:&amp;quot;, response.text)&lt;br /&gt;
&lt;br /&gt;
    except requests.RequestException as error:&lt;br /&gt;
        print(&amp;quot;Network error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    print(&amp;quot;Raspberry Pi Edge Computing System Started&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            temperature = dht.temperature&lt;br /&gt;
            humidity = dht.humidity&lt;br /&gt;
&lt;br /&gt;
            if temperature is not None and humidity is not None:&lt;br /&gt;
                temperature_samples.append(temperature)&lt;br /&gt;
                humidity_samples.append(humidity)&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;Raw Temperature:&amp;quot;, temperature, &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Raw Humidity:&amp;quot;, humidity, &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            if len(temperature_samples) &amp;gt;= SAMPLES_PER_BATCH:&lt;br /&gt;
                # Local data aggregation&lt;br /&gt;
                avg_temp = sum(temperature_samples) / len(temperature_samples)&lt;br /&gt;
                avg_humidity = sum(humidity_samples) / len(humidity_samples)&lt;br /&gt;
&lt;br /&gt;
                # Local threshold-based decision&lt;br /&gt;
                alert = avg_temp &amp;gt;= TEMP_THRESHOLD&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;\n--- Edge Processing Result ---&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Temperature:&amp;quot;, round(avg_temp, 2), &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Humidity:&amp;quot;, round(avg_humidity, 2), &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                if alert:&lt;br /&gt;
                    print(&amp;quot;ALERT: Temperature threshold exceeded&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    print(&amp;quot;Status: Normal&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                # Send processed data to cloud&lt;br /&gt;
                upload_to_cloud(&lt;br /&gt;
                    round(avg_temp, 2),&lt;br /&gt;
                    round(avg_humidity, 2),&lt;br /&gt;
                    alert&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
                # Clear batch for next aggregation&lt;br /&gt;
                temperature_samples.clear()&lt;br /&gt;
                humidity_samples.clear()&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;------------------------------\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        except RuntimeError as error:&lt;br /&gt;
            # Temporary DHT11 reading errors&lt;br /&gt;
            print(&amp;quot;Sensor reading error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
        time.sleep(SAMPLE_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
except KeyboardInterrupt:&lt;br /&gt;
    print(&amp;quot;Program stopped by user&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
    dht.exit()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Statement&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import time&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides timing functions used to control the sensor reading interval.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import board&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides Raspberry Pi board pin definitions used by the sensor library.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import adafruit_dht&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import requests&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides HTTP communication with the ThingSpeak cloud server.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dht = adafruit_dht.DHT11(board.D4)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Initializes the DHT11 sensor on GPIO4.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;API_KEY&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the ThingSpeak channel Write API Key used for authentication.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;THINGSPEAK_URL&amp;lt;/code&amp;gt;&lt;br /&gt;
| Specifies the ThingSpeak update API endpoint.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SAMPLE_INTERVAL = 2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sets the delay between sensor-reading attempts to two seconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SAMPLES_PER_BATCH = 10&amp;lt;/code&amp;gt;&lt;br /&gt;
| Specifies that 10 valid sensor readings are collected before local processing.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TEMP_THRESHOLD = 30.0&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sets the temperature threshold to 30°C.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;temperature_samples.append(temperature)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores a valid temperature reading locally.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;humidity_samples.append(humidity)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores a valid humidity reading locally.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sum(temperature_samples) / len(temperature_samples)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Calculates the average temperature of the current batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sum(humidity_samples) / len(humidity_samples)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Calculates the average humidity of the current batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;avg_temp &amp;gt;= TEMP_THRESHOLD&amp;lt;/code&amp;gt;&lt;br /&gt;
| Performs the local threshold-based temperature check.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;requests.post()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sends the processed sensor values to ThingSpeak using an HTTP POST request.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field1&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the average temperature in ThingSpeak.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the average humidity in ThingSpeak.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field3&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the temperature alert status as 0 or 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;temperature_samples.clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clears the collected temperature readings after processing the batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;humidity_samples.clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clears the collected humidity readings after processing the batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dht.exit()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Releases the DHT sensor resources when the program terminates.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Hardware Setup ===&lt;br /&gt;
&lt;br /&gt;
# Switch off or disconnect the Raspberry Pi from its power supply before making the connections.&lt;br /&gt;
# Connect the DHT11 sensor to the Raspberry Pi according to the pin connection table.&lt;br /&gt;
# Connect DHT11 VCC to Raspberry Pi 3.3V.&lt;br /&gt;
# Connect DHT11 DATA to Raspberry Pi GPIO4 (Physical Pin 7).&lt;br /&gt;
# Connect DHT11 GND to Raspberry Pi GND (Physical Pin 6).&lt;br /&gt;
# Verify all connections before powering the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Software Setup ===&lt;br /&gt;
&lt;br /&gt;
# Boot the Raspberry Pi with Raspberry Pi OS.&lt;br /&gt;
# Connect the Raspberry Pi to a Wi-Fi network with Internet access.&lt;br /&gt;
# Open the terminal.&lt;br /&gt;
# Create and activate a Python virtual environment if required.&lt;br /&gt;
# Install the required Python libraries.&lt;br /&gt;
# Create a Python file, for example &amp;lt;code&amp;gt;edge_computing.py&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Enter the given program and save the file.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: ThingSpeak Setup ===&lt;br /&gt;
&lt;br /&gt;
# Sign in to ThingSpeak.&lt;br /&gt;
# Create a new channel.&lt;br /&gt;
# Enable three fields in the channel.&lt;br /&gt;
# Name Field 1 as &#039;&#039;&#039;Average Temperature&#039;&#039;&#039;.&lt;br /&gt;
# Name Field 2 as &#039;&#039;&#039;Average Humidity&#039;&#039;&#039;.&lt;br /&gt;
# Name Field 3 as &#039;&#039;&#039;Temperature Alert&#039;&#039;&#039;.&lt;br /&gt;
# Save the channel.&lt;br /&gt;
# Open the &#039;&#039;&#039;API Keys&#039;&#039;&#039; section.&lt;br /&gt;
# Copy the channel&#039;s &#039;&#039;&#039;Write API Key&#039;&#039;&#039;.&lt;br /&gt;
# Replace &amp;lt;code&amp;gt;YOUR_API_KEY_HERE&amp;lt;/code&amp;gt; in the program with the actual Write API Key.&lt;br /&gt;
# Save the Python program.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Execute the Program ===&lt;br /&gt;
&lt;br /&gt;
# Open the terminal on the Raspberry Pi.&lt;br /&gt;
# Navigate to the directory containing the Python program.&lt;br /&gt;
# Activate the Python virtual environment if one is being used.&lt;br /&gt;
# Run the program using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python edge_computing.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Observe the raw temperature and humidity readings displayed in the terminal.&lt;br /&gt;
# Allow the program to collect 10 valid readings.&lt;br /&gt;
# Observe the calculated average temperature and average humidity.&lt;br /&gt;
# Observe the threshold status displayed by the program.&lt;br /&gt;
# Check the cloud upload status and ThingSpeak Entry ID.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Verify Edge Processing ===&lt;br /&gt;
&lt;br /&gt;
# Observe that sensor readings are first stored locally on the Raspberry Pi.&lt;br /&gt;
# Verify that an average is calculated after 10 valid readings.&lt;br /&gt;
# Check whether the average temperature is below or equal to the threshold condition.&lt;br /&gt;
# If the average temperature is 30°C or higher, observe the temperature alert message.&lt;br /&gt;
# If the average temperature is below 30°C, observe the normal status message.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Verify ThingSpeak Data ===&lt;br /&gt;
&lt;br /&gt;
# Open the ThingSpeak channel.&lt;br /&gt;
# Open the channel visualization page.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 1&#039;&#039;&#039; for average temperature.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 2&#039;&#039;&#039; for average humidity.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 3&#039;&#039;&#039; for the temperature alert.&lt;br /&gt;
# Compare the values displayed on ThingSpeak with the processed values shown in the Raspberry Pi terminal.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Processing Stage&lt;br /&gt;
! Expected Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Sensor Reading&lt;br /&gt;
| Temperature and humidity readings from the DHT11 are displayed on the Raspberry Pi terminal.&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Local Data Collection&lt;br /&gt;
| Valid sensor readings are stored locally in the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Data Aggregation&lt;br /&gt;
| Average temperature and average humidity are calculated after 10 valid readings.&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Threshold Detection&lt;br /&gt;
| Temperature alert is generated when the average temperature is greater than or equal to 30°C.&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Cloud Transmission&lt;br /&gt;
| Average temperature, average humidity and alert status are transmitted to ThingSpeak using HTTP.&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Cloud Visualization&lt;br /&gt;
| Processed sensor values are stored and displayed in the ThingSpeak channel.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sample Serial Output ===&lt;br /&gt;
&lt;br /&gt;
The following is an illustrative example. Actual temperature and humidity values will depend on the environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raspberry Pi Edge Computing System Started&lt;br /&gt;
&lt;br /&gt;
Raw Temperature: 27.0 °C&lt;br /&gt;
Raw Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
Raw Temperature: 27.0 °C&lt;br /&gt;
Raw Humidity: 62.0 %&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--- Edge Processing Result ---&lt;br /&gt;
Average Temperature: 27.2 °C&lt;br /&gt;
Average Humidity: 61.7 %&lt;br /&gt;
Status: Normal&lt;br /&gt;
Cloud upload successful&lt;br /&gt;
Entry ID: 12345&lt;br /&gt;
------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The Entry ID shown above is only an example. The actual Entry ID is generated by ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
== Comparison: Cloud-Based vs Edge-Based Processing ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Cloud-Based Processing&lt;br /&gt;
! Edge-Based Processing&lt;br /&gt;
|-&lt;br /&gt;
| Data processing&lt;br /&gt;
| Performed primarily on a remote cloud server.&lt;br /&gt;
| Performed locally on the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| Data transmission&lt;br /&gt;
| Raw sensor readings may be transmitted continuously.&lt;br /&gt;
| Sensor readings are processed locally before transmission.&lt;br /&gt;
|-&lt;br /&gt;
| Bandwidth usage&lt;br /&gt;
| Can be higher when raw readings are continuously transmitted.&lt;br /&gt;
| Can be reduced by aggregating readings locally.&lt;br /&gt;
|-&lt;br /&gt;
| Response latency&lt;br /&gt;
| Depends on network communication and cloud processing.&lt;br /&gt;
| Local threshold decisions can be made directly on the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| Local decision-making&lt;br /&gt;
| Requires communication with the cloud when processing is remote.&lt;br /&gt;
| Threshold detection is performed locally.&lt;br /&gt;
|-&lt;br /&gt;
| Cloud workload&lt;br /&gt;
| Can increase when large amounts of raw data are uploaded.&lt;br /&gt;
| Reduced because processed values are transmitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An edge computing application was successfully implemented using a Raspberry Pi and DHT11 temperature and humidity sensor. The Raspberry Pi collected sensor readings and processed them locally by calculating the average temperature and humidity over a batch of 10 valid readings.&lt;br /&gt;
&lt;br /&gt;
A threshold-based temperature detection mechanism was implemented locally, using 30°C as the threshold. The processed temperature, humidity and alert status were then transmitted to the ThingSpeak cloud platform using HTTP.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrates how edge computing can perform local data processing and decision-making before transmitting relevant information to the cloud, thereby reducing unnecessary data transmission and supporting faster local responses.&lt;br /&gt;
&lt;br /&gt;
== Real-Life Applications ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Industrial condition monitoring:&#039;&#039;&#039; Temperature and humidity sensors can monitor machinery and industrial environments.&lt;br /&gt;
* &#039;&#039;&#039;Smart agriculture:&#039;&#039;&#039; Edge devices can locally process environmental sensor readings and transmit only important information to the cloud.&lt;br /&gt;
* &#039;&#039;&#039;Environmental monitoring:&#039;&#039;&#039; Local processing can be used to detect abnormal temperature or humidity conditions.&lt;br /&gt;
* &#039;&#039;&#039;Smart buildings:&#039;&#039;&#039; Edge devices can monitor environmental conditions and trigger local decisions.&lt;br /&gt;
* &#039;&#039;&#039;Predictive maintenance:&#039;&#039;&#039; Sensor data can be processed locally to detect abnormal operating conditions before transmitting summarized information to a cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is edge computing?&lt;br /&gt;
# What is the difference between edge computing and cloud computing?&lt;br /&gt;
# Why is Raspberry Pi used as an edge device in this experiment?&lt;br /&gt;
# What is the role of the DHT11 sensor?&lt;br /&gt;
# Which GPIO pin is used to connect the DHT11 data pin?&lt;br /&gt;
# Why is GPIO4 used in this experiment?&lt;br /&gt;
# How many sensor readings are collected before calculating the average?&lt;br /&gt;
# What is the purpose of &amp;lt;code&amp;gt;SAMPLE_INTERVAL&amp;lt;/code&amp;gt;?&lt;br /&gt;
# What is the value of the temperature threshold used in this experiment?&lt;br /&gt;
# What happens when the average temperature reaches or exceeds 30°C?&lt;br /&gt;
# What is the purpose of local data aggregation?&lt;br /&gt;
# How does edge computing reduce bandwidth usage?&lt;br /&gt;
# Which communication protocol is used to transmit data to ThingSpeak?&lt;br /&gt;
# What is the purpose of the HTTP POST request?&lt;br /&gt;
# What are Field 1, Field 2 and Field 3 used for in ThingSpeak?&lt;br /&gt;
# What is a ThingSpeak Write API Key?&lt;br /&gt;
# Why should the API key not be publicly shared?&lt;br /&gt;
# What is the purpose of the &amp;lt;code&amp;gt;requests&amp;lt;/code&amp;gt; Python library?&lt;br /&gt;
# What is the difference between raw sensor data and processed sensor data?&lt;br /&gt;
# What are the advantages of processing sensor data at the edge?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1381</id>
		<title>MDM331AID/Experiment 6</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1381"/>
		<updated>2026-10-08T02:38:35Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Edge Computing Using Raspberry Pi for Local Sensor Data Processing =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement an edge computing model using a Raspberry Pi in which sensor data is processed locally before being transmitted to the cloud, thereby reducing unnecessary data transmission, bandwidth usage, and response latency.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept and architecture of edge computing.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with a Raspberry Pi.&lt;br /&gt;
* To read temperature and humidity data from the DHT11 sensor using Python.&lt;br /&gt;
* To process and aggregate sensor readings locally on the Raspberry Pi.&lt;br /&gt;
* To implement threshold-based temperature event detection at the edge.&lt;br /&gt;
* To transmit processed sensor data to the ThingSpeak cloud platform using HTTP.&lt;br /&gt;
* To understand how edge processing can reduce unnecessary network traffic and improve response time.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Raspberry Pi 4 (4 GB) (COG-RPI4)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Temperature and Humidity Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| MicroSD card with Raspberry Pi OS&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Raspberry Pi power supply&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with internet access&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Wi-Fi network with Internet access&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edge computing&#039;&#039;&#039; is a distributed computing approach in which data is processed close to the source where it is generated instead of sending all raw data to a remote cloud server for processing.&lt;br /&gt;
&lt;br /&gt;
In a conventional cloud-based IoT system, sensor data may be transmitted continuously to a remote server where processing and decision-making are performed. In an edge computing system, a local device such as a Raspberry Pi performs some of the processing near the sensor. Only the required or processed information is then transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Raspberry Pi acts as the &#039;&#039;&#039;edge device&#039;&#039;&#039;. It reads temperature and humidity data from the DHT11 sensor, collects multiple readings, calculates their averages, performs a temperature threshold check, and sends the processed results to ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
=== Need for Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
The major advantages of edge computing include:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Reduced latency:&#039;&#039;&#039; Local processing allows decisions to be made without waiting for remote cloud processing.&lt;br /&gt;
* &#039;&#039;&#039;Reduced bandwidth usage:&#039;&#039;&#039; Processed or aggregated data can be transmitted instead of every raw sensor reading.&lt;br /&gt;
* &#039;&#039;&#039;Reduced cloud workload:&#039;&#039;&#039; Unnecessary raw data processing at the cloud can be reduced.&lt;br /&gt;
* &#039;&#039;&#039;Local decision-making:&#039;&#039;&#039; Conditions such as temperature thresholds can be checked directly on the edge device.&lt;br /&gt;
* &#039;&#039;&#039;Improved scalability:&#039;&#039;&#039; Reducing unnecessary network traffic can be beneficial when many IoT devices are deployed.&lt;br /&gt;
&lt;br /&gt;
=== Role of Raspberry Pi as an Edge Device ===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi acts as the local processing unit in this experiment. It receives temperature and humidity readings from the DHT11 sensor through GPIO4.&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi collects &#039;&#039;&#039;10 valid sensor readings&#039;&#039;&#039; and calculates the average temperature and average humidity locally. It then compares the average temperature with a predefined threshold of &#039;&#039;&#039;30°C&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
If the average temperature is greater than or equal to 30°C, an alert condition is generated. The processed temperature, humidity and alert status are then transmitted to ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
=== DHT11 Temperature and Humidity Sensor ===&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital sensor capable of measuring temperature and relative humidity.&lt;br /&gt;
&lt;br /&gt;
The sensor provides temperature and humidity readings through a digital data interface. In this experiment, the DHT11 is connected to the Raspberry Pi and is read using the Adafruit CircuitPython DHT library.&lt;br /&gt;
&lt;br /&gt;
The DHT11 is suitable for basic environmental monitoring and IoT demonstrations because it provides both temperature and humidity measurements using a single data connection.&lt;br /&gt;
&lt;br /&gt;
=== Local Data Processing ===&lt;br /&gt;
&lt;br /&gt;
In this experiment, sensor data is processed locally on the Raspberry Pi before being transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
The processing sequence is:&lt;br /&gt;
&lt;br /&gt;
# The Raspberry Pi reads temperature and humidity from the DHT11.&lt;br /&gt;
# Valid readings are stored in local lists.&lt;br /&gt;
# The process continues until 10 valid readings are collected.&lt;br /&gt;
# The average temperature is calculated from the collected readings.&lt;br /&gt;
# The average humidity is calculated from the collected readings.&lt;br /&gt;
# The average temperature is compared with the threshold value of 30°C.&lt;br /&gt;
# An alert status is generated based on the threshold condition.&lt;br /&gt;
# The processed values are transmitted to ThingSpeak.&lt;br /&gt;
# The local data lists are cleared and the next batch of readings is collected.&lt;br /&gt;
&lt;br /&gt;
This approach demonstrates how edge computing can reduce the amount of raw sensor data that needs to be transmitted to the cloud.&lt;br /&gt;
&lt;br /&gt;
=== Threshold-Based Event Detection ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to determine whether a measured parameter has reached a specified condition.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the temperature threshold is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature Threshold = 30°C&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi performs the following check:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Average Temperature &amp;gt;= 30°C&lt;br /&gt;
        |&lt;br /&gt;
        +---- Yes ----&amp;gt; Temperature Alert&lt;br /&gt;
        |&lt;br /&gt;
        +---- No -----&amp;gt; Normal Status&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting alert status is converted into a numerical value before transmission to ThingSpeak:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Condition&lt;br /&gt;
! Alert Value&lt;br /&gt;
|-&lt;br /&gt;
| Average temperature &amp;lt; 30°C&lt;br /&gt;
| 0&lt;br /&gt;
|-&lt;br /&gt;
| Average temperature &amp;gt;= 30°C&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Cloud Communication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ThingSpeak&#039;&#039;&#039; is a cloud-based IoT platform that can be used to collect, store and visualize sensor data.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Raspberry Pi communicates with ThingSpeak using an &#039;&#039;&#039;HTTP POST request&#039;&#039;&#039;. The Python &#039;&#039;&#039;Requests&#039;&#039;&#039; library is used to send the processed sensor values to the ThingSpeak update API.&lt;br /&gt;
&lt;br /&gt;
The three transmitted values are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Field 1:&#039;&#039;&#039; Average Temperature&lt;br /&gt;
* &#039;&#039;&#039;Field 2:&#039;&#039;&#039; Average Humidity&lt;br /&gt;
* &#039;&#039;&#039;Field 3:&#039;&#039;&#039; Temperature Alert&lt;br /&gt;
&lt;br /&gt;
The ThingSpeak channel stores the received values and provides visualization of the uploaded sensor data.&lt;br /&gt;
&lt;br /&gt;
=== System Architecture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       DHT11 Sensor&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +----------------------+&lt;br /&gt;
     |    Raspberry Pi      |&lt;br /&gt;
     |     Edge Device      |&lt;br /&gt;
     |                      |&lt;br /&gt;
     |  Sensor Reading      |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Data Collection     |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Average Calculation |&lt;br /&gt;
     |        ↓             |&lt;br /&gt;
     |  Threshold Detection |&lt;br /&gt;
     +----------------------+&lt;br /&gt;
            |&lt;br /&gt;
            | Processed Data&lt;br /&gt;
            v&lt;br /&gt;
       Wi-Fi Network&lt;br /&gt;
            |&lt;br /&gt;
            | HTTP POST&lt;br /&gt;
            v&lt;br /&gt;
     +----------------------+&lt;br /&gt;
     |      ThingSpeak      |&lt;br /&gt;
     |    Cloud Platform    |&lt;br /&gt;
     |                      |&lt;br /&gt;
     |   Data Storage       |&lt;br /&gt;
     |   Visualization      |&lt;br /&gt;
     +----------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the Raspberry Pi using the following connections. The program initializes the sensor using &#039;&#039;&#039;board.D4&#039;&#039;&#039;, corresponding to &#039;&#039;&#039;GPIO4&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Raspberry Pi Pin&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 1 (3.3V)&lt;br /&gt;
| VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 7 (GPIO4)&lt;br /&gt;
| DATA&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 6 (GND)&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; Raspberry Pi GPIO pins operate at 3.3 V logic and are &#039;&#039;&#039;not 5 V tolerant&#039;&#039;&#039;. Do not apply 5 V signals directly to Raspberry Pi GPIO pins. Verify the DHT11 module pinout before making connections.&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi OS&lt;br /&gt;
* Python 3&lt;br /&gt;
* Adafruit CircuitPython DHT library&lt;br /&gt;
* Adafruit Blinka library&lt;br /&gt;
* Requests Python library&lt;br /&gt;
* ThingSpeak account&lt;br /&gt;
* ThingSpeak channel with three fields&lt;br /&gt;
* Wi-Fi connection with Internet access&lt;br /&gt;
&lt;br /&gt;
=== Install Required Libraries ===&lt;br /&gt;
&lt;br /&gt;
If a Python virtual environment is being used, activate it before installing the required packages.&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install adafruit-circuitpython-dht&lt;br /&gt;
pip install adafruit-blinka&lt;br /&gt;
pip install requests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The required libraries provide the following functionality:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Adafruit CircuitPython DHT:&#039;&#039;&#039; Interfaces with the DHT11 sensor.&lt;br /&gt;
* &#039;&#039;&#039;Adafruit Blinka:&#039;&#039;&#039; Provides compatibility between CircuitPython libraries and Raspberry Pi hardware.&lt;br /&gt;
* &#039;&#039;&#039;Requests:&#039;&#039;&#039; Allows the Raspberry Pi to communicate with the ThingSpeak server using HTTP requests.&lt;br /&gt;
&lt;br /&gt;
== ThingSpeak Cloud Setup ==&lt;br /&gt;
&lt;br /&gt;
Create a ThingSpeak channel before running the program.&lt;br /&gt;
&lt;br /&gt;
Configure the channel with the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Field&lt;br /&gt;
! Name&lt;br /&gt;
! Data&lt;br /&gt;
|-&lt;br /&gt;
| Field 1&lt;br /&gt;
| Average Temperature&lt;br /&gt;
| Average temperature in °C&lt;br /&gt;
|-&lt;br /&gt;
| Field 2&lt;br /&gt;
| Average Humidity&lt;br /&gt;
| Average relative humidity in %&lt;br /&gt;
|-&lt;br /&gt;
| Field 3&lt;br /&gt;
| Temperature Alert&lt;br /&gt;
| 0 = Normal, 1 = Alert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After creating the channel:&lt;br /&gt;
&lt;br /&gt;
# Open the &#039;&#039;&#039;API Keys&#039;&#039;&#039; section of the ThingSpeak channel.&lt;br /&gt;
# Copy the channel&#039;s &#039;&#039;&#039;Write API Key&#039;&#039;&#039;.&lt;br /&gt;
# Replace the placeholder API key in the program with the actual Write API Key.&lt;br /&gt;
# Save the Python program.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Security Note:&#039;&#039;&#039; Do not publish or share the actual ThingSpeak Write API Key in publicly accessible code or documentation.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
The following Python program performs local sensor data aggregation and threshold detection on the Raspberry Pi. It uploads the processed data to ThingSpeak after every batch of 10 valid sensor readings.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# 2026, Cognifront. Member of the IoT Kits family.&lt;br /&gt;
import time&lt;br /&gt;
import board&lt;br /&gt;
import adafruit_dht&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
# Sensor configuration&lt;br /&gt;
# board.D4 sets the pin configuration to BOARD, and uses pin 4&lt;br /&gt;
dht = adafruit_dht.DHT11(board.D4)&lt;br /&gt;
&lt;br /&gt;
# Cloud configuration&lt;br /&gt;
API_KEY = &amp;quot;YOUR_API_KEY_HERE&amp;quot;&lt;br /&gt;
THINGSPEAK_URL = &amp;quot;https://api.thingspeak.com/update&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Edge processing configuration&lt;br /&gt;
SAMPLE_INTERVAL = 2&lt;br /&gt;
SAMPLES_PER_BATCH = 10&lt;br /&gt;
TEMP_THRESHOLD = 30.0&lt;br /&gt;
&lt;br /&gt;
temperature_samples = []&lt;br /&gt;
humidity_samples = []&lt;br /&gt;
&lt;br /&gt;
def upload_to_cloud(avg_temp, avg_humidity, alert):&lt;br /&gt;
    payload = {&lt;br /&gt;
        &amp;quot;api_key&amp;quot;: API_KEY,&lt;br /&gt;
        &amp;quot;field1&amp;quot;: avg_temp,&lt;br /&gt;
        &amp;quot;field2&amp;quot;: avg_humidity,&lt;br /&gt;
        &amp;quot;field3&amp;quot;: int(alert)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        response = requests.post(&lt;br /&gt;
            THINGSPEAK_URL,&lt;br /&gt;
            data=payload,&lt;br /&gt;
            timeout=10&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        if response.status_code == 200 and response.text != &amp;quot;0&amp;quot;:&lt;br /&gt;
            print(&amp;quot;Cloud upload successful&amp;quot;)&lt;br /&gt;
            print(&amp;quot;Entry ID:&amp;quot;, response.text)&lt;br /&gt;
        else:&lt;br /&gt;
            print(&amp;quot;Cloud upload failed:&amp;quot;, response.text)&lt;br /&gt;
&lt;br /&gt;
    except requests.RequestException as error:&lt;br /&gt;
        print(&amp;quot;Network error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    print(&amp;quot;Raspberry Pi Edge Computing System Started&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            temperature = dht.temperature&lt;br /&gt;
            humidity = dht.humidity&lt;br /&gt;
&lt;br /&gt;
            if temperature is not None and humidity is not None:&lt;br /&gt;
                temperature_samples.append(temperature)&lt;br /&gt;
                humidity_samples.append(humidity)&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;Raw Temperature:&amp;quot;, temperature, &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Raw Humidity:&amp;quot;, humidity, &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            if len(temperature_samples) &amp;gt;= SAMPLES_PER_BATCH:&lt;br /&gt;
                # Local data aggregation&lt;br /&gt;
                avg_temp = sum(temperature_samples) / len(temperature_samples)&lt;br /&gt;
                avg_humidity = sum(humidity_samples) / len(humidity_samples)&lt;br /&gt;
&lt;br /&gt;
                # Local threshold-based decision&lt;br /&gt;
                alert = avg_temp &amp;gt;= TEMP_THRESHOLD&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;\n--- Edge Processing Result ---&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Temperature:&amp;quot;, round(avg_temp, 2), &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Humidity:&amp;quot;, round(avg_humidity, 2), &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                if alert:&lt;br /&gt;
                    print(&amp;quot;ALERT: Temperature threshold exceeded&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    print(&amp;quot;Status: Normal&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                # Send processed data to cloud&lt;br /&gt;
                upload_to_cloud(&lt;br /&gt;
                    round(avg_temp, 2),&lt;br /&gt;
                    round(avg_humidity, 2),&lt;br /&gt;
                    alert&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
                # Clear batch for next aggregation&lt;br /&gt;
                temperature_samples.clear()&lt;br /&gt;
                humidity_samples.clear()&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;------------------------------\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        except RuntimeError as error:&lt;br /&gt;
            # Temporary DHT11 reading errors&lt;br /&gt;
            print(&amp;quot;Sensor reading error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
        time.sleep(SAMPLE_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
except KeyboardInterrupt:&lt;br /&gt;
    print(&amp;quot;Program stopped by user&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
    dht.exit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Statement&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import time&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides timing functions used to control the sensor reading interval.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import board&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides Raspberry Pi board pin definitions used by the sensor library.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import adafruit_dht&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;import requests&amp;lt;/code&amp;gt;&lt;br /&gt;
| Provides HTTP communication with the ThingSpeak cloud server.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dht = adafruit_dht.DHT11(board.D4)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Initializes the DHT11 sensor on GPIO4.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;API_KEY&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the ThingSpeak channel Write API Key used for authentication.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;THINGSPEAK_URL&amp;lt;/code&amp;gt;&lt;br /&gt;
| Specifies the ThingSpeak update API endpoint.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SAMPLE_INTERVAL = 2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sets the delay between sensor-reading attempts to two seconds.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SAMPLES_PER_BATCH = 10&amp;lt;/code&amp;gt;&lt;br /&gt;
| Specifies that 10 valid sensor readings are collected before local processing.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;TEMP_THRESHOLD = 30.0&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sets the temperature threshold to 30°C.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;temperature_samples.append(temperature)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores a valid temperature reading locally.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;humidity_samples.append(humidity)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores a valid humidity reading locally.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sum(temperature_samples) / len(temperature_samples)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Calculates the average temperature of the current batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;sum(humidity_samples) / len(humidity_samples)&amp;lt;/code&amp;gt;&lt;br /&gt;
| Calculates the average humidity of the current batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;avg_temp &amp;gt;= TEMP_THRESHOLD&amp;lt;/code&amp;gt;&lt;br /&gt;
| Performs the local threshold-based temperature check.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;requests.post()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Sends the processed sensor values to ThingSpeak using an HTTP POST request.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field1&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the average temperature in ThingSpeak.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field2&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the average humidity in ThingSpeak.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;field3&amp;lt;/code&amp;gt;&lt;br /&gt;
| Stores the temperature alert status as 0 or 1.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;temperature_samples.clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clears the collected temperature readings after processing the batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;humidity_samples.clear()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Clears the collected humidity readings after processing the batch.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;dht.exit()&amp;lt;/code&amp;gt;&lt;br /&gt;
| Releases the DHT sensor resources when the program terminates.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Hardware Setup ===&lt;br /&gt;
&lt;br /&gt;
# Switch off or disconnect the Raspberry Pi from its power supply before making the connections.&lt;br /&gt;
# Connect the DHT11 sensor to the Raspberry Pi according to the pin connection table.&lt;br /&gt;
# Connect DHT11 VCC to Raspberry Pi 3.3V.&lt;br /&gt;
# Connect DHT11 DATA to Raspberry Pi GPIO4 (Physical Pin 7).&lt;br /&gt;
# Connect DHT11 GND to Raspberry Pi GND (Physical Pin 6).&lt;br /&gt;
# Verify all connections before powering the Raspberry Pi.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Software Setup ===&lt;br /&gt;
&lt;br /&gt;
# Boot the Raspberry Pi with Raspberry Pi OS.&lt;br /&gt;
# Connect the Raspberry Pi to a Wi-Fi network with Internet access.&lt;br /&gt;
# Open the terminal.&lt;br /&gt;
# Create and activate a Python virtual environment if required.&lt;br /&gt;
# Install the required Python libraries.&lt;br /&gt;
# Create a Python file, for example &amp;lt;code&amp;gt;edge_computing.py&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Enter the given program and save the file.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: ThingSpeak Setup ===&lt;br /&gt;
&lt;br /&gt;
# Sign in to ThingSpeak.&lt;br /&gt;
# Create a new channel.&lt;br /&gt;
# Enable three fields in the channel.&lt;br /&gt;
# Name Field 1 as &#039;&#039;&#039;Average Temperature&#039;&#039;&#039;.&lt;br /&gt;
# Name Field 2 as &#039;&#039;&#039;Average Humidity&#039;&#039;&#039;.&lt;br /&gt;
# Name Field 3 as &#039;&#039;&#039;Temperature Alert&#039;&#039;&#039;.&lt;br /&gt;
# Save the channel.&lt;br /&gt;
# Open the &#039;&#039;&#039;API Keys&#039;&#039;&#039; section.&lt;br /&gt;
# Copy the channel&#039;s &#039;&#039;&#039;Write API Key&#039;&#039;&#039;.&lt;br /&gt;
# Replace &amp;lt;code&amp;gt;YOUR_API_KEY_HERE&amp;lt;/code&amp;gt; in the program with the actual Write API Key.&lt;br /&gt;
# Save the Python program.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Execute the Program ===&lt;br /&gt;
&lt;br /&gt;
# Open the terminal on the Raspberry Pi.&lt;br /&gt;
# Navigate to the directory containing the Python program.&lt;br /&gt;
# Activate the Python virtual environment if one is being used.&lt;br /&gt;
# Run the program using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python edge_computing.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Observe the raw temperature and humidity readings displayed in the terminal.&lt;br /&gt;
# Allow the program to collect 10 valid readings.&lt;br /&gt;
# Observe the calculated average temperature and average humidity.&lt;br /&gt;
# Observe the threshold status displayed by the program.&lt;br /&gt;
# Check the cloud upload status and ThingSpeak Entry ID.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Verify Edge Processing ===&lt;br /&gt;
&lt;br /&gt;
# Observe that sensor readings are first stored locally on the Raspberry Pi.&lt;br /&gt;
# Verify that an average is calculated after 10 valid readings.&lt;br /&gt;
# Check whether the average temperature is below or equal to the threshold condition.&lt;br /&gt;
# If the average temperature is 30°C or higher, observe the temperature alert message.&lt;br /&gt;
# If the average temperature is below 30°C, observe the normal status message.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Verify ThingSpeak Data ===&lt;br /&gt;
&lt;br /&gt;
# Open the ThingSpeak channel.&lt;br /&gt;
# Open the channel visualization page.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 1&#039;&#039;&#039; for average temperature.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 2&#039;&#039;&#039; for average humidity.&lt;br /&gt;
# Observe the value in &#039;&#039;&#039;Field 3&#039;&#039;&#039; for the temperature alert.&lt;br /&gt;
# Compare the values displayed on ThingSpeak with the processed values shown in the Raspberry Pi terminal.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Processing Stage&lt;br /&gt;
! Expected Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Sensor Reading&lt;br /&gt;
| Temperature and humidity readings from the DHT11 are displayed on the Raspberry Pi terminal.&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Local Data Collection&lt;br /&gt;
| Valid sensor readings are stored locally in the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Data Aggregation&lt;br /&gt;
| Average temperature and average humidity are calculated after 10 valid readings.&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Threshold Detection&lt;br /&gt;
| Temperature alert is generated when the average temperature is greater than or equal to 30°C.&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Cloud Transmission&lt;br /&gt;
| Average temperature, average humidity and alert status are transmitted to ThingSpeak using HTTP.&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Cloud Visualization&lt;br /&gt;
| Processed sensor values are stored and displayed in the ThingSpeak channel.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Sample Serial Output ===&lt;br /&gt;
&lt;br /&gt;
The following is an illustrative example. Actual temperature and humidity values will depend on the environment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raspberry Pi Edge Computing System Started&lt;br /&gt;
&lt;br /&gt;
Raw Temperature: 27.0 °C&lt;br /&gt;
Raw Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
Raw Temperature: 27.0 °C&lt;br /&gt;
Raw Humidity: 62.0 %&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--- Edge Processing Result ---&lt;br /&gt;
Average Temperature: 27.2 °C&lt;br /&gt;
Average Humidity: 61.7 %&lt;br /&gt;
Status: Normal&lt;br /&gt;
Cloud upload successful&lt;br /&gt;
Entry ID: 12345&lt;br /&gt;
------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The Entry ID shown above is only an example. The actual Entry ID is generated by ThingSpeak.&lt;br /&gt;
&lt;br /&gt;
== Comparison: Cloud-Based vs Edge-Based Processing ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Cloud-Based Processing&lt;br /&gt;
! Edge-Based Processing&lt;br /&gt;
|-&lt;br /&gt;
| Data processing&lt;br /&gt;
| Performed primarily on a remote cloud server.&lt;br /&gt;
| Performed locally on the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| Data transmission&lt;br /&gt;
| Raw sensor readings may be transmitted continuously.&lt;br /&gt;
| Sensor readings are processed locally before transmission.&lt;br /&gt;
|-&lt;br /&gt;
| Bandwidth usage&lt;br /&gt;
| Can be higher when raw readings are continuously transmitted.&lt;br /&gt;
| Can be reduced by aggregating readings locally.&lt;br /&gt;
|-&lt;br /&gt;
| Response latency&lt;br /&gt;
| Depends on network communication and cloud processing.&lt;br /&gt;
| Local threshold decisions can be made directly on the Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| Local decision-making&lt;br /&gt;
| Requires communication with the cloud when processing is remote.&lt;br /&gt;
| Threshold detection is performed locally.&lt;br /&gt;
|-&lt;br /&gt;
| Cloud workload&lt;br /&gt;
| Can increase when large amounts of raw data are uploaded.&lt;br /&gt;
| Reduced because processed values are transmitted.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An edge computing application was successfully implemented using a Raspberry Pi and DHT11 temperature and humidity sensor. The Raspberry Pi collected sensor readings and processed them locally by calculating the average temperature and humidity over a batch of 10 valid readings.&lt;br /&gt;
&lt;br /&gt;
A threshold-based temperature detection mechanism was implemented locally, using 30°C as the threshold. The processed temperature, humidity and alert status were then transmitted to the ThingSpeak cloud platform using HTTP.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrates how edge computing can perform local data processing and decision-making before transmitting relevant information to the cloud, thereby reducing unnecessary data transmission and supporting faster local responses.&lt;br /&gt;
&lt;br /&gt;
== Real-Life Applications ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Industrial condition monitoring:&#039;&#039;&#039; Temperature and humidity sensors can monitor machinery and industrial environments.&lt;br /&gt;
* &#039;&#039;&#039;Smart agriculture:&#039;&#039;&#039; Edge devices can locally process environmental sensor readings and transmit only important information to the cloud.&lt;br /&gt;
* &#039;&#039;&#039;Environmental monitoring:&#039;&#039;&#039; Local processing can be used to detect abnormal temperature or humidity conditions.&lt;br /&gt;
* &#039;&#039;&#039;Smart buildings:&#039;&#039;&#039; Edge devices can monitor environmental conditions and trigger local decisions.&lt;br /&gt;
* &#039;&#039;&#039;Predictive maintenance:&#039;&#039;&#039; Sensor data can be processed locally to detect abnormal operating conditions before transmitting summarized information to a cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is edge computing?&lt;br /&gt;
# What is the difference between edge computing and cloud computing?&lt;br /&gt;
# Why is Raspberry Pi used as an edge device in this experiment?&lt;br /&gt;
# What is the role of the DHT11 sensor?&lt;br /&gt;
# Which GPIO pin is used to connect the DHT11 data pin?&lt;br /&gt;
# Why is GPIO4 used in this experiment?&lt;br /&gt;
# How many sensor readings are collected before calculating the average?&lt;br /&gt;
# What is the purpose of &amp;lt;code&amp;gt;SAMPLE_INTERVAL&amp;lt;/code&amp;gt;?&lt;br /&gt;
# What is the value of the temperature threshold used in this experiment?&lt;br /&gt;
# What happens when the average temperature reaches or exceeds 30°C?&lt;br /&gt;
# What is the purpose of local data aggregation?&lt;br /&gt;
# How does edge computing reduce bandwidth usage?&lt;br /&gt;
# Which communication protocol is used to transmit data to ThingSpeak?&lt;br /&gt;
# What is the purpose of the HTTP POST request?&lt;br /&gt;
# What are Field 1, Field 2 and Field 3 used for in ThingSpeak?&lt;br /&gt;
# What is a ThingSpeak Write API Key?&lt;br /&gt;
# Why should the API key not be publicly shared?&lt;br /&gt;
# What is the purpose of the &amp;lt;code&amp;gt;requests&amp;lt;/code&amp;gt; Python library?&lt;br /&gt;
# What is the difference between raw sensor data and processed sensor data?&lt;br /&gt;
# What are the advantages of processing sensor data at the edge?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1380</id>
		<title>MDM331AID/Experiment 6</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_6&amp;diff=1380"/>
		<updated>2026-10-08T02:30:33Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Edge Computing Using Raspberry Pi for Local Sensor Data Processing =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement an edge computing model using a Raspberry Pi in which sensor data is processed locally before being transmitted to the cloud, thereby reducing unnecessary data transmission, bandwidth usage, and response latency.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept and architecture of edge computing.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with Raspberry Pi.&lt;br /&gt;
* To process sensor readings locally using Python.&lt;br /&gt;
* To implement threshold-based event detection at the edge.&lt;br /&gt;
* To transmit processed sensor data to a cloud platform.&lt;br /&gt;
* To understand how edge computing can reduce network traffic and improve response time.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Raspberry Pi 4 (4 GB) (COG-RPI4)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Temperature and Humidity Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| MicroSD card with Raspberry Pi OS&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Raspberry Pi power supply&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with internet access&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Wi-Fi network&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
Edge computing is a distributed computing approach in which data is processed close to the source where it is generated rather than sending all raw data to a remote cloud server.&lt;br /&gt;
&lt;br /&gt;
In a conventional cloud-based model, sensor data is transmitted to the cloud for processing. In an edge computing model, a local device such as a Raspberry Pi performs data processing and sends only relevant information to the cloud.&lt;br /&gt;
&lt;br /&gt;
=== Need for Edge Computing ===&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Reduced latency:&#039;&#039;&#039; Local processing avoids waiting for a remote server for immediate decisions.&lt;br /&gt;
* &#039;&#039;&#039;Reduced bandwidth usage:&#039;&#039;&#039; Only selected or processed data is transmitted instead of every raw sensor reading.&lt;br /&gt;
* &#039;&#039;&#039;Improved reliability:&#039;&#039;&#039; Local processing can continue even during temporary internet disconnections.&lt;br /&gt;
* &#039;&#039;&#039;Better scalability:&#039;&#039;&#039; Reducing unnecessary cloud traffic can help support larger deployments.&lt;br /&gt;
* &#039;&#039;&#039;Local decision-making:&#039;&#039;&#039; Threshold detection and other control operations can be performed directly on the edge device.&lt;br /&gt;
&lt;br /&gt;
=== Role of Raspberry Pi as an Edge Device ===&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi acts as an edge computing device in this experiment. It reads sensor data, processes the readings locally, detects abnormal conditions, and prepares summarized data for cloud transmission.&lt;br /&gt;
&lt;br /&gt;
=== DHT11 Sensor ===&lt;br /&gt;
&lt;br /&gt;
The DHT11 is a digital sensor used to measure temperature and relative humidity.&lt;br /&gt;
&lt;br /&gt;
Typical operating measurement ranges are:&lt;br /&gt;
&lt;br /&gt;
* Temperature: 0°C to 50°C.&lt;br /&gt;
* Relative humidity: 20% to 90%.&lt;br /&gt;
&lt;br /&gt;
The sensor provides digital readings through a single data interface.&lt;br /&gt;
&lt;br /&gt;
=== Local Data Processing ===&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Raspberry Pi reads temperature and humidity values at regular intervals.&lt;br /&gt;
&lt;br /&gt;
The following processing operations are performed locally:&lt;br /&gt;
&lt;br /&gt;
* Calculate average temperature and humidity over a group of readings.&lt;br /&gt;
* Compare the average temperature with a predefined threshold.&lt;br /&gt;
* Generate a local alert if the threshold is exceeded.&lt;br /&gt;
* Transmit processed values and alert status to the cloud rather than uploading every individual reading.&lt;br /&gt;
&lt;br /&gt;
=== Cloud Communication ===&lt;br /&gt;
&lt;br /&gt;
A cloud platform can store and visualize the processed sensor information. In this experiment, ThingSpeak is used as an example cloud service.&lt;br /&gt;
&lt;br /&gt;
The Raspberry Pi sends processed data using an HTTP request. The cloud platform stores the submitted values for visualization and further analysis.&lt;br /&gt;
&lt;br /&gt;
=== System Architecture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       DHT11 Sensor&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +------------------+&lt;br /&gt;
     |   Raspberry Pi   |&lt;br /&gt;
     |   Edge Device    |&lt;br /&gt;
     |                  |&lt;br /&gt;
     | Sensor Reading   |&lt;br /&gt;
     | Local Processing |&lt;br /&gt;
     | Threshold Check  |&lt;br /&gt;
     | Data Aggregation |&lt;br /&gt;
     +------------------+&lt;br /&gt;
            |&lt;br /&gt;
       Processed Data&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
        Wi-Fi Network&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +------------------+&lt;br /&gt;
     | Cloud Platform   |&lt;br /&gt;
     |   ThingSpeak     |&lt;br /&gt;
     |                  |&lt;br /&gt;
     | Data Storage     |&lt;br /&gt;
     | Visualization    |&lt;br /&gt;
     +------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Raspberry Pi Pin&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 1 (3.3V)&lt;br /&gt;
| VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 7 (GPIO4)&lt;br /&gt;
| DATA&lt;br /&gt;
| Digital data interface&lt;br /&gt;
|-&lt;br /&gt;
| Physical Pin 6 (GND)&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These connections assume a DHT11 module with compatible 3.3V logic levels and the indicated pin labels. Verify the actual sensor-board pinout before connecting. Raspberry Pi GPIO pins are not 5V tolerant.&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi OS&lt;br /&gt;
* Python 3&lt;br /&gt;
* Adafruit CircuitPython DHT library&lt;br /&gt;
* Adafruit Blinka library&lt;br /&gt;
* Requests Python library&lt;br /&gt;
* ThingSpeak account and channel&lt;br /&gt;
&lt;br /&gt;
=== Install Required Libraries ===&lt;br /&gt;
&lt;br /&gt;
If using a Python virtual environment, activate it first. Install the required packages using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pip install adafruit-circuitpython-dht&lt;br /&gt;
pip install adafruit-blinka&lt;br /&gt;
pip install requests&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the DHT library requires additional system dependencies, install them according to the library&#039;s installation instructions for your Raspberry Pi OS version.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
The following Python program performs local sensor data aggregation and threshold detection on the Raspberry Pi. It uploads the processed data to ThingSpeak every 20 seconds.&lt;br /&gt;
&lt;br /&gt;
Create a ThingSpeak channel with the following fields:&lt;br /&gt;
&lt;br /&gt;
* Field 1: Average Temperature&lt;br /&gt;
* Field 2: Average Humidity&lt;br /&gt;
* Field 3: Temperature Alert&lt;br /&gt;
&lt;br /&gt;
Replace the API key with the channel&#039;s Write API Key.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# 2026, Cognifront. Member of the IoT Kits family.&lt;br /&gt;
import time&lt;br /&gt;
import board&lt;br /&gt;
import adafruit_dht&lt;br /&gt;
import requests&lt;br /&gt;
&lt;br /&gt;
# Sensor configuration&lt;br /&gt;
# board.D4 sets the pin configuration to BOARD, and uses pin 4&lt;br /&gt;
dht = adafruit_dht.DHT11(board.D4)&lt;br /&gt;
&lt;br /&gt;
# Cloud configuration&lt;br /&gt;
API_KEY = &amp;quot;YOUR_API_KEY_HERE&amp;quot;&lt;br /&gt;
THINGSPEAK_URL = &amp;quot;https://api.thingspeak.com/update&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Edge processing configuration&lt;br /&gt;
SAMPLE_INTERVAL = 2&lt;br /&gt;
SAMPLES_PER_BATCH = 10&lt;br /&gt;
TEMP_THRESHOLD = 30.0&lt;br /&gt;
&lt;br /&gt;
temperature_samples = []&lt;br /&gt;
humidity_samples = []&lt;br /&gt;
&lt;br /&gt;
def upload_to_cloud(avg_temp, avg_humidity, alert):&lt;br /&gt;
    payload = {&lt;br /&gt;
        &amp;quot;api_key&amp;quot;: API_KEY,&lt;br /&gt;
        &amp;quot;field1&amp;quot;: avg_temp,&lt;br /&gt;
        &amp;quot;field2&amp;quot;: avg_humidity,&lt;br /&gt;
        &amp;quot;field3&amp;quot;: int(alert)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    try:&lt;br /&gt;
        response = requests.post(&lt;br /&gt;
            THINGSPEAK_URL,&lt;br /&gt;
            data=payload,&lt;br /&gt;
            timeout=10&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        if response.status_code == 200 and response.text != &amp;quot;0&amp;quot;:&lt;br /&gt;
            print(&amp;quot;Cloud upload successful&amp;quot;)&lt;br /&gt;
            print(&amp;quot;Entry ID:&amp;quot;, response.text)&lt;br /&gt;
        else:&lt;br /&gt;
            print(&amp;quot;Cloud upload failed:&amp;quot;, response.text)&lt;br /&gt;
&lt;br /&gt;
    except requests.RequestException as error:&lt;br /&gt;
        print(&amp;quot;Network error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
try:&lt;br /&gt;
    print(&amp;quot;Raspberry Pi Edge Computing System Started&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
        try:&lt;br /&gt;
            temperature = dht.temperature&lt;br /&gt;
            humidity = dht.humidity&lt;br /&gt;
&lt;br /&gt;
            if temperature is not None and humidity is not None:&lt;br /&gt;
                temperature_samples.append(temperature)&lt;br /&gt;
                humidity_samples.append(humidity)&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;Raw Temperature:&amp;quot;, temperature, &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Raw Humidity:&amp;quot;, humidity, &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
            if len(temperature_samples) &amp;gt;= SAMPLES_PER_BATCH:&lt;br /&gt;
                # Local data aggregation&lt;br /&gt;
                avg_temp = sum(temperature_samples) / len(temperature_samples)&lt;br /&gt;
                avg_humidity = sum(humidity_samples) / len(humidity_samples)&lt;br /&gt;
&lt;br /&gt;
                # Local threshold-based decision&lt;br /&gt;
                alert = avg_temp &amp;gt;= TEMP_THRESHOLD&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;\n--- Edge Processing Result ---&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Temperature:&amp;quot;, round(avg_temp, 2), &amp;quot;°C&amp;quot;)&lt;br /&gt;
                print(&amp;quot;Average Humidity:&amp;quot;, round(avg_humidity, 2), &amp;quot;%&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                if alert:&lt;br /&gt;
                    print(&amp;quot;ALERT: Temperature threshold exceeded&amp;quot;)&lt;br /&gt;
                else:&lt;br /&gt;
                    print(&amp;quot;Status: Normal&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
                # Send processed data to cloud&lt;br /&gt;
                upload_to_cloud(&lt;br /&gt;
                    round(avg_temp, 2),&lt;br /&gt;
                    round(avg_humidity, 2),&lt;br /&gt;
                    alert&lt;br /&gt;
                )&lt;br /&gt;
&lt;br /&gt;
                # Clear batch for next aggregation&lt;br /&gt;
                temperature_samples.clear()&lt;br /&gt;
                humidity_samples.clear()&lt;br /&gt;
&lt;br /&gt;
                print(&amp;quot;------------------------------\n&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
        except RuntimeError as error:&lt;br /&gt;
            # Temporary DHT11 reading errors&lt;br /&gt;
            print(&amp;quot;Sensor reading error:&amp;quot;, error)&lt;br /&gt;
&lt;br /&gt;
        time.sleep(SAMPLE_INTERVAL)&lt;br /&gt;
&lt;br /&gt;
except KeyboardInterrupt:&lt;br /&gt;
    print(&amp;quot;Program stopped by user&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
finally:&lt;br /&gt;
    dht.exit()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Statement&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| import board&lt;br /&gt;
| Provides board pin definitions for Raspberry Pi.&lt;br /&gt;
|-&lt;br /&gt;
| import adafruit_dht&lt;br /&gt;
| Provides functions to read the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| import requests&lt;br /&gt;
| Provides HTTP communication with the cloud.&lt;br /&gt;
|-&lt;br /&gt;
| dht = adafruit_dht.DHT11(board.D4)&lt;br /&gt;
| Initializes the DHT11 sensor using GPIO4.&lt;br /&gt;
|-&lt;br /&gt;
| SAMPLE_INTERVAL = 2&lt;br /&gt;
| Defines a two-second interval between sensor-reading attempts.&lt;br /&gt;
|-&lt;br /&gt;
| SAMPLES_PER_BATCH = 10&lt;br /&gt;
| Defines the number of readings collected before local aggregation.&lt;br /&gt;
|-&lt;br /&gt;
| TEMP_THRESHOLD = 30.0&lt;br /&gt;
| Defines the demonstration temperature threshold.&lt;br /&gt;
|-&lt;br /&gt;
| temperature_samples.append(temperature)&lt;br /&gt;
| Stores the latest valid temperature reading locally.&lt;br /&gt;
|-&lt;br /&gt;
| sum(temperature_samples) / len(temperature_samples)&lt;br /&gt;
| Calculates the average temperature for the current batch.&lt;br /&gt;
|-&lt;br /&gt;
| avg_temp &amp;gt;= TEMP_THRESHOLD&lt;br /&gt;
| Performs local threshold-based event detection.&lt;br /&gt;
|-&lt;br /&gt;
| requests.post()&lt;br /&gt;
| Transmits the processed sensor data to the cloud using HTTP.&lt;br /&gt;
|-&lt;br /&gt;
| temperature_samples.clear()&lt;br /&gt;
| Clears the current batch after processing.&lt;br /&gt;
|-&lt;br /&gt;
| dht.exit()&lt;br /&gt;
| Releases the DHT sensor resources when the program ends.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Hardware Setup ===&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the Raspberry Pi using the specified pin connections.&lt;br /&gt;
# Connect the Raspberry Pi to its power supply.&lt;br /&gt;
# Ensure the sensor is powered using a compatible voltage and logic interface.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Software Setup ===&lt;br /&gt;
&lt;br /&gt;
# Boot Raspberry Pi OS.&lt;br /&gt;
# Connect the Raspberry Pi to a Wi-Fi network with internet access.&lt;br /&gt;
# Open the terminal.&lt;br /&gt;
# Create and activate a Python virtual environment if required.&lt;br /&gt;
# Install the required Python libraries.&lt;br /&gt;
# Create a Python file named edge_computing.py.&lt;br /&gt;
# Enter the given program and save it.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Cloud Setup ===&lt;br /&gt;
&lt;br /&gt;
# Sign in to ThingSpeak.&lt;br /&gt;
# Create a new channel.&lt;br /&gt;
# Enable Field 1, Field 2, and Field 3.&lt;br /&gt;
# Name the fields as Average Temperature, Average Humidity, and Temperature Alert.&lt;br /&gt;
# Save the channel.&lt;br /&gt;
# Open the API Keys tab.&lt;br /&gt;
# Copy the Write API Key.&lt;br /&gt;
# Replace YOUR_THINGSPEAK_WRITE_API_KEY in the program with the actual key.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Execute the Program ===&lt;br /&gt;
&lt;br /&gt;
# Run the program using the command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python edge_computing.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Observe the raw sensor readings in the Raspberry Pi terminal.&lt;br /&gt;
# Observe the locally calculated average temperature and humidity.&lt;br /&gt;
# Check the local threshold detection output.&lt;br /&gt;
# Observe the cloud upload status.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Verify Cloud Data ===&lt;br /&gt;
&lt;br /&gt;
# Open the ThingSpeak channel.&lt;br /&gt;
# View the private channel&#039;s visualization page.&lt;br /&gt;
# Observe the uploaded average temperature and humidity.&lt;br /&gt;
# Observe the temperature alert field.&lt;br /&gt;
# Compare the local processing output with the cloud values.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Processing Stage&lt;br /&gt;
! Expected Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Sensor reading&lt;br /&gt;
| Raw temperature and humidity readings displayed locally&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Data aggregation&lt;br /&gt;
| Average of ten valid readings calculated locally&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Threshold detection&lt;br /&gt;
| Local alert generated when average temperature reaches or exceeds 30°C&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Cloud transmission&lt;br /&gt;
| Processed readings and alert status sent to ThingSpeak&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Cloud visualization&lt;br /&gt;
| Processed values displayed in the ThingSpeak channel&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Comparison: Cloud-Based vs Edge-Based Processing ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Cloud-Based Processing&lt;br /&gt;
! Edge-Based Processing&lt;br /&gt;
|-&lt;br /&gt;
| Data processing&lt;br /&gt;
| Performed on a remote cloud server&lt;br /&gt;
| Performed locally on Raspberry Pi&lt;br /&gt;
|-&lt;br /&gt;
| Data transmission&lt;br /&gt;
| Raw readings may be transmitted continuously&lt;br /&gt;
| Aggregated readings and alert status are transmitted&lt;br /&gt;
|-&lt;br /&gt;
| Bandwidth usage&lt;br /&gt;
| Can be higher when all raw data is uploaded&lt;br /&gt;
| Can be reduced by local aggregation and selective transmission&lt;br /&gt;
|-&lt;br /&gt;
| Response latency&lt;br /&gt;
| Depends on network and cloud processing&lt;br /&gt;
| Local decisions can be made without waiting for cloud processing&lt;br /&gt;
|-&lt;br /&gt;
| Internet dependency&lt;br /&gt;
| Remote processing requires connectivity&lt;br /&gt;
| Local processing can continue during internet outages&lt;br /&gt;
|-&lt;br /&gt;
| Scalability&lt;br /&gt;
| More raw data can increase cloud traffic and processing requirements&lt;br /&gt;
| Local filtering can reduce cloud traffic as deployments grow&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An edge computing application was implemented using a Raspberry Pi and a DHT11 sensor. Sensor data was aggregated and processed locally. Temperature threshold detection was performed on the Raspberry Pi, and processed sensor values and alert status were transmitted to the ThingSpeak cloud platform.&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates how local processing can reduce unnecessary data transmission and support low-latency decision-making.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is edge computing?&lt;br /&gt;
# What is the difference between edge computing and cloud computing?&lt;br /&gt;
# Why is Raspberry Pi suitable for edge computing applications?&lt;br /&gt;
# What is data aggregation?&lt;br /&gt;
# How does local processing reduce bandwidth usage?&lt;br /&gt;
# What is latency in an IoT system?&lt;br /&gt;
# What is the role of the DHT11 sensor in this experiment?&lt;br /&gt;
# Why is threshold detection performed locally?&lt;br /&gt;
# What is the purpose of the HTTP POST request?&lt;br /&gt;
# What is the difference between raw and processed sensor data?&lt;br /&gt;
# Can edge computing work without an internet connection?&lt;br /&gt;
# What are the limitations of this edge computing application?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1379</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1379"/>
		<updated>2026-10-08T02:13:01Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* SHA-256 Hashing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hashing algorithm used to convert input data of any length into a fixed-size &#039;&#039;&#039;256-bit hash&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The output is normally represented as a &#039;&#039;&#039;64-character hexadecimal value&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Basic characteristics of SHA-256 are:&lt;br /&gt;
&lt;br /&gt;
* It accepts input data of any length.&lt;br /&gt;
* It always produces a fixed 256-bit output.&lt;br /&gt;
* The output is represented using 64 hexadecimal characters.&lt;br /&gt;
* The same input always produces the same hash.&lt;br /&gt;
* A small change in the input produces a completely different hash.&lt;br /&gt;
* It is designed to be difficult to reverse the hash back to the original input.&lt;br /&gt;
* SHA-256 is a &#039;&#039;&#039;hashing algorithm&#039;&#039;&#039;, not an encryption algorithm.&lt;br /&gt;
* It can be used to verify passwords and detect changes in data.&lt;br /&gt;
&lt;br /&gt;
The basic working process of SHA-256 is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Input Data&lt;br /&gt;
    ↓&lt;br /&gt;
Convert into Binary&lt;br /&gt;
    ↓&lt;br /&gt;
Add Padding&lt;br /&gt;
    ↓&lt;br /&gt;
Divide into 512-bit Blocks&lt;br /&gt;
    ↓&lt;br /&gt;
Expand Each Block into 64 Words&lt;br /&gt;
    ↓&lt;br /&gt;
Initialize Eight 32-bit Registers&lt;br /&gt;
    ↓&lt;br /&gt;
Perform 64 Rounds of Processing&lt;br /&gt;
    ↓&lt;br /&gt;
Bitwise Operations and Modular Addition&lt;br /&gt;
    ↓&lt;br /&gt;
Combine Eight 32-bit Results&lt;br /&gt;
    ↓&lt;br /&gt;
256-bit Hash&lt;br /&gt;
    ↓&lt;br /&gt;
64 Hexadecimal Characters&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
During processing, SHA-256 uses operations such as:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;XOR&#039;&#039;&#039; – performs bit-by-bit exclusive OR operation.&lt;br /&gt;
* &#039;&#039;&#039;AND&#039;&#039;&#039; – performs bit-by-bit AND operation.&lt;br /&gt;
* &#039;&#039;&#039;NOT&#039;&#039;&#039; – inverts the bits.&lt;br /&gt;
* &#039;&#039;&#039;Bit Rotation&#039;&#039;&#039; – rotates bits to the left or right.&lt;br /&gt;
* &#039;&#039;&#039;Bit Shifting&#039;&#039;&#039; – shifts bits to the left or right.&lt;br /&gt;
* &#039;&#039;&#039;Modular Addition&#039;&#039;&#039; – performs addition using a fixed 32-bit word size.&lt;br /&gt;
&lt;br /&gt;
SHA-256 uses &#039;&#039;&#039;predefined constants&#039;&#039;&#039; and performs &#039;&#039;&#039;64 processing rounds&#039;&#039;&#039; for each 512-bit block. These operations repeatedly mix the input data to produce the final hash.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
admin123&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this experiment, the password entered by the user is converted into a SHA-256 hash. The generated hash is then compared with the stored password hash. If both hashes are the same, the password is considered correct and the user is allowed to access the protected sensor data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. For real-world password storage, password-specific algorithms such as salted Argon2, bcrypt, scrypt or PBKDF2 are preferred.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and wifiPassword:&#039;&#039;&#039; Store the Wi-Fi network name and password required by the ESP32 to connect to the selected Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.mode(WIFI_STA):&#039;&#039;&#039; Configures the ESP32 to operate in Station (STA) mode so that it connects to an existing Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.begin():&#039;&#039;&#039; Starts the connection process using the configured Wi-Fi network name and password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.status():&#039;&#039;&#039; Checks the current Wi-Fi connection status of the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WL_CONNECTED:&#039;&#039;&#039; Indicates that the ESP32 has successfully connected to the Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Returns the IP address assigned to the ESP32 by the Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Serial Monitor displays output similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==============================&lt;br /&gt;
ESP32 Smart Sensor Security&lt;br /&gt;
==============================&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected.&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started.&lt;br /&gt;
&lt;br /&gt;
Open this address in your browser:&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&lt;br /&gt;
Username: admin&lt;br /&gt;
Password: admin123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1378</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1378"/>
		<updated>2026-10-08T01:56:59Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Code Explanation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and wifiPassword:&#039;&#039;&#039; Store the Wi-Fi network name and password required by the ESP32 to connect to the selected Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.mode(WIFI_STA):&#039;&#039;&#039; Configures the ESP32 to operate in Station (STA) mode so that it connects to an existing Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.begin():&#039;&#039;&#039; Starts the connection process using the configured Wi-Fi network name and password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.status():&#039;&#039;&#039; Checks the current Wi-Fi connection status of the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WL_CONNECTED:&#039;&#039;&#039; Indicates that the ESP32 has successfully connected to the Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Returns the IP address assigned to the ESP32 by the Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Serial Monitor displays output similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==============================&lt;br /&gt;
ESP32 Smart Sensor Security&lt;br /&gt;
==============================&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected.&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started.&lt;br /&gt;
&lt;br /&gt;
Open this address in your browser:&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&lt;br /&gt;
Username: admin&lt;br /&gt;
Password: admin123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1377</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1377"/>
		<updated>2026-10-08T01:56:01Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Serial Monitor displays output similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==============================&lt;br /&gt;
ESP32 Smart Sensor Security&lt;br /&gt;
==============================&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected.&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started.&lt;br /&gt;
&lt;br /&gt;
Open this address in your browser:&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&lt;br /&gt;
Username: admin&lt;br /&gt;
Password: admin123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1376</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1376"/>
		<updated>2026-10-08T01:55:28Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Observations and Output */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
The Serial Monitor displays output similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
==============================&lt;br /&gt;
ESP32 Smart Sensor Security&lt;br /&gt;
==============================&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected.&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started.&lt;br /&gt;
&lt;br /&gt;
Open this address in your browser:&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&lt;br /&gt;
Username: admin&lt;br /&gt;
Password: admin123&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1375</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1375"/>
		<updated>2026-10-08T01:54:34Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* ESP32 Web Server */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 operates in Wi-Fi Station (STA) mode and obtains an IP address from the connected Wi-Fi network. The assigned IP address is displayed in the Serial Monitor and is used to access the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Smart Sensor Security System&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial browser page displays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Username: [____________]&lt;br /&gt;
&lt;br /&gt;
Password: [____________]&lt;br /&gt;
&lt;br /&gt;
          [ Login ]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an incorrect password is entered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Access Denied&lt;br /&gt;
&lt;br /&gt;
Invalid username or password.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Authentication Successful&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.6 °C&lt;br /&gt;
Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
[Refresh Sensor Data]&lt;br /&gt;
&lt;br /&gt;
[Logout]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1374</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1374"/>
		<updated>2026-10-08T01:50:01Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact IP address depends on the network to which the ESP32 is connected.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Smart Sensor Security System&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial browser page displays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Username: [____________]&lt;br /&gt;
&lt;br /&gt;
Password: [____________]&lt;br /&gt;
&lt;br /&gt;
          [ Login ]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an incorrect password is entered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Access Denied&lt;br /&gt;
&lt;br /&gt;
Invalid username or password.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Authentication Successful&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.6 °C&lt;br /&gt;
Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
[Refresh Sensor Data]&lt;br /&gt;
&lt;br /&gt;
[Logout]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1373</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1373"/>
		<updated>2026-10-08T01:48:58Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact IP address depends on the network to which the ESP32 is connected.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;Brahmand&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;cog_wifi#3357&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Smart Sensor Security System&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial browser page displays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Username: [____________]&lt;br /&gt;
&lt;br /&gt;
Password: [____________]&lt;br /&gt;
&lt;br /&gt;
          [ Login ]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an incorrect password is entered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Access Denied&lt;br /&gt;
&lt;br /&gt;
Invalid username or password.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Authentication Successful&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.6 °C&lt;br /&gt;
Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
[Refresh Sensor Data]&lt;br /&gt;
&lt;br /&gt;
[Logout]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1372</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1372"/>
		<updated>2026-10-08T01:48:27Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact IP address depends on the network to which the ESP32 is connected.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Wi-Fi Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* ssid = &amp;quot;Brahmand&amp;quot;;&lt;br /&gt;
const char* wifiPassword = &amp;quot;cog_wifi#3357&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/* ==============================&lt;br /&gt;
   Login Credentials&lt;br /&gt;
   ============================== */&lt;br /&gt;
&lt;br /&gt;
const char* loginUsername = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Password:&lt;br /&gt;
   admin123&lt;br /&gt;
&lt;br /&gt;
   Correct SHA-256 hash:&lt;br /&gt;
   240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
  &amp;quot;240be518fabd2724ddb6f04eeb1da5967448d7e831c08c8fa822809f74c720a9&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   SHA-256 Function&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char hash[32];&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     0 = SHA-256&lt;br /&gt;
     1 = SHA-224&lt;br /&gt;
  */&lt;br /&gt;
  mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_update(&lt;br /&gt;
    &amp;amp;ctx,&lt;br /&gt;
    (const unsigned char*)input.c_str(),&lt;br /&gt;
    input.length()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
&lt;br /&gt;
  mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
  String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
  {&lt;br /&gt;
    if (hash[i] &amp;lt; 0x10)&lt;br /&gt;
    {&lt;br /&gt;
      result += &amp;quot;0&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    result += String(hash[i], HEX);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor Login&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:400px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:90%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:1px solid #ccc;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;input[type=submit]{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;width:96%;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;cursor:pointer;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Password Protected IoT System&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;text&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;username&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Username&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;name=&#039;password&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;placeholder=&#039;Password&#039; required&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, html);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Login Authentication&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
  String enteredUsername = server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
  String enteredPassword = server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  String enteredHash = sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Login attempt&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;Username: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredUsername);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Password Hash: &amp;quot;);&lt;br /&gt;
  Serial.println(enteredHash);&lt;br /&gt;
&lt;br /&gt;
  if (&lt;br /&gt;
    enteredUsername == loginUsername &amp;amp;&amp;amp;&lt;br /&gt;
    enteredHash == storedPasswordHash&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = true;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication successful&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/sensor&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Login successful&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;Authentication failed&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
    html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Access Denied&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Invalid username or password.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      401,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Protected Sensor Page&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
  if (!authenticated)&lt;br /&gt;
  {&lt;br /&gt;
    server.sendHeader(&amp;quot;Location&amp;quot;, &amp;quot;/&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      302,&lt;br /&gt;
      &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
      &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check whether DHT11 reading is valid.&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body style=&#039;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;padding:40px;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Sensor Error&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;Unable to read DHT11 sensor.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
      500,&lt;br /&gt;
      &amp;quot;text/html&amp;quot;,&lt;br /&gt;
      html&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;!DOCTYPE html&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta name=&#039;viewport&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;width=device-width, initial-scale=1&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;meta http-equiv=&#039;refresh&#039; &amp;quot;;&lt;br /&gt;
  html += &amp;quot;content=&#039;10&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;body{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-family:Arial;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#f2f2f2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-align:center;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.box{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;max-width:500px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:auto;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:30px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:12px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;box-shadow:0 4px 15px rgba(0,0,0,0.15);&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.value{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-size:32px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;font-weight:bold;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;a{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;display:inline-block;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;padding:12px 20px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;margin:8px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#1976d2;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;color:white;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;text-decoration:none;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;border-radius:6px;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;.logout{&amp;quot;;&lt;br /&gt;
  html += &amp;quot;background:#d32f2f;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;}&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/style&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;box&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;h2&amp;gt;Authentication Successful&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Temperature&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(temperature, 1);&lt;br /&gt;
  html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Humidity&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;div class=&#039;value&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
  html += String(humidity, 1);&lt;br /&gt;
  html += &amp;quot; %&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;p&amp;gt;Data refreshes automatically every 10 seconds.&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;Refresh&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;a class=&#039;logout&#039; href=&#039;/logout&#039;&amp;gt;Logout&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
  html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    200,&lt;br /&gt;
    &amp;quot;text/html&amp;quot;,&lt;br /&gt;
    html&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Logout&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
  authenticated = false;&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;User logged out.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  server.sendHeader(&lt;br /&gt;
    &amp;quot;Location&amp;quot;,&lt;br /&gt;
    &amp;quot;/&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.send(&lt;br /&gt;
    302,&lt;br /&gt;
    &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
    &amp;quot;Logged out&amp;quot;&lt;br /&gt;
  );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Setup&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Smart Sensor Security&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;==============================&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start DHT11&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Connect to Wi-Fi&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  WiFi.begin(&lt;br /&gt;
    ssid,&lt;br /&gt;
    wifiPassword&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Connecting to Wi-Fi&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  int attempts = 0;&lt;br /&gt;
&lt;br /&gt;
  while (&lt;br /&gt;
    WiFi.status() != WL_CONNECTED &amp;amp;&amp;amp;&lt;br /&gt;
    attempts &amp;lt; 40&lt;br /&gt;
  )&lt;br /&gt;
  {&lt;br /&gt;
    delay(500);&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    attempts++;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Check Wi-Fi connection&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  if (WiFi.status() != WL_CONNECTED)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Wi-Fi connection failed.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
      &amp;quot;Check SSID and Wi-Fi password.&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Wi-Fi connected.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 IP address: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Web server routes&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleRoot&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/login&amp;quot;,&lt;br /&gt;
    HTTP_POST,&lt;br /&gt;
    handleLogin&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleSensor&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  server.on(&lt;br /&gt;
    &amp;quot;/logout&amp;quot;,&lt;br /&gt;
    HTTP_GET,&lt;br /&gt;
    handleLogout&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Start web server&lt;br /&gt;
  */&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Open this address in your browser:&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;http://&amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.localIP());&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Username: admin&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Password: admin123&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================================&lt;br /&gt;
   Main Loop&lt;br /&gt;
   ========================================= */&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Smart Sensor Security System&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial browser page displays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Username: [____________]&lt;br /&gt;
&lt;br /&gt;
Password: [____________]&lt;br /&gt;
&lt;br /&gt;
          [ Login ]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an incorrect password is entered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Access Denied&lt;br /&gt;
&lt;br /&gt;
Invalid username or password.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Authentication Successful&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.6 °C&lt;br /&gt;
Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
[Refresh Sensor Data]&lt;br /&gt;
&lt;br /&gt;
[Logout]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=File:IoT_TCP_DHT11_Programs.zip&amp;diff=1371</id>
		<title>File:IoT TCP DHT11 Programs.zip</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=File:IoT_TCP_DHT11_Programs.zip&amp;diff=1371"/>
		<updated>2026-10-08T01:13:27Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: CogWikiEditor uploaded a new version of File:IoT TCP DHT11 Programs.zip&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1370</id>
		<title>MDM331AID/Experiment 7</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1370"/>
		<updated>2026-10-08T01:08:44Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Viva Questions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: RFID-Based Identification System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design an RFID-based identification system that reads tag information and displays the tag ID on a monitoring system, demonstrating short-range communication technology in IoT.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand RFID technology and its role in IoT.&lt;br /&gt;
* To interface an RFID reader with an Arduino UNO.&lt;br /&gt;
* To read the unique identification number (UID) of an RFID tag.&lt;br /&gt;
* To display the tag ID on the Arduino IDE Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Arduino UNO&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MFRC522 RFID reader module&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| RFID tags or cards compatible with the reader&lt;br /&gt;
| 1 or more&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Radio Frequency Identification (RFID)&#039;&#039;&#039; is a wireless identification technology that uses radio waves to exchange information between an RFID reader and an RFID tag.&lt;br /&gt;
&lt;br /&gt;
An RFID system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;RFID tag:&#039;&#039;&#039; Stores identification information. Passive tags obtain operating energy from the reader&#039;s electromagnetic field.&lt;br /&gt;
* &#039;&#039;&#039;RFID reader:&#039;&#039;&#039; Communicates with the tag and retrieves its identification information.&lt;br /&gt;
* &#039;&#039;&#039;Controller:&#039;&#039;&#039; Processes the information received from the reader. In this experiment, the Arduino UNO acts as the controller.&lt;br /&gt;
* &#039;&#039;&#039;Monitoring system:&#039;&#039;&#039; Displays the received tag ID. In this experiment, the Arduino IDE Serial Monitor is used.&lt;br /&gt;
&lt;br /&gt;
The MFRC522 reader communicates with the Arduino UNO using the SPI (Serial Peripheral Interface) protocol. When a compatible RFID tag is brought close to the reader, the reader detects the tag and retrieves its UID. The Arduino then displays the UID on the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
RFID is a short-range communication technology. The reading distance depends on the reader, tag, antenna, operating conditions and tag type.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The UID is used here for demonstration and identification only. UID-based checking alone is not a secure authentication mechanism.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections assume an MFRC522 RFID module and an Arduino UNO.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! RFID Module Pin&lt;br /&gt;
! Arduino UNO Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| SDA / SS&lt;br /&gt;
| D10&lt;br /&gt;
| SPI chip select&lt;br /&gt;
|-&lt;br /&gt;
| SCK&lt;br /&gt;
| D13&lt;br /&gt;
| SPI clock&lt;br /&gt;
|-&lt;br /&gt;
| MOSI&lt;br /&gt;
| D11&lt;br /&gt;
| SPI data from Arduino to reader&lt;br /&gt;
|-&lt;br /&gt;
| MISO&lt;br /&gt;
| D12&lt;br /&gt;
| SPI data from reader to Arduino&lt;br /&gt;
|-&lt;br /&gt;
| RST&lt;br /&gt;
| D9&lt;br /&gt;
| Reset&lt;br /&gt;
|-&lt;br /&gt;
| 3.3V&lt;br /&gt;
| 3.3V (Connect to 5V if system not working)&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|-&lt;br /&gt;
| IRQ&lt;br /&gt;
| Not connected&lt;br /&gt;
| Not required for this program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the Arduino UNO to the computer. The computer runs the Arduino IDE and displays the received tag ID through the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;MFRC522&#039;&#039;&#039; library using the Arduino IDE Library Manager before uploading the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;MFRC522.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SS_PIN 10&lt;br /&gt;
#define RST_PIN 9&lt;br /&gt;
&lt;br /&gt;
MFRC522 rfid(SS_PIN, RST_PIN);&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(9600);&lt;br /&gt;
    SPI.begin();&lt;br /&gt;
    rfid.PCD_Init();&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;RFID Identification System&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;Place an RFID tag near the reader.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    // Check whether a new tag is present&lt;br /&gt;
    if (!rfid.PICC_IsNewCardPresent())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Read the tag serial number&lt;br /&gt;
    if (!rfid.PICC_ReadCardSerial())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Tag UID: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (byte i = 0; i &amp;lt; rfid.uid.size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (rfid.uid.uidByte[i] &amp;lt; 0x10)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        Serial.print(rfid.uid.uidByte[i], HEX);&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;lt; rfid.uid.size - 1)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;:&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.println();&lt;br /&gt;
&lt;br /&gt;
    // Stop communication with the current tag&lt;br /&gt;
    rfid.PICC_HaltA();&lt;br /&gt;
    rfid.PCD_StopCrypto1();&lt;br /&gt;
&lt;br /&gt;
    delay(500);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SPI.begin():&#039;&#039;&#039; Initializes SPI communication between the Arduino UNO and the RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;rfid.PCD_Init():&#039;&#039;&#039; Initializes the MFRC522 RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;PICC_IsNewCardPresent():&#039;&#039;&#039; Checks whether a new RFID tag is present in the reader&#039;s field.&lt;br /&gt;
* &#039;&#039;&#039;PICC_ReadCardSerial():&#039;&#039;&#039; Reads the UID of the detected RFID tag.&lt;br /&gt;
* &#039;&#039;&#039;rfid.uid.size:&#039;&#039;&#039; Gives the number of bytes in the UID.&lt;br /&gt;
* &#039;&#039;&#039;Serial.print():&#039;&#039;&#039; Displays the UID in hexadecimal format on the Serial Monitor.&lt;br /&gt;
* &#039;&#039;&#039;PICC_HaltA():&#039;&#039;&#039; Stops communication with the selected tag.&lt;br /&gt;
* &#039;&#039;&#039;PCD_StopCrypto1():&#039;&#039;&#039; Stops the reader&#039;s Crypto1 authentication state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
# Verify the power supply and logic-level compatibility of the RFID module.&lt;br /&gt;
# Connect the Arduino UNO to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the MFRC522 library using the Library Manager.&lt;br /&gt;
# Select the appropriate Arduino UNO board and COM port.&lt;br /&gt;
# Copy the program into the Arduino IDE.&lt;br /&gt;
# Compile and upload the program to the Arduino UNO.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 9600.&lt;br /&gt;
# Bring a compatible RFID tag or card close to the RFID reader.&lt;br /&gt;
# Observe the UID displayed on the Serial Monitor.&lt;br /&gt;
# Repeat the experiment with different tags and compare the displayed UIDs.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following is an illustrative example of the expected Serial Monitor output. Actual UIDs will depend on the RFID tags used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RFID Identification System&lt;br /&gt;
Place an RFID tag near the reader.&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
Tag UID: 6B:21:CD:07&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! RFID Tag&lt;br /&gt;
! Observed UID&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Tag 1&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Tag 2&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Tag 3&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The RFID reader was interfaced with the Arduino UNO using SPI communication. The system read the UIDs of compatible RFID tags and displayed the identification information on the Serial Monitor, demonstrating short-range wireless identification.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is RFID?&lt;br /&gt;
# What are the main components of an RFID system?&lt;br /&gt;
# What is the difference between an RFID reader and an RFID tag?&lt;br /&gt;
# What is the purpose of the UID in an RFID tag?&lt;br /&gt;
# Which communication protocol is used between the MFRC522 and Arduino UNO?&lt;br /&gt;
# What is SPI communication?&lt;br /&gt;
# What factors affect the reading range of an RFID system?&lt;br /&gt;
# What is the difference between passive and active RFID tags?&lt;br /&gt;
# Why is UID-only identification not considered secure authentication?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1369</id>
		<title>MDM331AID/Experiment 7</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1369"/>
		<updated>2026-10-08T01:08:28Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Components Required */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: RFID-Based Identification System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design an RFID-based identification system that reads tag information and displays the tag ID on a monitoring system, demonstrating short-range communication technology in IoT.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand RFID technology and its role in IoT.&lt;br /&gt;
* To interface an RFID reader with an Arduino UNO.&lt;br /&gt;
* To read the unique identification number (UID) of an RFID tag.&lt;br /&gt;
* To display the tag ID on the Arduino IDE Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Arduino UNO&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MFRC522 RFID reader module&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| RFID tags or cards compatible with the reader&lt;br /&gt;
| 1 or more&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Radio Frequency Identification (RFID)&#039;&#039;&#039; is a wireless identification technology that uses radio waves to exchange information between an RFID reader and an RFID tag.&lt;br /&gt;
&lt;br /&gt;
An RFID system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;RFID tag:&#039;&#039;&#039; Stores identification information. Passive tags obtain operating energy from the reader&#039;s electromagnetic field.&lt;br /&gt;
* &#039;&#039;&#039;RFID reader:&#039;&#039;&#039; Communicates with the tag and retrieves its identification information.&lt;br /&gt;
* &#039;&#039;&#039;Controller:&#039;&#039;&#039; Processes the information received from the reader. In this experiment, the Arduino UNO acts as the controller.&lt;br /&gt;
* &#039;&#039;&#039;Monitoring system:&#039;&#039;&#039; Displays the received tag ID. In this experiment, the Arduino IDE Serial Monitor is used.&lt;br /&gt;
&lt;br /&gt;
The MFRC522 reader communicates with the Arduino UNO using the SPI (Serial Peripheral Interface) protocol. When a compatible RFID tag is brought close to the reader, the reader detects the tag and retrieves its UID. The Arduino then displays the UID on the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
RFID is a short-range communication technology. The reading distance depends on the reader, tag, antenna, operating conditions and tag type.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The UID is used here for demonstration and identification only. UID-based checking alone is not a secure authentication mechanism.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections assume an MFRC522 RFID module and an Arduino UNO.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! RFID Module Pin&lt;br /&gt;
! Arduino UNO Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| SDA / SS&lt;br /&gt;
| D10&lt;br /&gt;
| SPI chip select&lt;br /&gt;
|-&lt;br /&gt;
| SCK&lt;br /&gt;
| D13&lt;br /&gt;
| SPI clock&lt;br /&gt;
|-&lt;br /&gt;
| MOSI&lt;br /&gt;
| D11&lt;br /&gt;
| SPI data from Arduino to reader&lt;br /&gt;
|-&lt;br /&gt;
| MISO&lt;br /&gt;
| D12&lt;br /&gt;
| SPI data from reader to Arduino&lt;br /&gt;
|-&lt;br /&gt;
| RST&lt;br /&gt;
| D9&lt;br /&gt;
| Reset&lt;br /&gt;
|-&lt;br /&gt;
| 3.3V&lt;br /&gt;
| 3.3V (Connect to 5V if system not working)&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|-&lt;br /&gt;
| IRQ&lt;br /&gt;
| Not connected&lt;br /&gt;
| Not required for this program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the Arduino UNO to the computer. The computer runs the Arduino IDE and displays the received tag ID through the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;MFRC522&#039;&#039;&#039; library using the Arduino IDE Library Manager before uploading the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;MFRC522.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SS_PIN 10&lt;br /&gt;
#define RST_PIN 9&lt;br /&gt;
&lt;br /&gt;
MFRC522 rfid(SS_PIN, RST_PIN);&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(9600);&lt;br /&gt;
    SPI.begin();&lt;br /&gt;
    rfid.PCD_Init();&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;RFID Identification System&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;Place an RFID tag near the reader.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    // Check whether a new tag is present&lt;br /&gt;
    if (!rfid.PICC_IsNewCardPresent())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Read the tag serial number&lt;br /&gt;
    if (!rfid.PICC_ReadCardSerial())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Tag UID: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (byte i = 0; i &amp;lt; rfid.uid.size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (rfid.uid.uidByte[i] &amp;lt; 0x10)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        Serial.print(rfid.uid.uidByte[i], HEX);&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;lt; rfid.uid.size - 1)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;:&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.println();&lt;br /&gt;
&lt;br /&gt;
    // Stop communication with the current tag&lt;br /&gt;
    rfid.PICC_HaltA();&lt;br /&gt;
    rfid.PCD_StopCrypto1();&lt;br /&gt;
&lt;br /&gt;
    delay(500);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SPI.begin():&#039;&#039;&#039; Initializes SPI communication between the Arduino UNO and the RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;rfid.PCD_Init():&#039;&#039;&#039; Initializes the MFRC522 RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;PICC_IsNewCardPresent():&#039;&#039;&#039; Checks whether a new RFID tag is present in the reader&#039;s field.&lt;br /&gt;
* &#039;&#039;&#039;PICC_ReadCardSerial():&#039;&#039;&#039; Reads the UID of the detected RFID tag.&lt;br /&gt;
* &#039;&#039;&#039;rfid.uid.size:&#039;&#039;&#039; Gives the number of bytes in the UID.&lt;br /&gt;
* &#039;&#039;&#039;Serial.print():&#039;&#039;&#039; Displays the UID in hexadecimal format on the Serial Monitor.&lt;br /&gt;
* &#039;&#039;&#039;PICC_HaltA():&#039;&#039;&#039; Stops communication with the selected tag.&lt;br /&gt;
* &#039;&#039;&#039;PCD_StopCrypto1():&#039;&#039;&#039; Stops the reader&#039;s Crypto1 authentication state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
# Verify the power supply and logic-level compatibility of the RFID module.&lt;br /&gt;
# Connect the Arduino UNO to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the MFRC522 library using the Library Manager.&lt;br /&gt;
# Select the appropriate Arduino UNO board and COM port.&lt;br /&gt;
# Copy the program into the Arduino IDE.&lt;br /&gt;
# Compile and upload the program to the Arduino UNO.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 9600.&lt;br /&gt;
# Bring a compatible RFID tag or card close to the RFID reader.&lt;br /&gt;
# Observe the UID displayed on the Serial Monitor.&lt;br /&gt;
# Repeat the experiment with different tags and compare the displayed UIDs.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following is an illustrative example of the expected Serial Monitor output. Actual UIDs will depend on the RFID tags used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RFID Identification System&lt;br /&gt;
Place an RFID tag near the reader.&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
Tag UID: 6B:21:CD:07&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! RFID Tag&lt;br /&gt;
! Observed UID&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Tag 1&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Tag 2&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Tag 3&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The RFID reader was interfaced with the Arduino UNO using SPI communication. The system read the UIDs of compatible RFID tags and displayed the identification information on the Serial Monitor, demonstrating short-range wireless identification.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is RFID?&lt;br /&gt;
# What are the main components of an RFID system?&lt;br /&gt;
# What is the difference between an RFID reader and an RFID tag?&lt;br /&gt;
# What is the purpose of the UID in an RFID tag?&lt;br /&gt;
# Which communication protocol is used between the MFRC522 and Arduino UNO?&lt;br /&gt;
# What is SPI communication?&lt;br /&gt;
# Why does the MFRC522 require a 3.3 V supply?&lt;br /&gt;
# What factors affect the reading range of an RFID system?&lt;br /&gt;
# What is the difference between passive and active RFID tags?&lt;br /&gt;
# Why is UID-only identification not considered secure authentication?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1368</id>
		<title>MDM331AID/Experiment 7</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_7&amp;diff=1368"/>
		<updated>2026-10-08T01:08:12Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Pin Connections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: RFID-Based Identification System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design an RFID-based identification system that reads tag information and displays the tag ID on a monitoring system, demonstrating short-range communication technology in IoT.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand RFID technology and its role in IoT.&lt;br /&gt;
* To interface an RFID reader with an Arduino UNO.&lt;br /&gt;
* To read the unique identification number (UID) of an RFID tag.&lt;br /&gt;
* To display the tag ID on the Arduino IDE Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Arduino UNO&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MFRC522 RFID reader module&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| RFID tags or cards compatible with the reader&lt;br /&gt;
| 1 or more&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| 3.3 V-compatible logic-level interface, if required by the RFID module&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Radio Frequency Identification (RFID)&#039;&#039;&#039; is a wireless identification technology that uses radio waves to exchange information between an RFID reader and an RFID tag.&lt;br /&gt;
&lt;br /&gt;
An RFID system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;RFID tag:&#039;&#039;&#039; Stores identification information. Passive tags obtain operating energy from the reader&#039;s electromagnetic field.&lt;br /&gt;
* &#039;&#039;&#039;RFID reader:&#039;&#039;&#039; Communicates with the tag and retrieves its identification information.&lt;br /&gt;
* &#039;&#039;&#039;Controller:&#039;&#039;&#039; Processes the information received from the reader. In this experiment, the Arduino UNO acts as the controller.&lt;br /&gt;
* &#039;&#039;&#039;Monitoring system:&#039;&#039;&#039; Displays the received tag ID. In this experiment, the Arduino IDE Serial Monitor is used.&lt;br /&gt;
&lt;br /&gt;
The MFRC522 reader communicates with the Arduino UNO using the SPI (Serial Peripheral Interface) protocol. When a compatible RFID tag is brought close to the reader, the reader detects the tag and retrieves its UID. The Arduino then displays the UID on the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
RFID is a short-range communication technology. The reading distance depends on the reader, tag, antenna, operating conditions and tag type.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The UID is used here for demonstration and identification only. UID-based checking alone is not a secure authentication mechanism.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections assume an MFRC522 RFID module and an Arduino UNO.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! RFID Module Pin&lt;br /&gt;
! Arduino UNO Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| SDA / SS&lt;br /&gt;
| D10&lt;br /&gt;
| SPI chip select&lt;br /&gt;
|-&lt;br /&gt;
| SCK&lt;br /&gt;
| D13&lt;br /&gt;
| SPI clock&lt;br /&gt;
|-&lt;br /&gt;
| MOSI&lt;br /&gt;
| D11&lt;br /&gt;
| SPI data from Arduino to reader&lt;br /&gt;
|-&lt;br /&gt;
| MISO&lt;br /&gt;
| D12&lt;br /&gt;
| SPI data from reader to Arduino&lt;br /&gt;
|-&lt;br /&gt;
| RST&lt;br /&gt;
| D9&lt;br /&gt;
| Reset&lt;br /&gt;
|-&lt;br /&gt;
| 3.3V&lt;br /&gt;
| 3.3V (Connect to 5V if system not working)&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|-&lt;br /&gt;
| IRQ&lt;br /&gt;
| Not connected&lt;br /&gt;
| Not required for this program&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the Arduino UNO to the computer. The computer runs the Arduino IDE and displays the received tag ID through the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;MFRC522&#039;&#039;&#039; library using the Arduino IDE Library Manager before uploading the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;
#include &amp;lt;MFRC522.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define SS_PIN 10&lt;br /&gt;
#define RST_PIN 9&lt;br /&gt;
&lt;br /&gt;
MFRC522 rfid(SS_PIN, RST_PIN);&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(9600);&lt;br /&gt;
    SPI.begin();&lt;br /&gt;
    rfid.PCD_Init();&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&amp;quot;RFID Identification System&amp;quot;);&lt;br /&gt;
    Serial.println(&amp;quot;Place an RFID tag near the reader.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    // Check whether a new tag is present&lt;br /&gt;
    if (!rfid.PICC_IsNewCardPresent())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Read the tag serial number&lt;br /&gt;
    if (!rfid.PICC_ReadCardSerial())&lt;br /&gt;
    {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Tag UID: &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (byte i = 0; i &amp;lt; rfid.uid.size; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (rfid.uid.uidByte[i] &amp;lt; 0x10)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;0&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        Serial.print(rfid.uid.uidByte[i], HEX);&lt;br /&gt;
&lt;br /&gt;
        if (i &amp;lt; rfid.uid.size - 1)&lt;br /&gt;
        {&lt;br /&gt;
            Serial.print(&amp;quot;:&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.println();&lt;br /&gt;
&lt;br /&gt;
    // Stop communication with the current tag&lt;br /&gt;
    rfid.PICC_HaltA();&lt;br /&gt;
    rfid.PCD_StopCrypto1();&lt;br /&gt;
&lt;br /&gt;
    delay(500);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SPI.begin():&#039;&#039;&#039; Initializes SPI communication between the Arduino UNO and the RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;rfid.PCD_Init():&#039;&#039;&#039; Initializes the MFRC522 RFID reader.&lt;br /&gt;
* &#039;&#039;&#039;PICC_IsNewCardPresent():&#039;&#039;&#039; Checks whether a new RFID tag is present in the reader&#039;s field.&lt;br /&gt;
* &#039;&#039;&#039;PICC_ReadCardSerial():&#039;&#039;&#039; Reads the UID of the detected RFID tag.&lt;br /&gt;
* &#039;&#039;&#039;rfid.uid.size:&#039;&#039;&#039; Gives the number of bytes in the UID.&lt;br /&gt;
* &#039;&#039;&#039;Serial.print():&#039;&#039;&#039; Displays the UID in hexadecimal format on the Serial Monitor.&lt;br /&gt;
* &#039;&#039;&#039;PICC_HaltA():&#039;&#039;&#039; Stops communication with the selected tag.&lt;br /&gt;
* &#039;&#039;&#039;PCD_StopCrypto1():&#039;&#039;&#039; Stops the reader&#039;s Crypto1 authentication state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the MFRC522 RFID reader to the Arduino UNO according to the pin connection table.&lt;br /&gt;
# Verify the power supply and logic-level compatibility of the RFID module.&lt;br /&gt;
# Connect the Arduino UNO to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the MFRC522 library using the Library Manager.&lt;br /&gt;
# Select the appropriate Arduino UNO board and COM port.&lt;br /&gt;
# Copy the program into the Arduino IDE.&lt;br /&gt;
# Compile and upload the program to the Arduino UNO.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 9600.&lt;br /&gt;
# Bring a compatible RFID tag or card close to the RFID reader.&lt;br /&gt;
# Observe the UID displayed on the Serial Monitor.&lt;br /&gt;
# Repeat the experiment with different tags and compare the displayed UIDs.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following is an illustrative example of the expected Serial Monitor output. Actual UIDs will depend on the RFID tags used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RFID Identification System&lt;br /&gt;
Place an RFID tag near the reader.&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
Tag UID: 6B:21:CD:07&lt;br /&gt;
Tag UID: 23:8A:4F:19&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! RFID Tag&lt;br /&gt;
! Observed UID&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Tag 1&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Tag 2&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Tag 3&lt;br /&gt;
| Record the UID displayed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The RFID reader was interfaced with the Arduino UNO using SPI communication. The system read the UIDs of compatible RFID tags and displayed the identification information on the Serial Monitor, demonstrating short-range wireless identification.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is RFID?&lt;br /&gt;
# What are the main components of an RFID system?&lt;br /&gt;
# What is the difference between an RFID reader and an RFID tag?&lt;br /&gt;
# What is the purpose of the UID in an RFID tag?&lt;br /&gt;
# Which communication protocol is used between the MFRC522 and Arduino UNO?&lt;br /&gt;
# What is SPI communication?&lt;br /&gt;
# Why does the MFRC522 require a 3.3 V supply?&lt;br /&gt;
# What factors affect the reading range of an RFID system?&lt;br /&gt;
# What is the difference between passive and active RFID tags?&lt;br /&gt;
# Why is UID-only identification not considered secure authentication?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=File:IoT_TCP_DHT11_Programs.zip&amp;diff=1367</id>
		<title>File:IoT TCP DHT11 Programs.zip</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=File:IoT_TCP_DHT11_Programs.zip&amp;diff=1367"/>
		<updated>2026-10-08T01:00:20Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_5&amp;diff=1366</id>
		<title>MDM331AID/Experiment 5</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_5&amp;diff=1366"/>
		<updated>2026-10-08T00:54:33Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Wi-Fi Connectivity and TCP/IP-Based Sensor Data Transmission Using ESP32 =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To configure and implement an IoT device using ESP32 to connect to a Wi-Fi network and transmit temperature and humidity data from a DHT11 sensor to a remote computer using TCP/IP communication.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand Wi-Fi connectivity in IoT devices.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with ESP32.&lt;br /&gt;
* To understand TCP/IP communication and socket programming.&lt;br /&gt;
* To configure a computer as a TCP server.&lt;br /&gt;
* To configure ESP32 as a TCP client.&lt;br /&gt;
* To establish a TCP connection between an ESP32 and a remote computer.&lt;br /&gt;
* To transmit and receive sensor data over a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board (COG-E32)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Temperature and Humidity Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Data Cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch Cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Remote Computer with Python 3&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Wi-Fi Network&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things (IoT) Device ===&lt;br /&gt;
&lt;br /&gt;
An IoT device is a physical device equipped with sensors, processing capabilities, and communication interfaces. It collects data from its surroundings and transmits the information to another device, computer, or remote server.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 acts as the IoT device. The DHT11 sensor measures temperature and relative humidity. The ESP32 processes these readings and transmits them to a remote computer through a Wi-Fi network using TCP/IP communication.&lt;br /&gt;
&lt;br /&gt;
=== Wi-Fi Connectivity ===&lt;br /&gt;
&lt;br /&gt;
Wi-Fi is a wireless networking technology based on IEEE 802.11 standards. It allows devices to communicate over a wireless local area network.&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability. Therefore, no separate Wi-Fi module is required.&lt;br /&gt;
&lt;br /&gt;
In this experiment, both the ESP32 and the remote computer should be connected to the same Wi-Fi network so that the ESP32 can establish a TCP connection with the computer.&lt;br /&gt;
&lt;br /&gt;
=== TCP/IP Communication ===&lt;br /&gt;
&lt;br /&gt;
TCP/IP is a protocol suite used for communication between networked devices.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IP (Internet Protocol):&#039;&#039;&#039; Provides addressing and routing of packets between devices.&lt;br /&gt;
* &#039;&#039;&#039;TCP (Transmission Control Protocol):&#039;&#039;&#039; Provides reliable, ordered and connection-oriented communication.&lt;br /&gt;
* &#039;&#039;&#039;Port:&#039;&#039;&#039; A logical communication endpoint used to identify a particular application or service.&lt;br /&gt;
* &#039;&#039;&#039;Socket:&#039;&#039;&#039; A software interface used by applications to establish network communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment:&lt;br /&gt;
&lt;br /&gt;
* The remote computer operates as the TCP server.&lt;br /&gt;
* The ESP32 operates as the TCP client.&lt;br /&gt;
* The Python program listens for incoming TCP connections.&lt;br /&gt;
* The ESP32 connects to the IP address and port of the remote computer.&lt;br /&gt;
* The DHT11 readings are transmitted through the established TCP connection.&lt;br /&gt;
&lt;br /&gt;
=== TCP Client and TCP Server ===&lt;br /&gt;
&lt;br /&gt;
The TCP server waits for incoming client connections. In this experiment, the Python program running on the remote computer is the TCP server.&lt;br /&gt;
&lt;br /&gt;
The TCP client initiates a connection to the server. In this experiment, the ESP32 is the TCP client.&lt;br /&gt;
&lt;br /&gt;
The communication flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      |&lt;br /&gt;
      | Temperature and Humidity&lt;br /&gt;
      v&lt;br /&gt;
+------------------+&lt;br /&gt;
|      ESP32       |&lt;br /&gt;
|    TCP Client    |&lt;br /&gt;
+------------------+&lt;br /&gt;
      |&lt;br /&gt;
      | Wi-Fi&lt;br /&gt;
      v&lt;br /&gt;
+------------------+&lt;br /&gt;
|  Wi-Fi Network   |&lt;br /&gt;
+------------------+&lt;br /&gt;
      |&lt;br /&gt;
      | TCP/IP&lt;br /&gt;
      v&lt;br /&gt;
+------------------+&lt;br /&gt;
| Remote Computer  |&lt;br /&gt;
|   TCP Server     |&lt;br /&gt;
|  Python Program  |&lt;br /&gt;
+------------------+&lt;br /&gt;
      |&lt;br /&gt;
      v&lt;br /&gt;
Display Sensor Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DHT11 Sensor ===&lt;br /&gt;
&lt;br /&gt;
The DHT11 is a digital temperature and humidity sensor. It provides temperature and relative humidity measurements through a digital data interface.&lt;br /&gt;
&lt;br /&gt;
Typical specifications include:&lt;br /&gt;
&lt;br /&gt;
* Temperature measurement range: 0 °C to 50 °C&lt;br /&gt;
* Relative humidity measurement range: 20% to 90%&lt;br /&gt;
* Digital single-wire data interface&lt;br /&gt;
&lt;br /&gt;
The DHT11 is suitable for basic IoT and environmental monitoring experiments.&lt;br /&gt;
&lt;br /&gt;
== System Architecture ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                 DHT11&lt;br /&gt;
                   |&lt;br /&gt;
             Temperature&lt;br /&gt;
             &amp;amp; Humidity&lt;br /&gt;
                   |&lt;br /&gt;
                   v&lt;br /&gt;
          +----------------+&lt;br /&gt;
          |     ESP32      |&lt;br /&gt;
          |   TCP Client   |&lt;br /&gt;
          +----------------+&lt;br /&gt;
                   |&lt;br /&gt;
                   | Wi-Fi&lt;br /&gt;
                   v&lt;br /&gt;
          +----------------+&lt;br /&gt;
          | Wi-Fi Router   |&lt;br /&gt;
          +----------------+&lt;br /&gt;
                   |&lt;br /&gt;
                   | TCP/IP&lt;br /&gt;
                   v&lt;br /&gt;
          +----------------+&lt;br /&gt;
          | Remote Computer|&lt;br /&gt;
          |  Python Server |&lt;br /&gt;
          +----------------+&lt;br /&gt;
                   |&lt;br /&gt;
                   v&lt;br /&gt;
          Temperature &amp;amp;&lt;br /&gt;
          Humidity Display&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 3V3&lt;br /&gt;
| VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| DATA&lt;br /&gt;
| Digital data connection&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The connections assume a compatible DHT11 module with clearly identified VCC, DATA and GND pins. Verify the actual sensor-board pinout before making the connections.&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== ESP32 ===&lt;br /&gt;
&lt;br /&gt;
* Arduino IDE&lt;br /&gt;
* ESP32 board support package&lt;br /&gt;
* DHT sensor library&lt;br /&gt;
* Adafruit Unified Sensor library&lt;br /&gt;
* Wi-Fi library included with the ESP32 board package&lt;br /&gt;
&lt;br /&gt;
=== Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
* Python 3&lt;br /&gt;
* Wi-Fi connection&lt;br /&gt;
* TCP/IP network connectivity&lt;br /&gt;
* TCP port 5000 available for the experiment&lt;br /&gt;
&lt;br /&gt;
The Python &#039;&#039;&#039;socket&#039;&#039;&#039; module is included with Python 3. No additional Python package is required.&lt;br /&gt;
&lt;br /&gt;
== Programs ==&lt;br /&gt;
&lt;br /&gt;
Two programs are required for this experiment.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Program&lt;br /&gt;
! Platform&lt;br /&gt;
! Function&lt;br /&gt;
|-&lt;br /&gt;
| Program 1: TCP Server&lt;br /&gt;
| Remote Computer&lt;br /&gt;
| Receives temperature and humidity data from ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| Program 2: ESP32 TCP Client&lt;br /&gt;
| ESP32&lt;br /&gt;
| Connects to Wi-Fi, reads DHT11 data and transmits it to the TCP server.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Download Programs ===&lt;br /&gt;
&lt;br /&gt;
The complete source code for both programs is provided in a single ZIP file.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Download:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Media:IoT_TCP_DHT11_Programs.zip|Download ESP32 and Python TCP/IP Programs]]&lt;br /&gt;
&lt;br /&gt;
The ZIP file contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
IoT_TCP_DHT11_Programs.zip&lt;br /&gt;
|&lt;br /&gt;
+-- tcp_server.py&lt;br /&gt;
|&lt;br /&gt;
+-- ESP32_DHT11_TCP_Client&lt;br /&gt;
    |&lt;br /&gt;
    +-- ESP32_DHT11_TCP_Client.ino&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Program 1: Python TCP Server ===&lt;br /&gt;
&lt;br /&gt;
The Python TCP Server runs on the remote computer.&lt;br /&gt;
&lt;br /&gt;
Its functions are:&lt;br /&gt;
&lt;br /&gt;
* Creates a TCP socket.&lt;br /&gt;
* Listens for incoming connections on port 5000.&lt;br /&gt;
* Accepts the connection from the ESP32.&lt;br /&gt;
* Receives sensor data transmitted by the ESP32.&lt;br /&gt;
* Displays the received temperature and humidity values.&lt;br /&gt;
* Detects when the ESP32 disconnects.&lt;br /&gt;
&lt;br /&gt;
The Python program is provided in the downloaded ZIP file as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tcp_server.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Program 2: ESP32 TCP Client ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 TCP Client runs on the ESP32.&lt;br /&gt;
&lt;br /&gt;
Its functions are:&lt;br /&gt;
&lt;br /&gt;
* Connects the ESP32 to the specified Wi-Fi network.&lt;br /&gt;
* Reads temperature from the DHT11 sensor.&lt;br /&gt;
* Reads relative humidity from the DHT11 sensor.&lt;br /&gt;
* Establishes a TCP connection with the remote computer.&lt;br /&gt;
* Transmits temperature and humidity data to the Python TCP server.&lt;br /&gt;
* Displays Wi-Fi, TCP and sensor information on the Serial Monitor.&lt;br /&gt;
&lt;br /&gt;
The Arduino program is provided in the downloaded ZIP file as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32_DHT11_TCP_Client/ESP32_DHT11_TCP_Client.ino&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program Configuration ==&lt;br /&gt;
&lt;br /&gt;
Before uploading the ESP32 program, configure the following parameters in the downloaded Arduino program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Description&lt;br /&gt;
! Example&lt;br /&gt;
|-&lt;br /&gt;
| Wi-Fi SSID&lt;br /&gt;
| Name of the Wi-Fi network&lt;br /&gt;
| MyWiFi&lt;br /&gt;
|-&lt;br /&gt;
| Wi-Fi Password&lt;br /&gt;
| Password of the Wi-Fi network&lt;br /&gt;
| mypassword123&lt;br /&gt;
|-&lt;br /&gt;
| Server IP Address&lt;br /&gt;
| IPv4 address of the remote computer running the Python server&lt;br /&gt;
| 192.168.1.100&lt;br /&gt;
|-&lt;br /&gt;
| Server Port&lt;br /&gt;
| TCP port used by the Python server&lt;br /&gt;
| 5000&lt;br /&gt;
|-&lt;br /&gt;
| DHT Pin&lt;br /&gt;
| ESP32 GPIO connected to DHT11 DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The Wi-Fi SSID, Wi-Fi password and Server IP Address must be changed according to the actual laboratory setup.&lt;br /&gt;
&lt;br /&gt;
The TCP port must remain the same in both programs.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Connect the Hardware ===&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using the USB data cable.&lt;br /&gt;
# Connect the remote computer to the Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Find the IP Address of the Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
The IP address of the remote computer is required because the ESP32 must know where the TCP server is located.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
&lt;br /&gt;
# Connect the remote computer to the required Wi-Fi network.&lt;br /&gt;
# Open &#039;&#039;&#039;Command Prompt&#039;&#039;&#039;.&lt;br /&gt;
# Type the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ipconfig&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Press Enter.&lt;br /&gt;
# Locate the &#039;&#039;&#039;Wireless LAN adapter Wi-Fi&#039;&#039;&#039; section.&lt;br /&gt;
# Find the &#039;&#039;&#039;IPv4 Address&#039;&#039;&#039; entry.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Wireless LAN adapter Wi-Fi:&lt;br /&gt;
&lt;br /&gt;
   IPv4 Address. . . . . . . . . . . : 192.168.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, the remote computer IP address is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Record this address.&lt;br /&gt;
# Enter this address as the TCP server IP address in the ESP32 program.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; Use the &#039;&#039;&#039;IPv4 Address&#039;&#039;&#039; of the remote computer. Do not use the &#039;&#039;&#039;Default Gateway&#039;&#039;&#039; address.&lt;br /&gt;
&lt;br /&gt;
==== Linux ====&lt;br /&gt;
&lt;br /&gt;
Open the Terminal and use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
hostname -I&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip addr&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Identify the IPv4 address of the Wi-Fi interface.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.100&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use this address as the TCP server IP address in the ESP32 program.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Download the Programs ===&lt;br /&gt;
&lt;br /&gt;
# Download the program ZIP file:&lt;br /&gt;
&lt;br /&gt;
[[Media:IoT_TCP_DHT11_Programs.zip|Download ESP32 and Python TCP/IP Programs]]&lt;br /&gt;
&lt;br /&gt;
# Extract the ZIP file.&lt;br /&gt;
# Verify that the following files are available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tcp_server.py&lt;br /&gt;
&lt;br /&gt;
ESP32_DHT11_TCP_Client/&lt;br /&gt;
    ESP32_DHT11_TCP_Client.ino&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Configure the Python TCP Server ===&lt;br /&gt;
&lt;br /&gt;
# Open the extracted &#039;&#039;&#039;tcp_server.py&#039;&#039;&#039; file.&lt;br /&gt;
# The Python server uses TCP port 5000.&lt;br /&gt;
# Open Command Prompt or Terminal.&lt;br /&gt;
# Navigate to the folder containing &#039;&#039;&#039;tcp_server.py&#039;&#039;&#039;.&lt;br /&gt;
# Run the following command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python tcp_server.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If required, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python3 tcp_server.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The expected output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
----------------------------------&lt;br /&gt;
ESP32 DHT11 TCP Receiver&lt;br /&gt;
----------------------------------&lt;br /&gt;
TCP Server started&lt;br /&gt;
Listening on port: 5000&lt;br /&gt;
Waiting for ESP32 connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Keep the Python TCP server running during the experiment.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: Configure the ESP32 Program ===&lt;br /&gt;
&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Open the file &#039;&#039;&#039;ESP32_DHT11_TCP_Client.ino&#039;&#039;&#039; from the downloaded ZIP file.&lt;br /&gt;
# Enter the Wi-Fi network name.&lt;br /&gt;
# Enter the Wi-Fi password.&lt;br /&gt;
# Enter the IPv4 address of the remote computer.&lt;br /&gt;
# Verify that the TCP port is set to 5000.&lt;br /&gt;
# Verify that the DHT11 DATA pin is configured as GPIO 4.&lt;br /&gt;
# Select the appropriate ESP32 board.&lt;br /&gt;
# Select the correct COM port.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Install Required Arduino Libraries ===&lt;br /&gt;
&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Open Library Manager.&lt;br /&gt;
# Search for &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039;.&lt;br /&gt;
# Install the &#039;&#039;&#039;DHT sensor library by Adafruit&#039;&#039;&#039;.&lt;br /&gt;
# Install &#039;&#039;&#039;Adafruit Unified Sensor&#039;&#039;&#039; if required.&lt;br /&gt;
# Ensure that the ESP32 board package is installed.&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;WiFi&#039;&#039;&#039; library is included with the ESP32 board support package.&lt;br /&gt;
&lt;br /&gt;
=== Step 7: Upload the ESP32 Program ===&lt;br /&gt;
&lt;br /&gt;
# Compile the ESP32 program.&lt;br /&gt;
# Upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor.&lt;br /&gt;
# Set the baud rate to &#039;&#039;&#039;115200&#039;&#039;&#039;.&lt;br /&gt;
# Observe the Wi-Fi connection status.&lt;br /&gt;
# Observe the ESP32 IP address.&lt;br /&gt;
# Observe the TCP connection status.&lt;br /&gt;
# Observe the transmitted DHT11 readings.&lt;br /&gt;
&lt;br /&gt;
Expected output:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32 DHT11 TCP/IP Client&lt;br /&gt;
----------------------------------&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected!&lt;br /&gt;
ESP32 IP Address: 192.168.1.120&lt;br /&gt;
&lt;br /&gt;
Connecting to TCP server: 192.168.1.100:5000&lt;br /&gt;
TCP server connected!&lt;br /&gt;
&lt;br /&gt;
Sent: Temperature: 28.4 C, Humidity: 61.0 %&lt;br /&gt;
Sent: Temperature: 28.5 C, Humidity: 61.0 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 8: Verify Data on the Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
The Python TCP server should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32 connected!&lt;br /&gt;
Client IP: 192.168.1.120&lt;br /&gt;
----------------------------------&lt;br /&gt;
Received: Temperature: 28.4 C, Humidity: 61.0 %&lt;br /&gt;
Received: Temperature: 28.5 C, Humidity: 61.0 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP addresses and sensor readings shown above are illustrative examples. Actual values will depend on the network and environment.&lt;br /&gt;
&lt;br /&gt;
=== Step 9: Verify TCP/IP Communication ===&lt;br /&gt;
&lt;br /&gt;
# Confirm that the ESP32 successfully connects to Wi-Fi.&lt;br /&gt;
# Confirm that the ESP32 obtains an IP address.&lt;br /&gt;
# Confirm that the ESP32 establishes a TCP connection with the remote computer.&lt;br /&gt;
# Confirm that the Python server reports the ESP32 connection.&lt;br /&gt;
# Verify that temperature and humidity values are received.&lt;br /&gt;
# Compare the values transmitted by the ESP32 with the values displayed by the Python server.&lt;br /&gt;
# Disconnect or reset the ESP32.&lt;br /&gt;
# Observe the disconnection message on the Python server.&lt;br /&gt;
&lt;br /&gt;
== TCP Communication Sequence ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. Start Python TCP Server&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
2. Server listens on TCP port 5000&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
3. ESP32 connects to Wi-Fi&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
4. ESP32 connects to Remote Computer&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
5. TCP connection established&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
6. ESP32 reads DHT11&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
7. ESP32 transmits sensor data&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
8. Python server receives data&lt;br /&gt;
             |&lt;br /&gt;
             v&lt;br /&gt;
9. Temperature and humidity displayed&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Important Network Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following conditions must be satisfied for successful communication.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Requirement&lt;br /&gt;
|-&lt;br /&gt;
| ESP32 Wi-Fi&lt;br /&gt;
| Connected to the Wi-Fi network&lt;br /&gt;
|-&lt;br /&gt;
| Remote Computer&lt;br /&gt;
| Connected to the same Wi-Fi or LAN&lt;br /&gt;
|-&lt;br /&gt;
| Server IP&lt;br /&gt;
| Must be the IPv4 address of the remote computer&lt;br /&gt;
|-&lt;br /&gt;
| TCP Port&lt;br /&gt;
| 5000&lt;br /&gt;
|-&lt;br /&gt;
| Python Server&lt;br /&gt;
| Must be running before the ESP32 attempts connection&lt;br /&gt;
|-&lt;br /&gt;
| Firewall&lt;br /&gt;
| Must allow TCP communication on port 5000&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; The IP address of the remote computer may change when it reconnects to the Wi-Fi network. If the ESP32 cannot connect after a network change, check the computer&#039;s IPv4 address again using &#039;&#039;&#039;ipconfig&#039;&#039;&#039; and update the ESP32 program if necessary.&lt;br /&gt;
&lt;br /&gt;
== Windows Firewall Configuration ==&lt;br /&gt;
&lt;br /&gt;
If the ESP32 cannot connect to the Python server, Windows Firewall may be blocking incoming connections.&lt;br /&gt;
&lt;br /&gt;
# Open &#039;&#039;&#039;Windows Security&#039;&#039;&#039;.&lt;br /&gt;
# Select &#039;&#039;&#039;Firewall &amp;amp; network protection&#039;&#039;&#039;.&lt;br /&gt;
# Select &#039;&#039;&#039;Advanced settings&#039;&#039;&#039;.&lt;br /&gt;
# Select &#039;&#039;&#039;Inbound Rules&#039;&#039;&#039;.&lt;br /&gt;
# Create a new inbound rule.&lt;br /&gt;
# Select &#039;&#039;&#039;Port&#039;&#039;&#039;.&lt;br /&gt;
# Select &#039;&#039;&#039;TCP&#039;&#039;&#039;.&lt;br /&gt;
# Enter port &#039;&#039;&#039;5000&#039;&#039;&#039;.&lt;br /&gt;
# Select &#039;&#039;&#039;Allow the connection&#039;&#039;&#039;.&lt;br /&gt;
# Apply the rule to the appropriate network profile.&lt;br /&gt;
# Give the rule a suitable name such as &#039;&#039;&#039;ESP32 TCP Server Port 5000&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alternatively, Windows may display a firewall permission dialog when Python first attempts to accept a network connection. Allow Python to communicate on the appropriate network.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Problem&lt;br /&gt;
! Possible Cause&lt;br /&gt;
! Solution&lt;br /&gt;
|-&lt;br /&gt;
| ESP32 cannot connect to Wi-Fi&lt;br /&gt;
| Incorrect SSID or password&lt;br /&gt;
| Verify the Wi-Fi name and password.&lt;br /&gt;
|-&lt;br /&gt;
| ESP32 connects to Wi-Fi but TCP connection fails&lt;br /&gt;
| Incorrect server IP&lt;br /&gt;
| Run &#039;&#039;&#039;ipconfig&#039;&#039;&#039; and verify the computer&#039;s IPv4 address.&lt;br /&gt;
|-&lt;br /&gt;
| Python server does not receive data&lt;br /&gt;
| Server not running&lt;br /&gt;
| Start &#039;&#039;&#039;python tcp_server.py&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Connection refused&lt;br /&gt;
| TCP server is not listening&lt;br /&gt;
| Start the Python TCP server and verify port 5000.&lt;br /&gt;
|-&lt;br /&gt;
| Connection timeout&lt;br /&gt;
| Firewall blocking TCP communication&lt;br /&gt;
| Allow TCP port 5000 through the firewall.&lt;br /&gt;
|-&lt;br /&gt;
| DHT11 reading fails&lt;br /&gt;
| Incorrect sensor connection&lt;br /&gt;
| Check VCC, DATA, GND and GPIO 4 connections.&lt;br /&gt;
|-&lt;br /&gt;
| Devices cannot communicate&lt;br /&gt;
| Different Wi-Fi networks&lt;br /&gt;
| Connect ESP32 and remote computer to the same network.&lt;br /&gt;
|-&lt;br /&gt;
| Wrong IP address&lt;br /&gt;
| Gateway address used instead of computer IP&lt;br /&gt;
| Use the computer&#039;s IPv4 Address shown by &#039;&#039;&#039;ipconfig&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
| Python command not recognized&lt;br /&gt;
| Python is not installed or not added to PATH&lt;br /&gt;
| Install Python 3 and add Python to PATH.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Temperature (C)&lt;br /&gt;
! Relative Humidity (percent)&lt;br /&gt;
! TCP Transmission Status&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Expected Output ==&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32 DHT11 TCP/IP Client&lt;br /&gt;
----------------------------------&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected!&lt;br /&gt;
ESP32 IP Address: 192.168.1.120&lt;br /&gt;
&lt;br /&gt;
Connecting to TCP server: 192.168.1.100:5000&lt;br /&gt;
TCP server connected!&lt;br /&gt;
&lt;br /&gt;
Sent: Temperature: 28.4 C, Humidity: 61.0 %&lt;br /&gt;
Sent: Temperature: 28.5 C, Humidity: 61.0 %&lt;br /&gt;
Sent: Temperature: 28.5 C, Humidity: 62.0 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
----------------------------------&lt;br /&gt;
ESP32 DHT11 TCP Receiver&lt;br /&gt;
----------------------------------&lt;br /&gt;
TCP Server started&lt;br /&gt;
Listening on port: 5000&lt;br /&gt;
Waiting for ESP32 connection...&lt;br /&gt;
&lt;br /&gt;
ESP32 connected!&lt;br /&gt;
Client IP: 192.168.1.120&lt;br /&gt;
----------------------------------&lt;br /&gt;
Received: Temperature: 28.4 C, Humidity: 61.0 %&lt;br /&gt;
Received: Temperature: 28.5 C, Humidity: 61.0 %&lt;br /&gt;
Received: Temperature: 28.5 C, Humidity: 62.0 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP addresses and sensor readings shown above are illustrative examples and may differ during the actual experiment.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An IoT application was successfully implemented using ESP32 and DHT11. The ESP32 was connected to a Wi-Fi network and configured as a TCP client. A remote computer was configured as a Python TCP server. Temperature and humidity data obtained from the DHT11 sensor was successfully transmitted from the ESP32 to the remote computer using TCP/IP socket communication.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is the role of Wi-Fi in this experiment?&lt;br /&gt;
# What is TCP?&lt;br /&gt;
# What is the difference between TCP and UDP?&lt;br /&gt;
# What is an IP address?&lt;br /&gt;
# How do you find the IPv4 address of a Windows computer?&lt;br /&gt;
# Why is the remote computer&#039;s IPv4 address entered in the ESP32 program?&lt;br /&gt;
# What is a TCP socket?&lt;br /&gt;
# What is the difference between a TCP client and a TCP server?&lt;br /&gt;
# Why is the ESP32 configured as a TCP client?&lt;br /&gt;
# Why is the remote computer configured as a TCP server?&lt;br /&gt;
# Why is TCP considered a reliable protocol?&lt;br /&gt;
# What is the purpose of the &#039;&#039;&#039;bind()&#039;&#039;&#039; function?&lt;br /&gt;
# What is the purpose of the &#039;&#039;&#039;listen()&#039;&#039;&#039; function?&lt;br /&gt;
# What is the purpose of the &#039;&#039;&#039;accept()&#039;&#039;&#039; function?&lt;br /&gt;
# What is the purpose of the &#039;&#039;&#039;recv()&#039;&#039;&#039; function?&lt;br /&gt;
# What is the purpose of &#039;&#039;&#039;client.connect()&#039;&#039;&#039; in the ESP32 program?&lt;br /&gt;
# Why must the TCP port number be the same in both programs?&lt;br /&gt;
# Why is port 5000 used in this experiment?&lt;br /&gt;
# What happens if Windows Firewall blocks port 5000?&lt;br /&gt;
# Why should the ESP32 and remote computer normally be connected to the same Wi-Fi network?&lt;br /&gt;
# What is the purpose of &#039;&#039;&#039;WiFi.localIP()&#039;&#039;&#039;?&lt;br /&gt;
# What is the difference between the ESP32 IP address and the remote computer IP address?&lt;br /&gt;
# How can this experiment be extended to store sensor readings in a database?&lt;br /&gt;
# How can this experiment be extended to send data to a cloud platform?&lt;br /&gt;
# What are the advantages of using TCP for sensor data transmission?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1365</id>
		<title>MDM331AID/Experiment 9</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1365"/>
		<updated>2026-10-07T17:31:15Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Introducing Manual Anomalies */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Perform Data Cleaning, Normalization, and Visualization on IoT Sensor Dataset =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To perform data cleaning, normalization, and visualization on an IoT sensor dataset and prepare the data for further analysis.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of data preprocessing in IoT applications.&lt;br /&gt;
* To inspect and identify missing, duplicate, inconsistent, and anomalous sensor data.&lt;br /&gt;
* To clean an IoT sensor dataset using appropriate data-cleaning techniques.&lt;br /&gt;
* To normalize sensor values to a standard numerical range.&lt;br /&gt;
* To visualize sensor data using suitable graphs.&lt;br /&gt;
* To compare the dataset before and after data cleaning and normalization.&lt;br /&gt;
* To understand how data preprocessing improves the quality and usability of IoT sensor data.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| IoT sensor dataset in CSV format&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jupyter Notebook / Google Colab / Python IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Pandas library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| NumPy library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Matplotlib library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data preprocessing&#039;&#039;&#039; is the process of preparing raw data for analysis by identifying and correcting problems such as missing values, duplicate records, incorrect data types, inconsistent values, and anomalous observations.&lt;br /&gt;
&lt;br /&gt;
IoT systems continuously generate sensor data. The collected data may contain errors due to sensor limitations, communication problems, transmission errors, incorrect entries, or abnormal operating conditions. Therefore, raw IoT data should be cleaned and transformed before it is used for analysis or visualization.&lt;br /&gt;
&lt;br /&gt;
The main stages of data preprocessing performed in this experiment are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Data inspection:&#039;&#039;&#039; Examining the structure, columns, data types, number of records, and statistical properties of the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Data cleaning:&#039;&#039;&#039; Identifying and handling missing values, duplicate records, invalid values, and anomalous observations.&lt;br /&gt;
* &#039;&#039;&#039;Data transformation:&#039;&#039;&#039; Converting data into suitable formats for analysis, such as converting timestamp values into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;Data normalization:&#039;&#039;&#039; Scaling numerical sensor values to a standard range so that they can be compared and processed more easily.&lt;br /&gt;
* &#039;&#039;&#039;Data visualization:&#039;&#039;&#039; Representing the processed data graphically to identify patterns, trends, variations, and anomalies.&lt;br /&gt;
&lt;br /&gt;
The dataset used in this experiment is an IoT temperature dataset obtained from the Cognifront cloud platform. The dataset contains the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Column&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| ID&lt;br /&gt;
| Unique record identifier generated for the sensor data record&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| Name of the sensor variable. In this dataset, it is DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Value&lt;br /&gt;
| Temperature value recorded by the sensor&lt;br /&gt;
|-&lt;br /&gt;
| Date&lt;br /&gt;
| Date and time at which the sensor reading was recorded&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The original dataset contains &#039;&#039;&#039;547 records&#039;&#039;&#039; and four columns: ID, Name, Value and Date. The Value column contains temperature readings, while the Date column contains the corresponding timestamps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing values&#039;&#039;&#039; are records where one or more required fields contain no valid value. Missing values may be removed or replaced depending on the nature of the dataset and the purpose of the analysis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Duplicate records&#039;&#039;&#039; are repeated records that contain the same data more than once. Duplicate records can occur because of repeated data transmission or storage operations and may need to be removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anomalies&#039;&#039;&#039; are observations that differ significantly from the normal pattern of the dataset. In a temperature dataset, an unusually high or low value may represent a sensor error, transmission error, or abnormal environmental condition. Anomalies should be investigated before deciding whether they should be removed, corrected, or retained.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normalization&#039;&#039;&#039; is the process of transforming numerical values to a common scale. In this experiment, Min-Max normalization is used to transform the temperature values into the range 0 to 1.&lt;br /&gt;
&lt;br /&gt;
The Min-Max normalization formula is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;X&#039;&#039;&#039; is the original sensor value.&lt;br /&gt;
* &#039;&#039;&#039;Xmin&#039;&#039;&#039; is the minimum value in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Xmax&#039;&#039;&#039; is the maximum value in the dataset.&lt;br /&gt;
&lt;br /&gt;
After normalization, the smallest value becomes 0 and the largest value becomes 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data visualization&#039;&#039;&#039; is used to represent the processed sensor data graphically. A line graph can be used to show temperature variation with time, while a histogram can be used to observe the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
The overall data-processing flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raw IoT CSV Dataset&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Inspection&lt;br /&gt;
        ↓&lt;br /&gt;
    Data Cleaning&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Transformation&lt;br /&gt;
        ↓&lt;br /&gt;
     Normalization&lt;br /&gt;
        ↓&lt;br /&gt;
     Visualization&lt;br /&gt;
        ↓&lt;br /&gt;
  Processed Dataset&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dataset Used ==&lt;br /&gt;
&lt;br /&gt;
The dataset used for this experiment is a DHT11 temperature dataset exported from the Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
The original dataset contains:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Number of records&lt;br /&gt;
| 547&lt;br /&gt;
|-&lt;br /&gt;
| Number of columns&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| Sensor variable&lt;br /&gt;
| DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Minimum temperature&lt;br /&gt;
| 27.1 °C&lt;br /&gt;
|-&lt;br /&gt;
| Maximum temperature&lt;br /&gt;
| 27.8 °C&lt;br /&gt;
|-&lt;br /&gt;
| Missing values&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate timestamps&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries before running the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program loads the IoT dataset, inspects the data, performs data cleaning, normalizes the temperature values using Min-Max normalization, and generates visualizations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from google.colab import files&lt;br /&gt;
dht_data = files.upload()&lt;br /&gt;
&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
# Load the dataset&lt;br /&gt;
df = pd.read_csv(&#039;anomalous-dht11-data.csv&#039;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDataset Information&amp;quot;)&lt;br /&gt;
print(df.info())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nMissing Values&amp;quot;)&lt;br /&gt;
print(df.isnull().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDuplicate Records&amp;quot;)&lt;br /&gt;
print(df.duplicated().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nStatistical Summary&amp;quot;)&lt;br /&gt;
print(df.describe())&lt;br /&gt;
&lt;br /&gt;
# Convert Date column to datetime&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(df[&amp;quot;Date&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Convert Value column to numeric&lt;br /&gt;
df[&amp;quot;Value&amp;quot;] = pd.to_numeric(df[&amp;quot;Value&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remove rows with missing required values&lt;br /&gt;
df = df.dropna(subset=[&amp;quot;ID&amp;quot;, &amp;quot;Name&amp;quot;, &amp;quot;Value&amp;quot;, &amp;quot;Date&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
# Remove duplicate records&lt;br /&gt;
df = df.drop_duplicates()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;# Now to remove *outliers*, we will use 2 methods:&lt;br /&gt;
&lt;br /&gt;
1.  Using IQR (Interquartile Range) method&lt;br /&gt;
2.  Using Domain-based method&lt;br /&gt;
&lt;br /&gt;
For our particular dataset, you will see why Domain-based method is more applicable by looking at the output of IQR method.&lt;br /&gt;
&lt;br /&gt;
**1) IQR (Interquartile Range) method**&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Detect temperature outliers using IQR&lt;br /&gt;
Q1 = df[&amp;quot;Value&amp;quot;].quantile(0.25)&lt;br /&gt;
Q3 = df[&amp;quot;Value&amp;quot;].quantile(0.75)&lt;br /&gt;
IQR = Q3 - Q1&lt;br /&gt;
&lt;br /&gt;
lower_limit = Q1 - 1.5 * IQR&lt;br /&gt;
upper_limit = Q3 + 1.5 * IQR&lt;br /&gt;
&lt;br /&gt;
outliers = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt; lower_limit) |&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt; upper_limit)&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDetected Outliers&amp;quot;)&lt;br /&gt;
print(outliers)&lt;br /&gt;
&lt;br /&gt;
# Remove detected outliers&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;**2) Domain-based method**&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lower_limit = 15&lt;br /&gt;
upper_limit = 50&lt;br /&gt;
&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
# Min-Max normalization&lt;br /&gt;
min_value = df_clean[&amp;quot;Value&amp;quot;].min()&lt;br /&gt;
max_value = df_clean[&amp;quot;Value&amp;quot;].max()&lt;br /&gt;
&lt;br /&gt;
df_clean[&amp;quot;Normalized_Value&amp;quot;] = (&lt;br /&gt;
    (df_clean[&amp;quot;Value&amp;quot;] - min_value) /&lt;br /&gt;
    (max_value - min_value)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Save cleaned and normalized dataset&lt;br /&gt;
df_clean.to_csv(&lt;br /&gt;
    &amp;quot;cleaned_normalized_dht11_data.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nCleaned Dataset&amp;quot;)&lt;br /&gt;
print(df_clean.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nNormalized Dataset&amp;quot;)&lt;br /&gt;
print(df_clean[[&amp;quot;Value&amp;quot;, &amp;quot;Normalized_Value&amp;quot;]].head())&lt;br /&gt;
&lt;br /&gt;
# Visualization 1: Temperature vs Time&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 2: Temperature distribution&lt;br /&gt;
plt.figure(figsize=(8, 5))&lt;br /&gt;
&lt;br /&gt;
plt.hist(&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    bins=10&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Frequency&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Distribution of DHT11 Temperature Values&amp;quot;)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 3: Normalized temperature&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Normalized_Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Normalized Temperature&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Normalized DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;files.upload():&#039;&#039;&#039; Opens a file-upload interface in Google Colab so that the IoT sensor CSV dataset can be uploaded.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the uploaded CSV dataset into a Pandas DataFrame.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.head():&#039;&#039;&#039; Displays the first few records of the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.info():&#039;&#039;&#039; Displays information about the columns, data types and number of non-null records.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;isnull().sum():&#039;&#039;&#039; Counts the number of missing values in each column.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;duplicated().sum():&#039;&#039;&#039; Counts the number of duplicate records in the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.describe():&#039;&#039;&#039; Displays statistical information such as count, mean, standard deviation, minimum and maximum values of numerical columns.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a proper date-time format. Invalid date values are converted to missing values using &#039;&#039;&#039;errors=&amp;quot;coerce&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the Value column into numerical data. Invalid values are converted to missing values using &#039;&#039;&#039;errors=&amp;quot;coerce&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records containing missing values in the required ID, Name, Value or Date fields.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;drop_duplicates():&#039;&#039;&#039; Removes duplicate records from the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Q1 and Q3:&#039;&#039;&#039; Represent the first and third quartiles of the temperature data and are used for IQR-based outlier detection.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR:&#039;&#039;&#039; Represents the Interquartile Range and is calculated as Q3 − Q1.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR outlier limits:&#039;&#039;&#039; Values below Q1 − 1.5 × IQR or above Q3 + 1.5 × IQR are identified as potential outliers.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR outlier detection:&#039;&#039;&#039; Identifies and displays potential outliers using the statistical IQR method. In this experiment, the IQR method is demonstrated for comparison but is not used for the final cleaning because the normal temperature readings are closely clustered.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Domain-based outlier detection:&#039;&#039;&#039; Defines an acceptable temperature range of 15 °C to 50 °C. Values outside this range are treated as anomalous temperature readings.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df_clean:&#039;&#039;&#039; Stores the final cleaned dataset after applying the domain-based temperature limits.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Min-Max normalization:&#039;&#039;&#039; Transforms the cleaned temperature values into the range 0 to 1 using the formula:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;to_csv():&#039;&#039;&#039; Saves the cleaned and normalized dataset as a new CSV file named &#039;&#039;&#039;cleaned_normalized_dht11_data.csv&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plt.plot():&#039;&#039;&#039; Creates a line graph showing the variation of temperature with respect to date and time.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plt.hist():&#039;&#039;&#039; Creates a histogram showing the distribution and frequency of the cleaned temperature values.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Normalized temperature plot:&#039;&#039;&#039; Displays the normalized temperature values against time to show the sensor readings after Min-Max normalization.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Obtain the DHT11 sensor dataset in CSV format from the Cognifront cloud platform.&lt;br /&gt;
# Make a copy of the original CSV file and use the copy for data-cleaning experiments.&lt;br /&gt;
# Open the Python environment such as Jupyter Notebook, Google Colab or a Python IDE.&lt;br /&gt;
# Install the required Pandas, NumPy and Matplotlib libraries.&lt;br /&gt;
# Load the CSV dataset using Pandas.&lt;br /&gt;
# Inspect the dataset and identify its columns, data types and number of records.&lt;br /&gt;
# Check the dataset for missing values.&lt;br /&gt;
# Check the dataset for duplicate records.&lt;br /&gt;
# Convert the Date column into the appropriate date-time format.&lt;br /&gt;
# Convert the sensor Value column into numerical format.&lt;br /&gt;
# Identify anomalous sensor values using statistical methods such as the IQR method.&lt;br /&gt;
# Remove or handle the identified invalid or anomalous records as required.&lt;br /&gt;
# Normalize the cleaned sensor values using Min-Max normalization.&lt;br /&gt;
# Save the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
# Plot the temperature values against time using a line graph.&lt;br /&gt;
# Plot the distribution of temperature values using a histogram.&lt;br /&gt;
# Plot the normalized temperature values against time.&lt;br /&gt;
# Compare the original and processed datasets and observe the effect of data cleaning and normalization.&lt;br /&gt;
&lt;br /&gt;
== Introducing Manual Anomalies ==&lt;br /&gt;
&lt;br /&gt;
The original Cognifront dataset is relatively clean. Therefore, for demonstrating data-cleaning techniques, controlled anomalies can be introduced into a &#039;&#039;&#039;copy&#039;&#039;&#039; of the original dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not modify the original downloaded dataset.&#039;&#039;&#039; Keep the original file as the raw dataset and create a separate file such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
anomalous-dht11-data.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following anomalies can be introduced for demonstration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Anomaly&lt;br /&gt;
! Example&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Missing value&lt;br /&gt;
| Replace a Value entry with an empty cell&lt;br /&gt;
| Demonstrates missing-value handling&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate record&lt;br /&gt;
| Copy one complete row and insert it again&lt;br /&gt;
| Demonstrates duplicate detection&lt;br /&gt;
|-&lt;br /&gt;
| Extreme temperature&lt;br /&gt;
| Change one Value to 80 °C&lt;br /&gt;
| Demonstrates outlier detection&lt;br /&gt;
|-&lt;br /&gt;
| Very low temperature&lt;br /&gt;
| Change one Value to -20 °C&lt;br /&gt;
| Demonstrates anomalous-value detection&lt;br /&gt;
|-&lt;br /&gt;
| Invalid value&lt;br /&gt;
| Replace one Value with text such as &amp;quot;ERROR&amp;quot;&lt;br /&gt;
| Demonstrates invalid data handling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, if the original data contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,27.5,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the Value can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,80,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, another record can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296950,DHT-Temp,,2026-10-07 08:51:15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to demonstrate a missing sensor value.&lt;br /&gt;
&lt;br /&gt;
An existing row can also be copied and inserted again to create a duplicate record.&lt;br /&gt;
&lt;br /&gt;
The modified dataset can then be processed using the Python program. The program should identify the missing, duplicate and anomalous records and produce a cleaned dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These manually introduced anomalies are artificial and are used only to demonstrate data-cleaning techniques. They should not be presented as actual errors produced by the DHT11 sensor or Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Operation&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Dataset inspection&lt;br /&gt;
| Dataset contains 547 records and 4 columns&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Missing-value check&lt;br /&gt;
| Original dataset contains no missing values&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Duplicate check&lt;br /&gt;
| Original dataset contains no duplicate records&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Data type conversion&lt;br /&gt;
| Date converted to datetime and Value converted to numeric&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Anomaly detection&lt;br /&gt;
| Artificial anomalous records are identified in the modified dataset&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Data cleaning&lt;br /&gt;
| Missing, duplicate and anomalous records are handled&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Normalization&lt;br /&gt;
| Temperature values are converted to the range 0 to 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Visualization&lt;br /&gt;
| Temperature variation and distribution are represented graphically&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| CSV export&lt;br /&gt;
| Cleaned and normalized data is saved as a new CSV file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT sensor dataset was successfully inspected, cleaned and normalized using Python. Missing values, duplicate records and anomalous sensor readings were identified and handled. The temperature values were normalized using Min-Max normalization, and the processed data was visualized using suitable graphs. The cleaned and normalized dataset was successfully exported as a CSV file.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is data preprocessing?&lt;br /&gt;
# Why is data cleaning required for IoT sensor data?&lt;br /&gt;
# What is the difference between raw data and cleaned data?&lt;br /&gt;
# What is a missing value?&lt;br /&gt;
# What is a duplicate record?&lt;br /&gt;
# What is an anomaly in a sensor dataset?&lt;br /&gt;
# Why are artificial anomalies introduced during this experiment?&lt;br /&gt;
# What is the IQR method?&lt;br /&gt;
# How is an outlier detected using the IQR method?&lt;br /&gt;
# What is data normalization?&lt;br /&gt;
# What is Min-Max normalization?&lt;br /&gt;
# What is the range of values produced by Min-Max normalization?&lt;br /&gt;
# Why is the Date column converted into datetime format?&lt;br /&gt;
# What is the purpose of the Pandas library?&lt;br /&gt;
# What is the purpose of NumPy?&lt;br /&gt;
# What is Matplotlib used for?&lt;br /&gt;
# What is the purpose of a histogram?&lt;br /&gt;
# What information can be obtained from a line graph of sensor data?&lt;br /&gt;
# Why should the original dataset be preserved before data cleaning?&lt;br /&gt;
# Why should manually introduced anomalies not be considered actual sensor errors?&lt;br /&gt;
# What is the purpose of exporting the processed dataset as a CSV file?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_5&amp;diff=1364</id>
		<title>MDM331AID/Experiment 5</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_5&amp;diff=1364"/>
		<updated>2026-10-07T16:27:15Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Wi-Fi Connectivity and TCP/IP-Based Sensor Data Transmission Using ESP32 =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To configure and implement an IoT device using ESP32 to connect to a Wi-Fi network and transmit temperature and humidity data from a DHT11 sensor to a remote computer using TCP/IP communication.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand Wi-Fi connectivity in IoT devices.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with ESP32.&lt;br /&gt;
* To understand TCP/IP communication and socket programming.&lt;br /&gt;
* To establish a TCP connection between an ESP32 and a remote computer.&lt;br /&gt;
* To transmit and receive sensor data over a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board (COG-E32)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Temperature and Humidity Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Data Cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch Cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Remote Computer connected to the same Wi-Fi network&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Wi-Fi Network&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things (IoT) Device ===&lt;br /&gt;
&lt;br /&gt;
An IoT device is a physical device equipped with sensors, processing capabilities, and communication interfaces. It collects data from its surroundings and transmits the information to another device or a remote server.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 acts as the IoT device. The DHT11 sensor collects temperature and humidity readings, which are transmitted to a remote computer.&lt;br /&gt;
&lt;br /&gt;
=== Wi-Fi Connectivity ===&lt;br /&gt;
&lt;br /&gt;
Wi-Fi is a wireless networking technology based on IEEE 802.11 standards. It allows IoT devices to connect to a local wireless network and exchange information with other devices.&lt;br /&gt;
&lt;br /&gt;
The ESP32 has built-in Wi-Fi connectivity, making it suitable for IoT communication experiments without requiring an additional Wi-Fi module.&lt;br /&gt;
&lt;br /&gt;
=== TCP/IP Communication ===&lt;br /&gt;
&lt;br /&gt;
TCP/IP is a protocol suite used for communication between devices over a network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IP (Internet Protocol):&#039;&#039;&#039; Provides addressing and routing of data packets between devices.&lt;br /&gt;
* &#039;&#039;&#039;TCP (Transmission Control Protocol):&#039;&#039;&#039; Provides reliable, ordered, connection-oriented data delivery.&lt;br /&gt;
* &#039;&#039;&#039;Socket:&#039;&#039;&#039; A software interface used by applications to send and receive data over a network.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the remote computer runs a TCP server that listens for incoming connections. The ESP32 acts as a TCP client and sends sensor readings to the server.&lt;br /&gt;
&lt;br /&gt;
The basic communication flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     |&lt;br /&gt;
     v&lt;br /&gt;
   ESP32&lt;br /&gt;
     |&lt;br /&gt;
     v&lt;br /&gt;
 Wi-Fi Network&lt;br /&gt;
     |&lt;br /&gt;
     v&lt;br /&gt;
Remote Computer&lt;br /&gt;
     |&lt;br /&gt;
     v&lt;br /&gt;
 TCP Server&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DHT11 Sensor ===&lt;br /&gt;
&lt;br /&gt;
The DHT11 is a digital temperature and humidity sensor. It provides temperature and relative humidity readings through a single digital data interface.&lt;br /&gt;
&lt;br /&gt;
Typical measurement ranges are:&lt;br /&gt;
&lt;br /&gt;
* Temperature: 0 C to 50 C.&lt;br /&gt;
* Relative humidity: 20 percent to 90 percent.&lt;br /&gt;
&lt;br /&gt;
The DHT11 is suitable for basic environmental monitoring demonstrations. Its accuracy and measurement range are limited compared with more advanced sensors.&lt;br /&gt;
&lt;br /&gt;
=== System Architecture ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
       DHT11 Sensor&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +----------------+&lt;br /&gt;
     |     ESP32      |&lt;br /&gt;
     |   TCP Client   |&lt;br /&gt;
     +----------------+&lt;br /&gt;
            |&lt;br /&gt;
        Wi-Fi Network&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
     +----------------+&lt;br /&gt;
     | Remote Computer|&lt;br /&gt;
     |   TCP Server   |&lt;br /&gt;
     +----------------+&lt;br /&gt;
            |&lt;br /&gt;
            v&lt;br /&gt;
      Display Sensor&lt;br /&gt;
           Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 3V3&lt;br /&gt;
| VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| DATA&lt;br /&gt;
| Digital data interface&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The connections assume a compatible DHT11 module with clearly identified VCC, DATA, and GND pins. Verify the actual sensor-board pinout before making the connections.&lt;br /&gt;
&lt;br /&gt;
== Software Requirements ==&lt;br /&gt;
&lt;br /&gt;
=== ESP32 ===&lt;br /&gt;
&lt;br /&gt;
* Arduino IDE&lt;br /&gt;
* ESP32 board support package&lt;br /&gt;
* DHT sensor library&lt;br /&gt;
* Wi-Fi library included with the ESP32 board package&lt;br /&gt;
&lt;br /&gt;
=== Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
* Python 3&lt;br /&gt;
* TCP server program&lt;br /&gt;
* Wi-Fi connection&lt;br /&gt;
* Network access from the ESP32&lt;br /&gt;
&lt;br /&gt;
== Program 1: TCP Server on Remote Computer ==&lt;br /&gt;
&lt;br /&gt;
The remote computer acts as a TCP server. It listens on port 5000 and displays the temperature and humidity data received from the ESP32.&lt;br /&gt;
&lt;br /&gt;
Download the program:&lt;br /&gt;
&lt;br /&gt;
[[Media:IoT_TCP_DHT11_Programs.zip|TCP Server and ESP32 Client Programs ZIP]]&lt;br /&gt;
&lt;br /&gt;
== Program 2: ESP32 TCP Client ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 connects to the Wi-Fi network, reads the DHT11 sensor values, and sends the readings to the remote computer using TCP.&lt;br /&gt;
&lt;br /&gt;
Download the program:&lt;br /&gt;
&lt;br /&gt;
[[Media:IoT_TCP_DHT11_Programs.zip|ESP32 TCP Client Program]]&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Configure the Remote Computer ===&lt;br /&gt;
&lt;br /&gt;
# Connect the remote computer to the Wi-Fi network.&lt;br /&gt;
# Find the local IP address of the remote computer using the appropriate network command.&lt;br /&gt;
# Replace the example IP address in the ESP32 client program with the remote computer&#039;s actual IP address.&lt;br /&gt;
# Save the TCP server program as tcp_server.py.&lt;br /&gt;
# Run the server using Python:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python tcp_server.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# Ensure that the firewall allows incoming TCP connections on port 5000.&lt;br /&gt;
# Keep the TCP server running while testing the ESP32.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Configure ESP32 ===&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 using the specified pin connections.&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Install the DHT sensor library if it is not already installed.&lt;br /&gt;
# Enter the Wi-Fi SSID and password in the ESP32 program.&lt;br /&gt;
# Enter the remote computer&#039;s IP address in the ESP32 program.&lt;br /&gt;
# Enter the TCP server port number in the ESP32 program.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Observe the Wi-Fi connection status.&lt;br /&gt;
# Observe the TCP connection status.&lt;br /&gt;
# Observe the temperature and humidity values being transmitted.&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Verify TCP/IP Communication ===&lt;br /&gt;
&lt;br /&gt;
# Check that the remote computer reports an incoming TCP connection.&lt;br /&gt;
# Observe the temperature and humidity data received by the TCP server.&lt;br /&gt;
# Compare the transmitted values with the sensor readings displayed by the ESP32.&lt;br /&gt;
# Verify that multiple sensor readings are received by the server.&lt;br /&gt;
# Stop the ESP32 program or disconnect the device.&lt;br /&gt;
# Observe the disconnection message on the TCP server.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Temperature (C)&lt;br /&gt;
! Relative Humidity (percent)&lt;br /&gt;
! Transmission Status&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Record measured value&lt;br /&gt;
| Successful / Failed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Expected output on the remote computer:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
TCP Server started&lt;br /&gt;
Waiting for ESP32 connection...&lt;br /&gt;
Connected by: (&#039;192.168.1.105&#039;, 54321)&lt;br /&gt;
Received: Temperature: 28.0 C, Humidity: 65.0 %&lt;br /&gt;
Received: Temperature: 28.0 C, Humidity: 64.0 %&lt;br /&gt;
Received: Temperature: 29.0 C, Humidity: 64.0 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above values and IP addresses are illustrative examples, not actual measurements.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An IoT application was implemented using an ESP32 and DHT11 sensor. The ESP32 successfully connected to a Wi-Fi network and transmitted temperature and humidity readings to a remote computer using TCP/IP socket communication.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is the role of Wi-Fi in an IoT application?&lt;br /&gt;
# What is TCP?&lt;br /&gt;
# What is the difference between TCP and UDP?&lt;br /&gt;
# What is an IP address?&lt;br /&gt;
# What is a TCP socket?&lt;br /&gt;
# What is the difference between a TCP client and a TCP server?&lt;br /&gt;
# Why is TCP considered a reliable communication protocol?&lt;br /&gt;
# What is the function of the bind() function in Python socket programming?&lt;br /&gt;
# What is the purpose of the listen() function?&lt;br /&gt;
# What is the purpose of the accept() function?&lt;br /&gt;
# What is the function of sendall() in Python?&lt;br /&gt;
# Why should the remote computer&#039;s IP address be configured in the ESP32?&lt;br /&gt;
# What is the difference between a local IP address and a public IP address?&lt;br /&gt;
# Why is port 5000 used in this experiment?&lt;br /&gt;
# How can the application be extended to store sensor readings in a database or cloud platform?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_4&amp;diff=1363</id>
		<title>MDM331AID/Experiment 4</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_4&amp;diff=1363"/>
		<updated>2026-10-07T16:00:19Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Arduino Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Gas Leakage Detection Using Arduino UNO =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To develop a gas leakage detection application using an Arduino UNO and an MQ-2 gas sensor to monitor the surrounding environment and generate an alert when the sensor reading exceeds a predefined threshold.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the working principle of the MQ-2 gas sensor.&lt;br /&gt;
* To interface a gas sensor with the Arduino UNO.&lt;br /&gt;
* To read analog sensor values using the ADC of the Arduino.&lt;br /&gt;
* To implement threshold-based gas detection.&lt;br /&gt;
* To activate an alert using an LED and buzzer when the sensor reading exceeds the set threshold.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Arduino UNO Development Board (COG-U1)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| MQ-2 Gas Sensor (COG-MSBA)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| LED bar&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Buzzer&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| USB data cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Gas Leakage Detection ===&lt;br /&gt;
&lt;br /&gt;
Gas leakage detection is an important application in homes, industries, laboratories, and other environments where combustible gases may be present. A gas sensor detects changes in the surrounding gas concentration and generates an electrical signal that can be processed by a microcontroller.&lt;br /&gt;
&lt;br /&gt;
=== MQ-2 Gas Sensor ===&lt;br /&gt;
&lt;br /&gt;
The MQ-2 is a semiconductor gas sensor commonly used for detecting combustible gases and smoke. It is sensitive to gases such as LPG, propane, methane, hydrogen, and smoke.&lt;br /&gt;
&lt;br /&gt;
The sensor contains a sensing element whose electrical resistance changes in the presence of certain gases. The sensor module converts this change into an electrical output.&lt;br /&gt;
&lt;br /&gt;
Common MQ-2 module interfaces include:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;VCC:&#039;&#039;&#039; Power supply input.&lt;br /&gt;
* &#039;&#039;&#039;GND:&#039;&#039;&#039; Ground connection.&lt;br /&gt;
* &#039;&#039;&#039;AO:&#039;&#039;&#039; Analog output voltage related to the sensor response.&lt;br /&gt;
* &#039;&#039;&#039;DO:&#039;&#039;&#039; Digital output from an onboard comparator, often with an adjustable threshold.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the analog output is used to read sensor values through the Arduino UNO&#039;s analog input.&lt;br /&gt;
&lt;br /&gt;
=== Analog-to-Digital Conversion ===&lt;br /&gt;
&lt;br /&gt;
The Arduino UNO has a 10-bit analog-to-digital converter (ADC). The analogRead() function converts the analog input voltage into a digital value ranging from 0 to 1023 when using the default reference.&lt;br /&gt;
&lt;br /&gt;
=== Threshold-Based Detection ===&lt;br /&gt;
&lt;br /&gt;
The Arduino continuously reads the analog output of the MQ-2 sensor. The measured value is compared with a predefined threshold.&lt;br /&gt;
&lt;br /&gt;
* If the sensor reading is below the threshold, the system indicates normal operation.&lt;br /&gt;
* If the sensor reading is equal to or above the threshold, the system activates the alert LED and buzzer.&lt;br /&gt;
&lt;br /&gt;
The threshold used in this experiment is a demonstration value and must be adjusted based on actual sensor readings. It does not represent a calibrated gas concentration.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Arduino UNO Pin&lt;br /&gt;
! MQ-2 / Output Connection&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 5V&lt;br /&gt;
| MQ-2 VCC&lt;br /&gt;
| Sensor power supply&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| MQ-2 GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|-&lt;br /&gt;
| A0&lt;br /&gt;
| MQ-2 AO&lt;br /&gt;
| Analog sensor output&lt;br /&gt;
|-&lt;br /&gt;
| D8&lt;br /&gt;
| LED bar input&lt;br /&gt;
| Visual alert output&lt;br /&gt;
|-&lt;br /&gt;
| D9&lt;br /&gt;
| Buzzer input&lt;br /&gt;
| Audible alert output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These connections assume that the MQ-2 board exposes an analog output compatible with the Arduino UNO and that the LED bar and buzzer accept active-HIGH digital control. Verify the actual pin labels and interface of your Cognifront sensor and output boards before connecting.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
          MQ-2 Gas Sensor&lt;br /&gt;
         +---------------+&lt;br /&gt;
         |               |&lt;br /&gt;
         | VCC  ---------+---- 5V&lt;br /&gt;
         | GND  ---------+---- GND&lt;br /&gt;
         | AO   ---------+---- A0&lt;br /&gt;
         +---------------+&lt;br /&gt;
&lt;br /&gt;
             Arduino UNO&lt;br /&gt;
         +------------------+&lt;br /&gt;
         |                  |&lt;br /&gt;
         | A0  &amp;lt;--- MQ-2 AO |&lt;br /&gt;
         |                  |&lt;br /&gt;
         | D8  ------------+---- LED Bar Input&lt;br /&gt;
         |                  |&lt;br /&gt;
         | D9  ------------+---- Buzzer Input&lt;br /&gt;
         |                  |&lt;br /&gt;
         | GND ------------+---- Common GND&lt;br /&gt;
         +------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Arduino Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int gasPin = A0;&lt;br /&gt;
const int ledPin = 8;&lt;br /&gt;
const int buzzerPin = 9;&lt;br /&gt;
&lt;br /&gt;
// Demonstration threshold; calibrate for your setup&lt;br /&gt;
const int gasThreshold = 400;&lt;br /&gt;
&lt;br /&gt;
int gasValue = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
&lt;br /&gt;
  pinMode(ledPin, OUTPUT);&lt;br /&gt;
  pinMode(buzzerPin, OUTPUT);&lt;br /&gt;
&lt;br /&gt;
  digitalWrite(ledPin, LOW);&lt;br /&gt;
  digitalWrite(buzzerPin, LOW);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;MQ-2 Gas Detection System&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  gasValue = analogRead(gasPin);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Gas Sensor Value: &amp;quot;);&lt;br /&gt;
  Serial.println(gasValue);&lt;br /&gt;
&lt;br /&gt;
  if (gasValue &amp;gt;= gasThreshold) {&lt;br /&gt;
    digitalWrite(ledPin, HIGH);&lt;br /&gt;
    digitalWrite(buzzerPin, HIGH);&lt;br /&gt;
    Serial.println(&amp;quot;WARNING: Gas level threshold exceeded!&amp;quot;);&lt;br /&gt;
  } else {&lt;br /&gt;
    digitalWrite(ledPin, LOW);&lt;br /&gt;
    digitalWrite(buzzerPin, LOW);&lt;br /&gt;
    Serial.println(&amp;quot;Status: Normal&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Statement&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| const int gasPin = A0;&lt;br /&gt;
| Defines analog pin A0 as the gas sensor input.&lt;br /&gt;
|-&lt;br /&gt;
| const int ledPin = 8;&lt;br /&gt;
| Defines digital pin D8 as the LED control output.&lt;br /&gt;
|-&lt;br /&gt;
| const int buzzerPin = 9;&lt;br /&gt;
| Defines digital pin D9 as the buzzer control output.&lt;br /&gt;
|-&lt;br /&gt;
| const int gasThreshold = 400;&lt;br /&gt;
| Sets a demonstration threshold for gas detection.&lt;br /&gt;
|-&lt;br /&gt;
| analogRead(gasPin)&lt;br /&gt;
| Reads the analog output of the gas sensor and returns a value from 0 to 1023.&lt;br /&gt;
|-&lt;br /&gt;
| Serial.println(gasValue)&lt;br /&gt;
| Displays the sensor reading on the Serial Monitor.&lt;br /&gt;
|-&lt;br /&gt;
| if (gasValue &amp;gt;= gasThreshold)&lt;br /&gt;
| Checks whether the sensor reading has reached or exceeded the threshold.&lt;br /&gt;
|-&lt;br /&gt;
| digitalWrite(ledPin, HIGH)&lt;br /&gt;
| Activates the LED alert output.&lt;br /&gt;
|-&lt;br /&gt;
| digitalWrite(buzzerPin, HIGH)&lt;br /&gt;
| Activates the buzzer alert output.&lt;br /&gt;
|-&lt;br /&gt;
| delay(1000)&lt;br /&gt;
| Pauses the program for one second before the next reading.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the MQ-2 sensor&#039;s VCC and GND pins to the Arduino UNO&#039;s 5V and GND, respectively.&lt;br /&gt;
# Connect the sensor&#039;s analog output (AO) to the Arduino analog input A0.&lt;br /&gt;
# Connect the LED bar input to D8 and the buzzer input to D9, ensuring that the output interfaces are compatible.&lt;br /&gt;
# Connect the Arduino UNO to the computer using the USB data cable.&lt;br /&gt;
# Open the Arduino IDE and select the Arduino UNO board and appropriate COM port.&lt;br /&gt;
# Enter the program and upload it to the Arduino UNO.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 9600.&lt;br /&gt;
# Allow the MQ-2 sensor to warm up and stabilize according to its datasheet and module instructions.&lt;br /&gt;
# Observe the sensor readings under the available ambient conditions.&lt;br /&gt;
# Adjust the demonstration threshold based on observed readings, if required.&lt;br /&gt;
# Observe the LED and buzzer response when the reading crosses the configured threshold.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Safety precaution:&#039;&#039;&#039; Do not intentionally release LPG, lighter gas, smoke, or other combustible gases to test the circuit. This is an educational demonstration, not a certified gas alarm or safety system. Conduct any controlled sensor testing only with appropriate laboratory safety procedures.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Sensor Reading&lt;br /&gt;
! Condition&lt;br /&gt;
! LED&lt;br /&gt;
! Buzzer&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Below threshold&lt;br /&gt;
| Normal&lt;br /&gt;
| OFF&lt;br /&gt;
| OFF&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Equal to or above threshold&lt;br /&gt;
| Threshold exceeded&lt;br /&gt;
| ON&lt;br /&gt;
| ON&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The readings and alert response should be recorded during the experiment. The table describes expected behavior, not measured results.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
An Arduino UNO-based gas detection demonstration was developed using an MQ-2 sensor. The sensor&#039;s analog output was read and compared against a predefined threshold. An LED and buzzer were programmed to provide alerts when the reading exceeded the threshold.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is the purpose of a gas sensor?&lt;br /&gt;
# What is the working principle of the MQ-2 sensor?&lt;br /&gt;
# Which gases can the MQ-2 sensor detect?&lt;br /&gt;
# What is the difference between the analog and digital outputs of an MQ-2 module?&lt;br /&gt;
# What is the resolution of the Arduino UNO ADC?&lt;br /&gt;
# What is the purpose of the analogRead() function?&lt;br /&gt;
# Why is a threshold used in gas detection?&lt;br /&gt;
# Why does an MQ-2 sensor require a warm-up period?&lt;br /&gt;
# Can an MQ-2 sensor directly measure gas concentration in parts per million without calibration?&lt;br /&gt;
# What are the limitations of a threshold-based gas detection system?&lt;br /&gt;
# How can this project be extended to send gas alerts through an IoT cloud platform?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_3&amp;diff=1362</id>
		<title>MDM331AID/Experiment 3</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_3&amp;diff=1362"/>
		<updated>2026-10-07T15:57:43Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Arduino Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment 3: Arduino-Based LED Control Using GPIO Pins =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To implement a simple IoT-oriented application using an Arduino UNO board to control an LED through GPIO pins and understand the physical design of IoT devices and the concept of device actuation.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the physical components of an IoT device.&lt;br /&gt;
* To configure Arduino GPIO pins as digital outputs.&lt;br /&gt;
* To control an LED using digital signals.&lt;br /&gt;
* To understand the role of actuators in IoT applications.&lt;br /&gt;
* To observe the relationship between software commands and physical device actions.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Arduino UNO Development Board (COG-U1)&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| LED bar available on the Arduino kit&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB data cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Physical Design of an IoT Device ===&lt;br /&gt;
&lt;br /&gt;
An IoT device consists of physical hardware and software that work together to sense, process, communicate, and perform actions. A typical IoT device includes the following components:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Processing unit:&#039;&#039;&#039; A microcontroller or processor that executes the program and controls device operations.&lt;br /&gt;
* &#039;&#039;&#039;Input interface:&#039;&#039;&#039; GPIO pins and sensor interfaces used to receive data from external components.&lt;br /&gt;
* &#039;&#039;&#039;Output interface:&#039;&#039;&#039; GPIO pins used to control actuators such as LEDs, buzzers, relays, and motors.&lt;br /&gt;
* &#039;&#039;&#039;Communication interface:&#039;&#039;&#039; Wi-Fi, Bluetooth, Ethernet, or other communication technologies used to exchange data.&lt;br /&gt;
* &#039;&#039;&#039;Power supply:&#039;&#039;&#039; Provides the electrical energy required for device operation.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the Arduino UNO acts as the processing unit, and the LED acts as a simple output actuator.&lt;br /&gt;
&lt;br /&gt;
=== GPIO Pins ===&lt;br /&gt;
&lt;br /&gt;
GPIO stands for General Purpose Input/Output. These pins allow a microcontroller to interact with external electronic components.&lt;br /&gt;
&lt;br /&gt;
Arduino UNO digital pins can be configured as:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;INPUT:&#039;&#039;&#039; To read digital signals.&lt;br /&gt;
* &#039;&#039;&#039;OUTPUT:&#039;&#039;&#039; To generate digital signals.&lt;br /&gt;
* &#039;&#039;&#039;INPUT_PULLUP:&#039;&#039;&#039; To read digital signals using an internal pull-up resistor.&lt;br /&gt;
&lt;br /&gt;
For LED control, the GPIO pin is configured as an output.&lt;br /&gt;
&lt;br /&gt;
=== Device Actuation ===&lt;br /&gt;
&lt;br /&gt;
Actuation is the process of converting a control signal into a physical action. In this experiment, the Arduino generates a digital HIGH or LOW signal on a GPIO pin to switch the LED on or off.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;HIGH:&#039;&#039;&#039; The output pin is set to a logic HIGH voltage, approximately 5 V on an Arduino UNO.&lt;br /&gt;
* &#039;&#039;&#039;LOW:&#039;&#039;&#039; The output pin is set to a logic LOW voltage, approximately 0 V.&lt;br /&gt;
&lt;br /&gt;
This demonstrates a basic form of device actuation. In a complete IoT system, commands could be received over a network and used to control the same GPIO output.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Arduino UNO Pin&lt;br /&gt;
! LED Bar Connection&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| D8&lt;br /&gt;
| LED bar input&lt;br /&gt;
| Digital output for LED control&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| LED bar GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The connection above assumes that the LED bar has a compatible input connection for direct GPIO control. Verify the LED bar&#039;s actual pin labels and current-limiting arrangement before connecting it. If the kit&#039;s LED bar uses a different interface, follow its board-specific connection details.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        Arduino UNO&lt;br /&gt;
      +-------------+&lt;br /&gt;
      |             |&lt;br /&gt;
      |         D8  |---------------- LED Bar Input&lt;br /&gt;
      |             |&lt;br /&gt;
      |        GND  |---------------- LED Bar GND&lt;br /&gt;
      |             |&lt;br /&gt;
      +-------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Arduino Program ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const int ledPin = 8;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  pinMode(ledPin, OUTPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  // Turn LED ON&lt;br /&gt;
  digitalWrite(ledPin, HIGH);&lt;br /&gt;
  delay(1000);&lt;br /&gt;
&lt;br /&gt;
  // Turn LED OFF&lt;br /&gt;
  digitalWrite(ledPin, LOW);&lt;br /&gt;
  delay(1000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Statement&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| const int ledPin = 8;&lt;br /&gt;
| Defines digital pin 8 as the LED control pin.&lt;br /&gt;
|-&lt;br /&gt;
| pinMode(ledPin, OUTPUT);&lt;br /&gt;
| Configures the selected GPIO pin as an output.&lt;br /&gt;
|-&lt;br /&gt;
| digitalWrite(ledPin, HIGH);&lt;br /&gt;
| Sets the GPIO output to HIGH to turn the LED on, assuming active-HIGH wiring.&lt;br /&gt;
|-&lt;br /&gt;
| delay(1000);&lt;br /&gt;
| Pauses program execution for 1000 milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
| digitalWrite(ledPin, LOW);&lt;br /&gt;
| Sets the GPIO output to LOW to turn the LED off, assuming active-HIGH wiring.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the Arduino UNO board to the computer using the USB data cable.&lt;br /&gt;
# Connect the LED bar input to digital pin D8 and its ground to Arduino GND, after verifying the LED bar&#039;s pinout and compatibility.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Select the appropriate Arduino UNO board and COM port.&lt;br /&gt;
# Enter the given Arduino program.&lt;br /&gt;
# Compile and upload the program to the Arduino UNO.&lt;br /&gt;
# Observe the LED switching on and off at one-second intervals.&lt;br /&gt;
# Modify the delay values and observe how the blinking speed changes.&lt;br /&gt;
&lt;br /&gt;
== Observations ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! GPIO Output&lt;br /&gt;
! Expected LED State&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| HIGH&lt;br /&gt;
| ON&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| LOW&lt;br /&gt;
| OFF&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| HIGH&lt;br /&gt;
| ON&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| LOW&lt;br /&gt;
| OFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The expected output is a repeating sequence of one second ON followed by one second OFF. Actual behavior depends on the LED bar&#039;s electrical interface and polarity.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The Arduino UNO was programmed to control an LED through a GPIO pin. The experiment demonstrates GPIO output configuration and basic device actuation, illustrating how software commands can produce physical actions in an IoT device.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is the full form of GPIO?&lt;br /&gt;
# What is the function of a microcontroller in an IoT device?&lt;br /&gt;
# What is the difference between digital input and digital output?&lt;br /&gt;
# What is device actuation?&lt;br /&gt;
# What is the purpose of the pinMode() function?&lt;br /&gt;
# What is the function of digitalWrite()?&lt;br /&gt;
# What is the difference between HIGH and LOW logic levels?&lt;br /&gt;
# Why is a current-limiting resistor required for a conventional LED?&lt;br /&gt;
# What is the role of a communication interface in an IoT device?&lt;br /&gt;
# How could this experiment be extended to control an LED remotely over Wi-Fi?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1361</id>
		<title>MDM331AID/Experiment 14</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_14&amp;diff=1361"/>
		<updated>2026-10-07T13:29:38Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Smart Threshold Alerts for Data Minimization using Privacy-by-Design =  == Aim ==  To design and implement a Privacy-by-Design IoT system using an LDR sensor and ESP32 that generates an alert only when a predefined threshold is crossed, thereby minimizing unnecessary sensor data transmission.  == Objectives ==  # To understand Privacy-by-Design in an IoT system. # To understand the concept of data minimization. # To interface an LDR sensor with ESP32. # To...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Smart Threshold Alerts for Data Minimization using Privacy-by-Design =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To design and implement a Privacy-by-Design IoT system using an LDR sensor and ESP32 that generates an alert only when a predefined threshold is crossed, thereby minimizing unnecessary sensor data transmission.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
# To understand Privacy-by-Design in an IoT system.&lt;br /&gt;
# To understand the concept of data minimization.&lt;br /&gt;
# To interface an LDR sensor with ESP32.&lt;br /&gt;
# To detect changes in light intensity.&lt;br /&gt;
# To define a threshold for detecting darkness.&lt;br /&gt;
# To generate a POWER CUT alert when darkness is detected.&lt;br /&gt;
# To process raw sensor data locally on the ESP32.&lt;br /&gt;
# To avoid continuously transmitting raw LDR readings.&lt;br /&gt;
# To transmit or expose only the required alert information.&lt;br /&gt;
# To demonstrate data minimization through data inspection.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| Reads the LDR and hosts the web server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| LDR&lt;br /&gt;
| 1&lt;br /&gt;
| Detects light intensity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 10 kOhm Resistor&lt;br /&gt;
| 1&lt;br /&gt;
| Forms the LDR voltage divider&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Breadboard&lt;br /&gt;
| 1&lt;br /&gt;
| Circuit connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| Accesses the ESP32 web page&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and powering ESP32&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| Programming the ESP32&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Internet of Things ===&lt;br /&gt;
&lt;br /&gt;
The Internet of Things, or IoT, is a system in which physical devices use sensors and communication technologies to collect and exchange information.&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, sensor readings may be continuously transmitted even when the application does not require all of the readings.&lt;br /&gt;
&lt;br /&gt;
For example, an LDR monitoring system may continuously generate values such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
3860&lt;br /&gt;
3715&lt;br /&gt;
3521&lt;br /&gt;
3480&lt;br /&gt;
3405&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the purpose of the application is only to detect a power cut, the application does not need every individual LDR reading.&lt;br /&gt;
&lt;br /&gt;
The ESP32 can instead process the sensor data locally and generate an alert only when the required condition occurs.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design ===&lt;br /&gt;
&lt;br /&gt;
Privacy-by-Design means that privacy is considered while designing the system rather than being added later.&lt;br /&gt;
&lt;br /&gt;
One important part of Privacy-by-Design is data minimization.&lt;br /&gt;
&lt;br /&gt;
Data minimization means collecting, processing, transmitting, and storing only the information that is necessary for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the purpose is to detect a possible power cut.&lt;br /&gt;
&lt;br /&gt;
Therefore, the system does not need to continuously expose the exact LDR readings.&lt;br /&gt;
&lt;br /&gt;
The ESP32 processes the readings locally and only generates the required alert when the threshold is crossed.&lt;br /&gt;
&lt;br /&gt;
=== Smart Threshold Alert ===&lt;br /&gt;
&lt;br /&gt;
A threshold is a predefined value used to identify a particular condition.&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the LDR value and compares it with the selected threshold.&lt;br /&gt;
&lt;br /&gt;
The operation is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR reading&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
ESP32&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Check threshold&lt;br /&gt;
    |&lt;br /&gt;
    +-------------------+&lt;br /&gt;
    |                   |&lt;br /&gt;
    v                   v&lt;br /&gt;
Normal condition    Dark condition&lt;br /&gt;
    |                   |&lt;br /&gt;
    v                   v&lt;br /&gt;
No alert            POWER CUT&lt;br /&gt;
                    alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The threshold value depends on the LDR circuit and surrounding lighting conditions.&lt;br /&gt;
&lt;br /&gt;
Therefore, the threshold should be calibrated before performing the experiment.&lt;br /&gt;
&lt;br /&gt;
=== Data Minimization ===&lt;br /&gt;
&lt;br /&gt;
In a conventional system, raw LDR readings may be continuously sent to another device or server.&lt;br /&gt;
&lt;br /&gt;
In the proposed system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR reading&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Local processing on ESP32&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Threshold check&lt;br /&gt;
    |&lt;br /&gt;
    +------------------+&lt;br /&gt;
    |                  |&lt;br /&gt;
    v                  v&lt;br /&gt;
Normal             Dark&lt;br /&gt;
    |                  |&lt;br /&gt;
    v                  v&lt;br /&gt;
No alert           POWER CUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The raw LDR value is used locally for decision making.&lt;br /&gt;
&lt;br /&gt;
Unnecessary raw readings are therefore not continuously exposed outside the device.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! LDR Circuit&lt;br /&gt;
! ESP32&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| LDR voltage divider output&lt;br /&gt;
| GPIO 34&lt;br /&gt;
| Analog input&lt;br /&gt;
|-&lt;br /&gt;
| Supply&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Circuit supply&lt;br /&gt;
|-&lt;br /&gt;
| Ground&lt;br /&gt;
| GND&lt;br /&gt;
| Common ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A typical voltage divider is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        3.3V&lt;br /&gt;
          |&lt;br /&gt;
         LDR&lt;br /&gt;
          |&lt;br /&gt;
          +-------- GPIO 34&lt;br /&gt;
          |&lt;br /&gt;
        10 kOhm&lt;br /&gt;
          |&lt;br /&gt;
         GND&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The voltage at GPIO 34 changes according to the amount of light falling on the LDR.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; Depending on the circuit arrangement, the LDR reading may increase or decrease when the sensor is covered. The actual behavior should be checked during calibration.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                 ESP32&lt;br /&gt;
             +------------+&lt;br /&gt;
             |            |&lt;br /&gt;
      3.3V --|            |&lt;br /&gt;
             |            |&lt;br /&gt;
             | GPIO 34 &amp;lt;--|------ LDR Circuit&lt;br /&gt;
             |            |&lt;br /&gt;
       GND --|            |&lt;br /&gt;
             |            |&lt;br /&gt;
             +------------+&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Wi-Fi Access Point&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
             Smartphone Browser&lt;br /&gt;
                    |&lt;br /&gt;
                    |&lt;br /&gt;
              192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Working Principle ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 works as a Wi-Fi Access Point and hosts a web server.&lt;br /&gt;
&lt;br /&gt;
The smartphone connects directly to the Wi-Fi network created by the ESP32.&lt;br /&gt;
&lt;br /&gt;
The student then opens:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the LDR value.&lt;br /&gt;
&lt;br /&gt;
The value is compared with the threshold.&lt;br /&gt;
&lt;br /&gt;
When sufficient light is present, the system remains in the normal condition.&lt;br /&gt;
&lt;br /&gt;
When the LDR is covered and the reading crosses the threshold, the ESP32 considers the condition to represent a power cut.&lt;br /&gt;
&lt;br /&gt;
The smartphone then displays the POWER CUT alert.&lt;br /&gt;
&lt;br /&gt;
The raw LDR value is processed locally.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
The following program avoids embedding HTML source directly into the MediaWiki page.&lt;br /&gt;
&lt;br /&gt;
The web page is constructed using character values so that the program does not contain HTML tags as literal text.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WiFi.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WebServer.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
const int LDR_PIN = 34;&lt;br /&gt;
&lt;br /&gt;
const char* ap_ssid = &amp;quot;ESP32-Power-Monitor&amp;quot;;&lt;br /&gt;
const char* ap_password = &amp;quot;12345678&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
const int LDR_THRESHOLD = 2000;&lt;br /&gt;
&lt;br /&gt;
bool powerCut = false;&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
  int ldrValue = analogRead(LDR_PIN);&lt;br /&gt;
&lt;br /&gt;
  if (ldrValue &amp;amp;lt; LDR_THRESHOLD)&lt;br /&gt;
  {&lt;br /&gt;
    powerCut = true;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    powerCut = false;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  String page = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  char lt = 60;&lt;br /&gt;
  char gt = 62;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;html&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;head&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1&#039;&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;title&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
  page += &amp;quot;Smart Power Monitor&amp;quot;;&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/title&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/head&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;body&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;h1&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
  page += &amp;quot;Smart Power Monitor&amp;quot;;&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/h1&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  if (powerCut)&lt;br /&gt;
  {&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;POWER CUT&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;Dark condition detected.&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;NORMAL&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/h2&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
    page += &amp;quot;No power cut detected.&amp;quot;;&lt;br /&gt;
    page += lt;&lt;br /&gt;
    page += &amp;quot;/p&amp;quot;;&lt;br /&gt;
    page += gt;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/body&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  page += lt;&lt;br /&gt;
  page += &amp;quot;/html&amp;quot;;&lt;br /&gt;
  page += gt;&lt;br /&gt;
&lt;br /&gt;
  server.send(200, &amp;quot;text/html&amp;quot;, page);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  pinMode(LDR_PIN, INPUT);&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAPConfig(&lt;br /&gt;
    IPAddress(192,168,1,4),&lt;br /&gt;
    IPAddress(192,168,1,1),&lt;br /&gt;
    IPAddress(255,255,255,0)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  WiFi.softAP(ap_ssid, ap_password);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;ESP32 Access Point started&amp;quot;);&lt;br /&gt;
  Serial.print(&amp;quot;IP Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.softAPIP());&lt;br /&gt;
&lt;br /&gt;
  server.on(&amp;quot;/&amp;quot;, handleRoot);&lt;br /&gt;
&lt;br /&gt;
  server.begin();&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Web server started&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code or Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.h&lt;br /&gt;
| Provides ESP32 Wi-Fi functionality.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer.h&lt;br /&gt;
| Provides the web server functionality.&lt;br /&gt;
|-&lt;br /&gt;
| LDR_PIN&lt;br /&gt;
| Defines GPIO 34 as the LDR analog input.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAP&lt;br /&gt;
| Creates a Wi-Fi Access Point using the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| WiFi.softAPConfig&lt;br /&gt;
| Sets the Access Point IP address to 192.168.1.4.&lt;br /&gt;
|-&lt;br /&gt;
| WebServer server(80)&lt;br /&gt;
| Creates an HTTP web server on port 80.&lt;br /&gt;
|-&lt;br /&gt;
| LDR_THRESHOLD&lt;br /&gt;
| Defines the value used to detect the dark condition.&lt;br /&gt;
|-&lt;br /&gt;
| analogRead&lt;br /&gt;
| Reads the analog value from the LDR circuit.&lt;br /&gt;
|-&lt;br /&gt;
| powerCut&lt;br /&gt;
| Stores whether a dark condition has been detected.&lt;br /&gt;
|-&lt;br /&gt;
| handleRoot&lt;br /&gt;
| Generates the web page displayed on the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| server.send&lt;br /&gt;
| Sends the web page to the browser.&lt;br /&gt;
|-&lt;br /&gt;
| server.handleClient&lt;br /&gt;
| Processes browser requests.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Access Point ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 creates its own Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
The network name is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Power-Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The IP address is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The smartphone can therefore access the web page using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Threshold Detection ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the LDR using:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
int ldrValue = analogRead(LDR_PIN);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value is compared with the threshold:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if (ldrValue &amp;lt; LDR_THRESHOLD)&lt;br /&gt;
{&lt;br /&gt;
  powerCut = true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the condition is satisfied, the ESP32 generates the POWER CUT alert.&lt;br /&gt;
&lt;br /&gt;
== Calibration of LDR Threshold ==&lt;br /&gt;
&lt;br /&gt;
The threshold should be calibrated before the experiment.&lt;br /&gt;
&lt;br /&gt;
# Upload the program to the ESP32.&lt;br /&gt;
# Open the Arduino IDE Serial Monitor.&lt;br /&gt;
# Observe the LDR readings under normal light.&lt;br /&gt;
# Cover the LDR with a finger.&lt;br /&gt;
# Observe the LDR readings again.&lt;br /&gt;
# Compare the readings for bright and dark conditions.&lt;br /&gt;
# Select a suitable threshold between the two conditions.&lt;br /&gt;
# Change the LDR_THRESHOLD value in the program.&lt;br /&gt;
# Upload the program again.&lt;br /&gt;
# Test the system.&lt;br /&gt;
&lt;br /&gt;
For example, the readings may be:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normal light:&lt;br /&gt;
3000 to 3800&lt;br /&gt;
&lt;br /&gt;
LDR covered:&lt;br /&gt;
500 to 1200&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In such a case, a threshold somewhere between these ranges can be selected.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The above values are examples only. Actual values depend on the LDR circuit and lighting conditions.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the LDR and resistor as a voltage divider.&lt;br /&gt;
# Connect the output of the voltage divider to GPIO 34.&lt;br /&gt;
# Connect the circuit to 3.3V and GND.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Open Arduino IDE.&lt;br /&gt;
# Select the appropriate ESP32 board.&lt;br /&gt;
# Select the appropriate COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor.&lt;br /&gt;
# Verify that the ESP32 Access Point has started.&lt;br /&gt;
# Connect the smartphone to ESP32-Power-Monitor.&lt;br /&gt;
# Open the smartphone browser.&lt;br /&gt;
# Enter http://192.168.1.4.&lt;br /&gt;
# Observe the NORMAL status.&lt;br /&gt;
# Keep the LDR exposed to light.&lt;br /&gt;
# Cover the LDR using a finger.&lt;br /&gt;
# Observe the POWER CUT alert.&lt;br /&gt;
# Remove the finger.&lt;br /&gt;
# Verify that the normal condition is restored.&lt;br /&gt;
# Perform the data inspection demonstration.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Normal Condition ===&lt;br /&gt;
&lt;br /&gt;
When the LDR is exposed to sufficient light:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR Condition : Bright&lt;br /&gt;
System Status : NORMAL&lt;br /&gt;
Alert         : None&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
No power-cut alert is generated.&lt;br /&gt;
&lt;br /&gt;
=== Dark Condition ===&lt;br /&gt;
&lt;br /&gt;
When the LDR is covered with a finger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR Condition : Dark&lt;br /&gt;
System Status : ALERT&lt;br /&gt;
Alert         : POWER CUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ESP32 detects the threshold crossing and generates the alert.&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Output ===&lt;br /&gt;
&lt;br /&gt;
Normal condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART POWER MONITOR&lt;br /&gt;
&lt;br /&gt;
NORMAL&lt;br /&gt;
&lt;br /&gt;
No power cut detected.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dark condition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SMART POWER MONITOR&lt;br /&gt;
&lt;br /&gt;
POWER CUT&lt;br /&gt;
&lt;br /&gt;
Dark condition detected.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Demonstration of Data Minimization ==&lt;br /&gt;
&lt;br /&gt;
The main purpose of this experiment is to demonstrate that unnecessary raw sensor data does not need to be transmitted.&lt;br /&gt;
&lt;br /&gt;
=== Conventional System ===&lt;br /&gt;
&lt;br /&gt;
In a conventional IoT system, the server may receive raw LDR readings continuously.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR value: 3860&lt;br /&gt;
&lt;br /&gt;
LDR value: 3715&lt;br /&gt;
&lt;br /&gt;
LDR value: 3521&lt;br /&gt;
&lt;br /&gt;
LDR value: 3480&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The server therefore receives detailed sensor information.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design System ===&lt;br /&gt;
&lt;br /&gt;
In the proposed system, the ESP32 processes the LDR reading locally.&lt;br /&gt;
&lt;br /&gt;
During normal conditions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR reading&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Local threshold check&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Normal condition&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
No alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the threshold is crossed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR reading&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Local threshold check&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
Dark condition&lt;br /&gt;
    |&lt;br /&gt;
    v&lt;br /&gt;
POWER CUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application only needs to expose the required event.&lt;br /&gt;
&lt;br /&gt;
The raw LDR measurement does not need to be exposed.&lt;br /&gt;
&lt;br /&gt;
== Data Inspection Demonstration ==&lt;br /&gt;
&lt;br /&gt;
The data inspection demonstration is used to compare the amount of information exposed by two system designs.&lt;br /&gt;
&lt;br /&gt;
The demonstration is educational and is intended to show the effect of data minimization.&lt;br /&gt;
&lt;br /&gt;
=== Conventional Design ===&lt;br /&gt;
&lt;br /&gt;
A conventional system may expose information such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
LDR value: 3860&lt;br /&gt;
LDR value: 3715&lt;br /&gt;
LDR value: 3521&lt;br /&gt;
LDR value: 1200&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An observer can therefore obtain detailed information about the sensor readings.&lt;br /&gt;
&lt;br /&gt;
=== Privacy-by-Design Design ===&lt;br /&gt;
&lt;br /&gt;
The Privacy-by-Design system processes the raw value locally.&lt;br /&gt;
&lt;br /&gt;
When there is no threshold event:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
No alert&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When darkness is detected:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
POWER CUT&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The application therefore exposes only the information needed for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
The raw LDR values are not required by the application.&lt;br /&gt;
&lt;br /&gt;
=== Demonstration Steps ===&lt;br /&gt;
&lt;br /&gt;
# Connect the smartphone to the ESP32 Access Point.&lt;br /&gt;
# Open the ESP32 web page.&lt;br /&gt;
# Observe the normal condition.&lt;br /&gt;
# Cover the LDR with a finger.&lt;br /&gt;
# Observe the POWER CUT alert.&lt;br /&gt;
# Inspect the application data using an appropriate network inspection or server logging method.&lt;br /&gt;
# Observe that the useful application information is the alert rather than a continuous stream of raw LDR values.&lt;br /&gt;
# Explain that the raw reading was processed locally before the alert was generated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; This demonstration is about data minimization. It does not claim that HTTP communication is encrypted or completely secure.&lt;br /&gt;
&lt;br /&gt;
== Conventional System vs Privacy-by-Design System ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Feature&lt;br /&gt;
! Conventional System&lt;br /&gt;
! Privacy-by-Design System&lt;br /&gt;
|-&lt;br /&gt;
| Sensor processing&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed locally on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Raw LDR readings&lt;br /&gt;
| May be continuously transmitted&lt;br /&gt;
| Processed locally&lt;br /&gt;
|-&lt;br /&gt;
| Normal readings&lt;br /&gt;
| May be transmitted&lt;br /&gt;
| No unnecessary transmission&lt;br /&gt;
|-&lt;br /&gt;
| Threshold detection&lt;br /&gt;
| May be performed at server&lt;br /&gt;
| Performed on ESP32&lt;br /&gt;
|-&lt;br /&gt;
| Alert&lt;br /&gt;
| May contain sensor information&lt;br /&gt;
| Only required alert is exposed&lt;br /&gt;
|-&lt;br /&gt;
| Data volume&lt;br /&gt;
| Higher&lt;br /&gt;
| Lower&lt;br /&gt;
|-&lt;br /&gt;
| Data exposure&lt;br /&gt;
| Higher&lt;br /&gt;
| Minimized&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Why This is Privacy-by-Design ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates Privacy-by-Design through the following design decisions:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Local Processing:&#039;&#039;&#039; Raw LDR readings are processed on the ESP32.&lt;br /&gt;
# &#039;&#039;&#039;Data Minimization:&#039;&#039;&#039; Continuous raw readings are not unnecessarily transmitted.&lt;br /&gt;
# &#039;&#039;&#039;Purpose Limitation:&#039;&#039;&#039; The system only needs to detect a possible power-cut condition.&lt;br /&gt;
# &#039;&#039;&#039;Smart Thresholding:&#039;&#039;&#039; An alert is generated only when the threshold is crossed.&lt;br /&gt;
# &#039;&#039;&#039;Reduced Data Exposure:&#039;&#039;&#039; Unnecessary sensor information is not exposed.&lt;br /&gt;
# &#039;&#039;&#039;Privacy by Default:&#039;&#039;&#039; The system is designed to minimize data exposure from the beginning.&lt;br /&gt;
&lt;br /&gt;
The main principle demonstrated is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Do not transmit unnecessary information&lt;br /&gt;
when the application does not require it.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Advantages ==&lt;br /&gt;
&lt;br /&gt;
# Reduces unnecessary data transmission.&lt;br /&gt;
# Reduces the amount of sensor information exposed outside the device.&lt;br /&gt;
# Reduces network traffic.&lt;br /&gt;
# Allows fast local decision making.&lt;br /&gt;
# Demonstrates data minimization clearly.&lt;br /&gt;
# Does not require an external cloud server.&lt;br /&gt;
# Can be demonstrated easily using a smartphone.&lt;br /&gt;
# Can be extended to other IoT alert applications.&lt;br /&gt;
&lt;br /&gt;
== Limitations ==&lt;br /&gt;
&lt;br /&gt;
# The LDR provides an indirect indication of a power cut.&lt;br /&gt;
# Changes in environmental lighting can also trigger the alert.&lt;br /&gt;
# The threshold must be calibrated.&lt;br /&gt;
# The HTTP communication used in this experiment is not encrypted.&lt;br /&gt;
# This experiment demonstrates data minimization and not complete IoT security.&lt;br /&gt;
# A real power monitoring system would use an appropriate electrical sensing method.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The smart threshold alert system was successfully implemented using an LDR sensor and ESP32.&lt;br /&gt;
&lt;br /&gt;
The ESP32 locally processed the LDR readings and detected a dark condition using a predefined threshold.&lt;br /&gt;
&lt;br /&gt;
When the threshold was crossed, the smartphone displayed a POWER CUT alert through the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
The ESP32 used the IP address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
192.168.1.4&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrated that raw LDR readings do not need to be continuously exposed when the application only requires an event notification.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated data minimization through local processing and smart threshold alerts as a practical Privacy-by-Design approach.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is Privacy-by-Design?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Privacy-by-Design means incorporating privacy considerations into the design of a system from the beginning.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. What is data minimization?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Data minimization means collecting, processing, transmitting, and storing only the data required for the intended purpose.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. Why is an LDR used?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; An LDR is used because its light-sensitive behavior makes it easy to manually generate a threshold event by covering it with a finger.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What does darkness represent in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Darkness is treated as an indication of a possible power cut.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. Why is the raw LDR value not continuously transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The application only needs to know whether the threshold has been crossed. Therefore, continuous transmission of the raw value is unnecessary.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. Where is the threshold checked?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The threshold is checked locally on the ESP32.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What happens when the threshold is not crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No power-cut alert is generated and unnecessary sensor data is not exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What happens when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The ESP32 detects the dark condition and generates the POWER CUT alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is the purpose of the data inspection demonstration?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; It demonstrates how much sensor information is exposed and how data minimization reduces unnecessary information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What information is required when the threshold is crossed?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The required information is the POWER CUT alert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Is the system completely secure?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. The main purpose is to demonstrate data minimization and Privacy-by-Design. HTTP communication is not encrypted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Does data minimization mean that no data is transmitted?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; No. It means that only the data necessary for the intended purpose should be transmitted or exposed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. Why is local processing useful?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; Local processing allows the ESP32 to make decisions using raw sensor data without unnecessarily exposing that raw data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is a smart threshold alert?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; A smart threshold alert is generated when a sensor reading crosses a predefined threshold representing a meaningful condition.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. What is the main principle demonstrated by this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ans:&#039;&#039;&#039; The main principle is data minimization. Raw sensor information is processed locally and only the required alert is exposed.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_ESPNOW&amp;diff=1360</id>
		<title>MDM331AID/Experiment 12 ESPNOW</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_ESPNOW&amp;diff=1360"/>
		<updated>2026-10-07T12:13:58Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Secure Sensor Data Transmission Using ESP-NOW =  == Aim ==  To implement secure wireless transmission of temperature and humidity data between two ESP32 devices using ESP-NOW with AES-128-based encryption.  == Objectives ==  * To understand the concept of ESP-NOW communication in IoT systems. * To interface a DHT11 temperature and humidity sensor with an ESP32. * To transmit sensor data directly between two ESP32 devices without using an access point or clo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using ESP-NOW =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure wireless transmission of temperature and humidity data between two ESP32 devices using ESP-NOW with AES-128-based encryption.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of ESP-NOW communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To transmit sensor data directly between two ESP32 devices without using an access point or cloud server.&lt;br /&gt;
* To configure ESP-NOW communication between a transmitter and receiver.&lt;br /&gt;
* To understand peer-to-peer wireless communication in IoT systems.&lt;br /&gt;
* To configure ESP-NOW encryption using a Primary Master Key (PMK) and Local Master Key (LMK).&lt;br /&gt;
* To understand how AES-128-based encryption protects ESP-NOW communication.&lt;br /&gt;
* To verify that the receiver successfully obtains the transmitted sensor data.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 2&lt;br /&gt;
| One transmitter and one receiver&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 2&lt;br /&gt;
| Programming and powering ESP32 boards&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Computer&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and monitoring&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== ESP-NOW ===&lt;br /&gt;
&lt;br /&gt;
ESP-NOW is a connectionless wireless communication protocol developed by Espressif for communication between ESP devices.&lt;br /&gt;
&lt;br /&gt;
It allows ESP32 devices to exchange data directly without requiring a traditional Wi-Fi access point or Internet connection. It is suitable for IoT applications such as sensors, remote controls and local device-to-device communication.&lt;br /&gt;
&lt;br /&gt;
The communication structure used in this experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
ESP32 Transmitter&lt;br /&gt;
      ↓&lt;br /&gt;
   ESP-NOW&lt;br /&gt;
      ↓&lt;br /&gt;
ESP32 Receiver&lt;br /&gt;
      ↓&lt;br /&gt;
Serial Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ESP-NOW Peer Communication ===&lt;br /&gt;
&lt;br /&gt;
In ESP-NOW, devices communicate using peer-to-peer wireless communication.&lt;br /&gt;
&lt;br /&gt;
The transmitter sends a sensor-data packet to the MAC address of the receiver.&lt;br /&gt;
&lt;br /&gt;
Unlike a normal Wi-Fi application, the devices do not need to establish a conventional IP connection with each other.&lt;br /&gt;
&lt;br /&gt;
=== ESP-NOW Security ===&lt;br /&gt;
&lt;br /&gt;
ESP-NOW provides security using the &#039;&#039;&#039;CCMP&#039;&#039;&#039; security mechanism.&lt;br /&gt;
&lt;br /&gt;
A Primary Master Key (PMK) and Local Master Keys (LMKs) are used for encrypted peer communication.&lt;br /&gt;
&lt;br /&gt;
The PMK is used to protect the LMK using AES-128, while the LMK associated with a paired device is used to encrypt the ESP-NOW communication frame.&lt;br /&gt;
&lt;br /&gt;
The basic security structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             Primary Master Key&lt;br /&gt;
                     ↓&lt;br /&gt;
               Protects LMK&lt;br /&gt;
                     ↓&lt;br /&gt;
          Local Master Key&lt;br /&gt;
                     ↓&lt;br /&gt;
             AES-128 / CCMP&lt;br /&gt;
                     ↓&lt;br /&gt;
          Encrypted ESP-NOW&lt;br /&gt;
                Communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an LMK is not configured for a paired device, that ESP-NOW communication is not encrypted. Therefore, configuring the encrypted peer correctly is an important part of this experiment.&lt;br /&gt;
&lt;br /&gt;
=== AES-128 ===&lt;br /&gt;
&lt;br /&gt;
AES stands for Advanced Encryption Standard.&lt;br /&gt;
&lt;br /&gt;
ESP-NOW uses AES-128 as part of its security mechanism. AES-128 uses a 128-bit key to protect the communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the encryption is handled by the ESP-NOW security mechanism rather than manually implementing AES encryption in the application code.&lt;br /&gt;
&lt;br /&gt;
Therefore:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
     ↓&lt;br /&gt;
ESP-NOW Security&lt;br /&gt;
     ↓&lt;br /&gt;
AES-128 / CCMP Protection&lt;br /&gt;
     ↓&lt;br /&gt;
Wireless Transmission&lt;br /&gt;
     ↓&lt;br /&gt;
ESP32 Receiver&lt;br /&gt;
     ↓&lt;br /&gt;
Decrypted Sensor Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advantages of ESP-NOW ===&lt;br /&gt;
&lt;br /&gt;
* Direct communication between ESP32 devices.&lt;br /&gt;
* Does not require an Internet connection.&lt;br /&gt;
* Does not require a cloud server.&lt;br /&gt;
* Low communication overhead.&lt;br /&gt;
* Suitable for local IoT applications.&lt;br /&gt;
* Supports encrypted peer communication.&lt;br /&gt;
* Suitable for sensor and control applications.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 Transmitter ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The second ESP32 is used only as the receiver and does not require a DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                 TRANSMITTER&lt;br /&gt;
&lt;br /&gt;
        +-------------------+&lt;br /&gt;
        |       DHT11       |&lt;br /&gt;
        |                   |&lt;br /&gt;
        | VCC DATA GND      |&lt;br /&gt;
        +--+----+----+------+&lt;br /&gt;
           |    |    |&lt;br /&gt;
          3.3V GPIO4 GND&lt;br /&gt;
           |    |    |&lt;br /&gt;
     +-----+----+----+-----+&lt;br /&gt;
     |       ESP32 #1      |&lt;br /&gt;
     |    TRANSMITTER      |&lt;br /&gt;
     +----------+----------+&lt;br /&gt;
                |&lt;br /&gt;
                |&lt;br /&gt;
                |  Secure ESP-NOW&lt;br /&gt;
                |  AES-128 / CCMP&lt;br /&gt;
                |&lt;br /&gt;
                ↓&lt;br /&gt;
     +---------------------+&lt;br /&gt;
     |      ESP32 #2       |&lt;br /&gt;
     |      RECEIVER       |&lt;br /&gt;
     +----------+----------+&lt;br /&gt;
                |&lt;br /&gt;
                ↓&lt;br /&gt;
          Serial Monitor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Important Configuration ===&lt;br /&gt;
&lt;br /&gt;
The following example uses:&lt;br /&gt;
&lt;br /&gt;
* ESP32 #1 as the transmitter.&lt;br /&gt;
* ESP32 #2 as the receiver.&lt;br /&gt;
* DHT11 connected to GPIO 4 of ESP32 #1.&lt;br /&gt;
* A fixed PMK for the ESP-NOW security configuration.&lt;br /&gt;
* A fixed LMK for the encrypted transmitter-receiver peer.&lt;br /&gt;
* The receiver&#039;s MAC address configured in the transmitter.&lt;br /&gt;
* The transmitter&#039;s MAC address configured in the receiver.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The MAC addresses must be changed to match the two ESP32 boards being used.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Find the MAC Address ===&lt;br /&gt;
&lt;br /&gt;
Upload the following program to each ESP32 separately:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WiFi.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;ESP32 MAC Address: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32 MAC Address: 24:6F:28:AA:BB:CC&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Record the MAC address of both ESP32 boards.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: ESP32 Transmitter Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WiFi.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;esp_now.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;DHT.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Replace this with the MAC address&lt;br /&gt;
   of ESP32 Receiver.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t receiverAddress[] =&lt;br /&gt;
{&lt;br /&gt;
  0x24, 0x6F, 0x28, 0xAA, 0xBB, 0xCC&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   16-byte Primary Master Key.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t PMK[] =&lt;br /&gt;
{&lt;br /&gt;
  &#039;P&#039;,&#039;M&#039;,&#039;K&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&lt;br /&gt;
  &#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   16-byte Local Master Key.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t LMK[] =&lt;br /&gt;
{&lt;br /&gt;
  &#039;L&#039;,&#039;M&#039;,&#039;K&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&lt;br /&gt;
  &#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
  float temperature;&lt;br /&gt;
  float humidity;&lt;br /&gt;
} SensorData;&lt;br /&gt;
&lt;br /&gt;
SensorData data;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Transmitter MAC: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
&lt;br /&gt;
  if (esp_now_init() != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;ESP-NOW initialization failed&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Set Primary Master Key.&lt;br /&gt;
  */&lt;br /&gt;
  if (esp_now_set_pmk(PMK) != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;PMK configuration failed&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Configure encrypted receiver.&lt;br /&gt;
  */&lt;br /&gt;
  esp_now_peer_info_t peerInfo = {};&lt;br /&gt;
&lt;br /&gt;
  memcpy(&lt;br /&gt;
    peerInfo.peer_addr,&lt;br /&gt;
    receiverAddress,&lt;br /&gt;
    6&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  peerInfo.channel = 0;&lt;br /&gt;
  peerInfo.encrypt = true;&lt;br /&gt;
&lt;br /&gt;
  memcpy(&lt;br /&gt;
    peerInfo.lmk,&lt;br /&gt;
    LMK,&lt;br /&gt;
    16&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  if (esp_now_add_peer(&amp;amp;peerInfo) != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Failed to add encrypted peer&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Secure ESP-NOW transmitter ready&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  data.temperature = dht.readTemperature();&lt;br /&gt;
  data.humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(data.temperature) ||&lt;br /&gt;
      isnan(data.humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  esp_err_t result = esp_now_send(&lt;br /&gt;
    receiverAddress,&lt;br /&gt;
    (uint8_t *)&amp;amp;data,&lt;br /&gt;
    sizeof(data)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  if (result == ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Encrypted sensor data sent&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Data transmission failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(data.temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(data.humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: ESP32 Receiver Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;WiFi.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;esp_now.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Replace this with the MAC address&lt;br /&gt;
   of ESP32 Transmitter.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t transmitterAddress[] =&lt;br /&gt;
{&lt;br /&gt;
  0x24, 0x6F, 0x28, 0x11, 0x22, 0x33&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Same 16-byte Primary Master Key&lt;br /&gt;
   used by the transmitter.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t PMK[] =&lt;br /&gt;
{&lt;br /&gt;
  &#039;P&#039;,&#039;M&#039;,&#039;K&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&lt;br /&gt;
  &#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Same 16-byte Local Master Key&lt;br /&gt;
   used by the transmitter.&lt;br /&gt;
*/&lt;br /&gt;
uint8_t LMK[] =&lt;br /&gt;
{&lt;br /&gt;
  &#039;L&#039;,&#039;M&#039;,&#039;K&#039;,&#039;1&#039;,&#039;2&#039;,&#039;3&#039;,&#039;4&#039;,&#039;5&#039;,&lt;br /&gt;
  &#039;6&#039;,&#039;7&#039;,&#039;8&#039;,&#039;9&#039;,&#039;A&#039;,&#039;B&#039;,&#039;C&#039;,&#039;D&#039;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
typedef struct&lt;br /&gt;
{&lt;br /&gt;
  float temperature;&lt;br /&gt;
  float humidity;&lt;br /&gt;
} SensorData;&lt;br /&gt;
&lt;br /&gt;
SensorData receivedData;&lt;br /&gt;
&lt;br /&gt;
void onDataReceive(&lt;br /&gt;
  const esp_now_recv_info_t *info,&lt;br /&gt;
  const uint8_t *incomingData,&lt;br /&gt;
  int len&lt;br /&gt;
)&lt;br /&gt;
{&lt;br /&gt;
  if (len != sizeof(SensorData))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Invalid data size&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  memcpy(&lt;br /&gt;
    &amp;amp;receivedData,&lt;br /&gt;
    incomingData,&lt;br /&gt;
    sizeof(receivedData)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Secure sensor data received&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(receivedData.temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(receivedData.humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  WiFi.mode(WIFI_STA);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Receiver MAC: &amp;quot;);&lt;br /&gt;
  Serial.println(WiFi.macAddress());&lt;br /&gt;
&lt;br /&gt;
  if (esp_now_init() != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;ESP-NOW initialization failed&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Set Primary Master Key.&lt;br /&gt;
  */&lt;br /&gt;
  if (esp_now_set_pmk(PMK) != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;PMK configuration failed&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /*&lt;br /&gt;
     Configure the encrypted transmitter peer.&lt;br /&gt;
  */&lt;br /&gt;
  esp_now_peer_info_t peerInfo = {};&lt;br /&gt;
&lt;br /&gt;
  memcpy(&lt;br /&gt;
    peerInfo.peer_addr,&lt;br /&gt;
    transmitterAddress,&lt;br /&gt;
    6&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  peerInfo.channel = 0;&lt;br /&gt;
  peerInfo.encrypt = true;&lt;br /&gt;
&lt;br /&gt;
  memcpy(&lt;br /&gt;
    peerInfo.lmk,&lt;br /&gt;
    LMK,&lt;br /&gt;
    16&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  if (esp_now_add_peer(&amp;amp;peerInfo) != ESP_OK)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Failed to add encrypted peer&amp;quot;);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  esp_now_register_recv_cb(onDataReceive);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Secure ESP-NOW receiver ready&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  delay(100);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code / Function&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `WiFi.mode(WIFI_STA)`&lt;br /&gt;
| Configures the ESP32 Wi-Fi interface in station mode.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_init()`&lt;br /&gt;
| Initializes ESP-NOW communication.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_set_pmk()`&lt;br /&gt;
| Sets the Primary Master Key used by ESP-NOW security.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_peer_info_t`&lt;br /&gt;
| Stores information about the ESP-NOW peer.&lt;br /&gt;
|-&lt;br /&gt;
| `peer_addr`&lt;br /&gt;
| Stores the MAC address of the communication peer.&lt;br /&gt;
|-&lt;br /&gt;
| `peerInfo.encrypt = true`&lt;br /&gt;
| Enables encrypted ESP-NOW communication with the configured peer.&lt;br /&gt;
|-&lt;br /&gt;
| `peerInfo.lmk`&lt;br /&gt;
| Stores the Local Master Key associated with the peer.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_add_peer()`&lt;br /&gt;
| Adds the encrypted peer to the ESP-NOW peer list.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_send()`&lt;br /&gt;
| Sends the sensor-data packet to the receiver.&lt;br /&gt;
|-&lt;br /&gt;
| `esp_now_register_recv_cb()`&lt;br /&gt;
| Registers the function that is called when ESP-NOW data is received.&lt;br /&gt;
|-&lt;br /&gt;
| `memcpy()`&lt;br /&gt;
| Copies the received byte data into the sensor-data structure.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
Two keys are used in the practical.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key&lt;br /&gt;
! Size&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| PMK&lt;br /&gt;
| 16 bytes&lt;br /&gt;
| Primary Master Key used to protect the LMK.&lt;br /&gt;
|-&lt;br /&gt;
| LMK&lt;br /&gt;
| 16 bytes&lt;br /&gt;
| Local Master Key associated with the encrypted peer.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
ESP-NOW documentation specifies 16-byte PMK and LMK values. The PMK is used to encrypt the LMK using AES-128, while the LMK is used for protecting the communication frame with CCMP.&lt;br /&gt;
&lt;br /&gt;
The transmitter and receiver must use the corresponding key configuration.&lt;br /&gt;
&lt;br /&gt;
== Security Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete security process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                 Sensor Data&lt;br /&gt;
                     ↓&lt;br /&gt;
              ESP32 Transmitter&lt;br /&gt;
                     ↓&lt;br /&gt;
               ESP-NOW Peer&lt;br /&gt;
                     ↓&lt;br /&gt;
               LMK / PMK&lt;br /&gt;
                     ↓&lt;br /&gt;
             AES-128 / CCMP&lt;br /&gt;
                     ↓&lt;br /&gt;
             Encrypted Frame&lt;br /&gt;
                     ↓&lt;br /&gt;
              Wireless Transfer&lt;br /&gt;
                     ↓&lt;br /&gt;
               ESP32 Receiver&lt;br /&gt;
                     ↓&lt;br /&gt;
              Decryption /&lt;br /&gt;
              Security Check&lt;br /&gt;
                     ↓&lt;br /&gt;
               Sensor Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to GPIO 4 of the transmitter ESP32.&lt;br /&gt;
# Connect both ESP32 boards to the computer using USB cables.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the DHT sensor library if required.&lt;br /&gt;
# Upload the MAC-address program to both ESP32 boards.&lt;br /&gt;
# Record the MAC address of the transmitter.&lt;br /&gt;
# Record the MAC address of the receiver.&lt;br /&gt;
# Enter the receiver MAC address in the transmitter program.&lt;br /&gt;
# Enter the transmitter MAC address in the receiver program.&lt;br /&gt;
# Keep the PMK and LMK identical on both ESP32 programs.&lt;br /&gt;
# Upload the receiver program to ESP32 #2.&lt;br /&gt;
# Open the receiver Serial Monitor at 115200 baud.&lt;br /&gt;
# Upload the transmitter program to ESP32 #1.&lt;br /&gt;
# Open the transmitter Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that both devices report successful ESP-NOW initialization.&lt;br /&gt;
# Verify that the encrypted peer is added successfully.&lt;br /&gt;
# Observe the DHT11 temperature and humidity readings on the transmitter.&lt;br /&gt;
# Observe the corresponding readings on the receiver.&lt;br /&gt;
# Verify that the receiver obtains the sensor data through the secured ESP-NOW link.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Transmitter Output ===&lt;br /&gt;
&lt;br /&gt;
The transmitter Serial Monitor should display output similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Transmitter MAC: 24:6F:28:AA:BB:CC&lt;br /&gt;
Secure ESP-NOW transmitter ready&lt;br /&gt;
&lt;br /&gt;
Encrypted sensor data sent&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Encrypted sensor data sent&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Receiver Output ===&lt;br /&gt;
&lt;br /&gt;
The receiver Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Receiver MAC: 24:6F:28:11:22:33&lt;br /&gt;
Secure ESP-NOW receiver ready&lt;br /&gt;
&lt;br /&gt;
Secure sensor data received&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Secure sensor data received&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Observation Table ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Transmitter Temperature&lt;br /&gt;
! Receiver Temperature&lt;br /&gt;
! Transmitter Humidity&lt;br /&gt;
! Receiver Humidity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
| 61 %&lt;br /&gt;
| 61 %&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 27.50 °C&lt;br /&gt;
| 27.50 °C&lt;br /&gt;
| 61 %&lt;br /&gt;
| 61 %&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 27.50 °C&lt;br /&gt;
| 27.50 °C&lt;br /&gt;
| 62 %&lt;br /&gt;
| 62 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The values shown above are example observations. Actual readings depend on the DHT11 sensor and surrounding environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Security Verification ==&lt;br /&gt;
&lt;br /&gt;
The security can be demonstrated by intentionally changing the security configuration.&lt;br /&gt;
&lt;br /&gt;
For example, the following tests can be performed:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Test&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| Correct receiver MAC and matching PMK/LMK&lt;br /&gt;
| Sensor data is successfully received.&lt;br /&gt;
|-&lt;br /&gt;
| Incorrect receiver MAC&lt;br /&gt;
| Data is not delivered to the intended receiver.&lt;br /&gt;
|-&lt;br /&gt;
| Incorrect LMK&lt;br /&gt;
| Encrypted peer communication does not work correctly.&lt;br /&gt;
|-&lt;br /&gt;
| ESP-NOW peer encryption disabled&lt;br /&gt;
| Communication is no longer using the configured encrypted peer mechanism.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This demonstrates that secure ESP-NOW communication depends on correctly configured peer security parameters.&lt;br /&gt;
&lt;br /&gt;
== ESP-NOW vs Normal Wi-Fi Communication ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Feature&lt;br /&gt;
! Normal Wi-Fi Application&lt;br /&gt;
! ESP-NOW&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Usually through an IP network&lt;br /&gt;
| Direct device-to-device&lt;br /&gt;
|-&lt;br /&gt;
| Internet required&lt;br /&gt;
| May be required&lt;br /&gt;
| No&lt;br /&gt;
|-&lt;br /&gt;
| Access point required&lt;br /&gt;
| Usually&lt;br /&gt;
| Not for direct ESP-NOW communication&lt;br /&gt;
|-&lt;br /&gt;
| IoT sensor applications&lt;br /&gt;
| Yes&lt;br /&gt;
| Yes&lt;br /&gt;
|-&lt;br /&gt;
| Encrypted peer communication&lt;br /&gt;
| Depends on the Wi-Fi/security protocol used&lt;br /&gt;
| Supported through ESP-NOW security&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
ESP-NOW is specifically designed for direct communication between ESP devices and does not require an access point for device-to-device communication.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The PMK and LMK used in this experiment are demonstration keys.&lt;br /&gt;
* Real IoT systems should use properly managed, unique keys.&lt;br /&gt;
* Keys should not be exposed publicly or hard-coded in production firmware without appropriate protection.&lt;br /&gt;
* The experiment demonstrates link-level ESP-NOW security and does not represent complete IoT security.&lt;br /&gt;
* Broadcast ESP-NOW communication does not provide the same encrypted peer mechanism as an encrypted unicast peer. Espressif notes that multicast vendor-specific action frames are not supported for encryption.&lt;br /&gt;
* Only authorized peers should be added when transmitting sensitive information.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32 transmitter, and temperature and humidity data were transmitted wirelessly to a second ESP32 using ESP-NOW. Encrypted peer communication was configured using a PMK and LMK, providing AES-128-based protection through ESP-NOW&#039;s CCMP security mechanism. The transmitted sensor values were successfully received by the second ESP32.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is ESP-NOW?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ESP-NOW is a connectionless wireless communication protocol developed by Espressif for direct communication between ESP devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Does ESP-NOW require an Internet connection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No. ESP-NOW can communicate directly between ESP devices without an Internet connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. Does ESP-NOW require a Wi-Fi router?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No. Direct ESP-NOW communication between ESP devices does not require a conventional Wi-Fi access point.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is the role of the MAC address?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The MAC address identifies the ESP-NOW peer to which the data is transmitted.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is PMK?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
PMK stands for Primary Master Key. It is a 16-byte key used as part of the ESP-NOW security mechanism.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is LMK?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LMK stands for Local Master Key. It is associated with an individual encrypted ESP-NOW peer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. Which encryption algorithm is associated with ESP-NOW security?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
ESP-NOW security uses AES-128 as part of its PMK/LMK and CCMP-based protection mechanism.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is CCMP?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
CCMP stands for Counter Mode with Cipher Block Chaining Message Authentication Code Protocol. It is used to protect ESP-NOW communication frames.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. Why is `peerInfo.encrypt = true` used?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It enables encrypted communication for the configured ESP-NOW peer.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What happens if the LMK is not configured for an encrypted peer?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The peer&#039;s ESP-NOW communication will not use the configured encrypted peer mechanism.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why are two ESP32 boards used?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
One ESP32 acts as the sensor transmitter and the other acts as the receiver, demonstrating direct IoT device-to-device communication.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Why is DHT11 connected only to the transmitter?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The transmitter reads the sensor data and sends it to the receiver. Therefore, the receiver does not need its own DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the advantage of ESP-NOW for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
It provides direct, low-overhead communication between ESP devices and is suitable for sensor and control applications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. How is this experiment different from HTTPS communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS secures communication between a client and a server using TLS. This experiment demonstrates encrypted local device-to-device communication using ESP-NOW.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. Is ESP-NOW itself an encryption algorithm?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
No. ESP-NOW is a communication protocol. Its security mechanism uses CCMP and AES-128-based key management to protect encrypted peer communication.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates secure wireless sensor-data transmission between two ESP32 devices using ESP-NOW. The DHT11 sensor data is transmitted directly from the transmitter ESP32 to the receiver ESP32 without using the Internet or a cloud server. ESP-NOW peer encryption is configured using PMK and LMK keys, providing AES-128-based protection through CCMP. The experiment demonstrates how secure device-to-device communication can be implemented in an IoT system.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1359</id>
		<title>AIDS IoT Kits User Manuals</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1359"/>
		<updated>2026-10-07T12:13:09Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Laboratory Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sppu-logo.jpg|200px|SPPU Logo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:200%; font-weight:bold;&amp;quot;&amp;gt;TE AIDS MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:120%;&amp;quot;&amp;gt;Cognifront IoT Kit for MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About the Laboratory ==&lt;br /&gt;
&lt;br /&gt;
The Internet of Things (IoT) laboratory provides hands-on experience in connecting physical devices, sensors, microcontrollers and cloud platforms to develop intelligent, connected systems.&lt;br /&gt;
&lt;br /&gt;
This laboratory manual is designed for students of Third Year B.E. Artificial Intelligence and Data Science Engineering, covering fundamental IoT concepts, embedded programming, sensor interfacing, network communication and cloud-based applications.&lt;br /&gt;
&lt;br /&gt;
== Laboratory Objectives ==&lt;br /&gt;
&lt;br /&gt;
* Understand the architecture and fundamental concepts of the Internet of Things.&lt;br /&gt;
* Interface sensors and actuators with embedded development boards.&lt;br /&gt;
* Develop programs for acquiring and processing sensor data.&lt;br /&gt;
* Implement communication protocols used in IoT systems.&lt;br /&gt;
* Connect IoT devices with cloud platforms for data visualization and monitoring.&lt;br /&gt;
* Design and implement real-world IoT applications.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #&lt;br /&gt;
! Experiment Title&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part A&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| [[MDM331AID/Experiment 1|Develop an application for the connectivity of the Arduino UNO/Raspberry Pi circuit with sensors.]]&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[MDM331AID/Experiment 2|Implement an application to detect obstacles and notify users using LEDs to understand the connectivity of Raspberry Pi / Arduino with IR sensor.]]&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| [[MDM331AID/Experiment 3|Implement a simple IoT application using an Arduino board to control an LED through GPIO pins in order to understand the physical design of IoT devices and device actuation.]]&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| [[MDM331AID/Experiment 4|Develop a program to detect gas leakage in the surrounding environment.]]&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| [[MDM331AID/Experiment 5|Configure and implement an IoT device (Arduino UNO/ESP module/Raspberry Pi) to connect to a Wi-Fi network and transmit sensor data to a remote computer using TCP/IP communication.]]&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| [[MDM331AID/Experiment 6|Implement an edge computing model where sensor data is processed locally on an edge device (Raspberry Pi) before being transmitted to the cloud to reduce latency and bandwidth usage.]]&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[MDM331AID/Experiment 7|Design an RFID-based identification system that reads tag information and displays the ID on a monitoring system to demonstrate short-range communication technologies in IoT.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part B&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| [[MDM331AID/Experiment 8|Develop an IoT application that uses a communication protocol to transmit sensor data between an IoT device and a server.]]&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| [[MDM331AID/Experiment 9|Perform data cleaning, normalization, and visualization on an IoT sensor dataset (any dataset can be considered).]]&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| [[MDM331AID/Experiment 10|Implement an IoT application to collect real-time temperature data using an IoT sensor and apply a machine learning model to predict future temperature values (any machine learning model).]]&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| [[MDM331AID/Experiment 11|Design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts (any security algorithm can be used).]]&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| [[MDM331AID/Experiment 12|(Final Page)Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/1&lt;br /&gt;
| [[MDM331AID/Experiment 12_BLE|(BLE)Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/2&lt;br /&gt;
| [[MDM331AID/Experiment 12_ESPNOW|(ESPNOW) Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| [[MDM331AID/Experiment 13|Develop and implement a machine learning model to perform classification (e.g., activity recognition or device state detection) and anomaly detection (e.g., fault detection in industrial IoT sensors).]]&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| [[MDM331AID/Experiment 14|Case study for data minimization using smart threshold alerts by providing Privacy-by-Design.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part C&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| [[MDM331AID/Experiment 15|Develop a Privacy-Aware Intelligent Smart IoT Application: Design and implementation of an AIoT-based smart sensor system with cloud-based data preprocessing and intelligent decision-making using machine learning techniques, incorporating secure communication protocols with built-in security and privacy mechanisms, with complete deliverables including a working demonstration and technical report.]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1358</id>
		<title>MDM331AID/Experiment 12 BLE</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12_BLE&amp;diff=1358"/>
		<updated>2026-10-07T12:12:09Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =  == Aim ==  To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.  == Objectives ==  * To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems. * To interface a DHT11 temperature and humidity sensor with an ESP32....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To configure the ESP32 as a BLE server.&lt;br /&gt;
* To transmit real-time sensor data from the ESP32 to a smartphone using BLE.&lt;br /&gt;
* To understand BLE services and characteristics.&lt;br /&gt;
* To implement BLE pairing and authentication using a passkey.&lt;br /&gt;
* To understand how BLE encryption protects transmitted sensor data.&lt;br /&gt;
* To verify secure sensor-data communication using a smartphone BLE application.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| IoT controller and BLE server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and power supply&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| BLE client for receiving sensor data&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| LightBlue® BLE Application&lt;br /&gt;
| 1&lt;br /&gt;
| Scanning, connecting and monitoring BLE data&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Application ===&lt;br /&gt;
&lt;br /&gt;
The recommended application for this experiment is **LightBlue® by Punch Through**.&lt;br /&gt;
&lt;br /&gt;
LightBlue is a BLE debugging and development application that is available for both Android and iOS. It can scan for BLE peripherals, connect to them, display their services and characteristics, and read or subscribe to characteristic values.&lt;br /&gt;
&lt;br /&gt;
The application can be installed from:&lt;br /&gt;
&lt;br /&gt;
* Android: [LightBlue® on Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
* iPhone/iPad: [LightBlue® on the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth Low Energy ===&lt;br /&gt;
&lt;br /&gt;
Bluetooth Low Energy (BLE) is a wireless communication technology designed for low-power communication between devices. It is widely used in IoT sensors, wearable devices, smart-home devices and other embedded systems.&lt;br /&gt;
&lt;br /&gt;
An ESP32 can operate as a BLE device and communicate with smartphones and other BLE-enabled devices. The Arduino ESP32 framework provides a BLE library for creating BLE servers, services and characteristics.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 operates as a &#039;&#039;&#039;BLE GATT server&#039;&#039;&#039;, while the smartphone operates as the &#039;&#039;&#039;BLE client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The communication structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     ↓&lt;br /&gt;
   ESP32&lt;br /&gt;
     ↓&lt;br /&gt;
 BLE GATT Server&lt;br /&gt;
     ↓&lt;br /&gt;
 Secure BLE Connection&lt;br /&gt;
     ↓&lt;br /&gt;
 Smartphone&lt;br /&gt;
     ↓&lt;br /&gt;
 LightBlue Application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BLE GATT ===&lt;br /&gt;
&lt;br /&gt;
BLE devices commonly organize application data using the Generic Attribute Profile (GATT).&lt;br /&gt;
&lt;br /&gt;
The main components used in this experiment are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Service:&#039;&#039;&#039;  &lt;br /&gt;
A service groups related functionality of a BLE device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Characteristic:&#039;&#039;&#039;  &lt;br /&gt;
A characteristic contains a particular piece of data that can be read, written or notified.&lt;br /&gt;
&lt;br /&gt;
For this experiment, one BLE service is created containing two characteristics:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Characteristic&lt;br /&gt;
! Data&lt;br /&gt;
! Operation&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature in °C&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity in %&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The smartphone can connect to the ESP32 and subscribe to notifications so that updated sensor values are received automatically.&lt;br /&gt;
&lt;br /&gt;
=== BLE Security ===&lt;br /&gt;
&lt;br /&gt;
BLE provides security mechanisms for authentication, pairing, bonding and encrypted communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, BLE security is configured using:&lt;br /&gt;
&lt;br /&gt;
* Pairing&lt;br /&gt;
* Bonding&lt;br /&gt;
* MITM (Man-in-the-Middle) protection&lt;br /&gt;
* Secure Connections&lt;br /&gt;
* Passkey authentication&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s ESP32 BLE security documentation supports authentication modes combining bonding, MITM protection and Secure Connections.&lt;br /&gt;
&lt;br /&gt;
=== Pairing ===&lt;br /&gt;
&lt;br /&gt;
Pairing is the process by which two Bluetooth devices establish the information required to create a trusted secure relationship.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the smartphone and ESP32 are paired using a passkey.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32&lt;br /&gt;
  ↓&lt;br /&gt;
BLE connection request&lt;br /&gt;
  ↓&lt;br /&gt;
Pairing request&lt;br /&gt;
  ↓&lt;br /&gt;
Passkey authentication&lt;br /&gt;
  ↓&lt;br /&gt;
Secure key establishment&lt;br /&gt;
  ↓&lt;br /&gt;
Encrypted BLE communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bonding ===&lt;br /&gt;
&lt;br /&gt;
Bonding allows the security information established during pairing to be stored so that the devices can recognize each other during future connections.&lt;br /&gt;
&lt;br /&gt;
Espressif distinguishes bonding from encryption: bonding stores long-term keys after successful encryption, while encryption protects the communication link.&lt;br /&gt;
&lt;br /&gt;
=== BLE Encryption ===&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE link can be encrypted.&lt;br /&gt;
&lt;br /&gt;
Therefore, the sensor data transmitted over the BLE connection is protected from simple interception of the communication.&lt;br /&gt;
&lt;br /&gt;
The security flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
    ↓&lt;br /&gt;
BLE Security / Pairing&lt;br /&gt;
    ↓&lt;br /&gt;
Authentication&lt;br /&gt;
    ↓&lt;br /&gt;
Encryption&lt;br /&gt;
    ↓&lt;br /&gt;
Secure BLE Transmission&lt;br /&gt;
    ↓&lt;br /&gt;
Smartphone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              +----------------+&lt;br /&gt;
              |     DHT11      |&lt;br /&gt;
              |                |&lt;br /&gt;
              | VCC  DATA  GND |&lt;br /&gt;
              +--+----+-----+--+&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                3.3V GPIO4 GND&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                 |    |     |&lt;br /&gt;
          +------+----+-----+------+&lt;br /&gt;
          |          ESP32         |&lt;br /&gt;
          |                        |&lt;br /&gt;
          |       BLE Server       |&lt;br /&gt;
          |          ))))          |&lt;br /&gt;
          +------------))----------+&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                Secure BLE Link&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                 +-----------+&lt;br /&gt;
                 | Smartphone|&lt;br /&gt;
                 |           |&lt;br /&gt;
                 | LightBlue |&lt;br /&gt;
                 +-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Arduino Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;Arduino.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEServer.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEUtils.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;DHT.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define DEVICE_NAME &amp;quot;ESP32-Secure-Sensor&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define SERVICE_UUID \&lt;br /&gt;
&amp;quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define TEMP_UUID \&lt;br /&gt;
&amp;quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define HUMIDITY_UUID \&lt;br /&gt;
&amp;quot;cba1d466-344c-4be3-ab3f-189f80dd7518&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BLE_PASSKEY 123456&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
BLECharacteristic *temperatureCharacteristic;&lt;br /&gt;
BLECharacteristic *humidityCharacteristic;&lt;br /&gt;
&lt;br /&gt;
class SecurityCallbacks : public BLESecurityCallbacks&lt;br /&gt;
{&lt;br /&gt;
  uint32_t onPassKeyRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Passkey requested&amp;quot;);&lt;br /&gt;
    return BLE_PASSKEY;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onPassKeyNotify(uint32_t passkey)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Passkey: &amp;quot;);&lt;br /&gt;
    Serial.println(passkey);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onConfirmPIN(uint32_t pin)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Confirm PIN: &amp;quot;);&lt;br /&gt;
    Serial.println(pin);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onSecurityRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Security request received&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onAuthenticationComplete(esp_ble_auth_cmpl_t desc)&lt;br /&gt;
  {&lt;br /&gt;
    if (desc.success)&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication successful&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::init(DEVICE_NAME);&lt;br /&gt;
&lt;br /&gt;
  BLESecurity *security = new BLESecurity();&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setPassKey(true, BLE_PASSKEY);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setCapability(ESP_IO_CAP_OUT);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setAuthenticationMode(&lt;br /&gt;
    true,   // Bonding&lt;br /&gt;
    true,   // MITM protection&lt;br /&gt;
    true    // Secure Connections&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::setSecurityCallbacks(&lt;br /&gt;
    new SecurityCallbacks()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEServer *server = BLEDevice::createServer();&lt;br /&gt;
&lt;br /&gt;
  BLEService *service =&lt;br /&gt;
    server-&amp;gt;createService(SERVICE_UUID);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      TEMP_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      HUMIDITY_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  service-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
  BLEAdvertising *advertising =&lt;br /&gt;
    BLEDevice::getAdvertising();&lt;br /&gt;
&lt;br /&gt;
  advertising-&amp;gt;addServiceUUID(SERVICE_UUID);&lt;br /&gt;
  advertising-&amp;gt;setScanResponse(true);&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::startAdvertising();&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Secure BLE Sensor Started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Device Name: ESP32-Secure-Sensor&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Passkey: 123456&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Waiting for BLE connection...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  char temperatureValue[10];&lt;br /&gt;
  char humidityValue[10];&lt;br /&gt;
&lt;br /&gt;
  dtostrf(temperature, 1, 2, temperatureValue);&lt;br /&gt;
  dtostrf(humidity, 1, 2, humidityValue);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    temperatureValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    humidityValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;notify();&lt;br /&gt;
  humidityCharacteristic-&amp;gt;notify();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Sensor data sent using secure BLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;`&lt;br /&gt;
| Provides the main BLE device functionality.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEServer.h&amp;amp;gt;`&lt;br /&gt;
| Provides functionality for creating a BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;`&lt;br /&gt;
| Provides BLE pairing and security configuration.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;DHT.h&amp;amp;gt;`&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `DHTPIN 4`&lt;br /&gt;
| Defines GPIO 4 as the DHT11 data pin.&lt;br /&gt;
|-&lt;br /&gt;
| `DEVICE_NAME`&lt;br /&gt;
| Defines the name advertised by the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| `SERVICE_UUID`&lt;br /&gt;
| Uniquely identifies the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `TEMP_UUID`&lt;br /&gt;
| Identifies the temperature characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `HUMIDITY_UUID`&lt;br /&gt;
| Identifies the humidity characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `BLE_PASSKEY 123456`&lt;br /&gt;
| Defines the passkey used for BLE authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.begin()`&lt;br /&gt;
| Initializes the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `BLEDevice::init()`&lt;br /&gt;
| Initializes BLE and assigns the device name.&lt;br /&gt;
|-&lt;br /&gt;
| `setPassKey()`&lt;br /&gt;
| Configures the BLE passkey.&lt;br /&gt;
|-&lt;br /&gt;
| `setCapability()`&lt;br /&gt;
| Defines the input/output capability used during authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `setAuthenticationMode(true, true, true)`&lt;br /&gt;
| Enables bonding, MITM protection and Secure Connections.&lt;br /&gt;
|-&lt;br /&gt;
| `createServer()`&lt;br /&gt;
| Creates the ESP32 BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `createService()`&lt;br /&gt;
| Creates the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `createCharacteristic()`&lt;br /&gt;
| Creates temperature and humidity characteristics.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_READ`&lt;br /&gt;
| Allows the smartphone to read the sensor value.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_NOTIFY`&lt;br /&gt;
| Allows the ESP32 to send updated sensor values to the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| `service-&amp;gt;start()`&lt;br /&gt;
| Starts the BLE service.&lt;br /&gt;
|-&lt;br /&gt;
| `startAdvertising()`&lt;br /&gt;
| Makes the ESP32 discoverable by BLE clients.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `setValue()`&lt;br /&gt;
| Updates the BLE characteristic value.&lt;br /&gt;
|-&lt;br /&gt;
| `notify()`&lt;br /&gt;
| Sends the updated value to subscribed BLE clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following security settings are used in the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Security Feature&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Passkey&lt;br /&gt;
| Provides authentication during pairing.&lt;br /&gt;
|-&lt;br /&gt;
| MITM Protection&lt;br /&gt;
| Provides protection against certain man-in-the-middle attacks during authenticated pairing.&lt;br /&gt;
|-&lt;br /&gt;
| Secure Connections&lt;br /&gt;
| Uses the BLE Secure Connections pairing mechanism.&lt;br /&gt;
|-&lt;br /&gt;
| Bonding&lt;br /&gt;
| Allows security information to be retained for future connections.&lt;br /&gt;
|-&lt;br /&gt;
| Encryption&lt;br /&gt;
| Protects data transmitted over the established BLE link.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Espressif documents BLE security configurations including bonding, MITM protection and Secure Connections, and provides dedicated BLE security examples.&lt;br /&gt;
&lt;br /&gt;
== Smartphone Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install LightBlue ===&lt;br /&gt;
&lt;br /&gt;
Install &#039;&#039;&#039;LightBlue® by Punch Through&#039;&#039;&#039; on the smartphone.&lt;br /&gt;
&lt;br /&gt;
For Android:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
For iPhone/iPad:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
The same application is available on both platforms.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Upload the Program ===&lt;br /&gt;
&lt;br /&gt;
1. Connect the ESP32 to the computer using the USB cable.&lt;br /&gt;
2. Open Arduino IDE.&lt;br /&gt;
3. Select the appropriate ESP32 board.&lt;br /&gt;
4. Select the correct COM port.&lt;br /&gt;
5. Upload the program.&lt;br /&gt;
6. Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Start LightBlue ===&lt;br /&gt;
&lt;br /&gt;
1. Enable Bluetooth on the smartphone.&lt;br /&gt;
2. Open the LightBlue application.&lt;br /&gt;
3. Allow the required Bluetooth permissions.&lt;br /&gt;
4. Start scanning for nearby BLE devices.&lt;br /&gt;
5. Locate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Select the device and tap &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LightBlue supports BLE scanning, connection, service/characteristic inspection, reading, writing and notifications.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Pair the Device ===&lt;br /&gt;
&lt;br /&gt;
When the ESP32 requests secure pairing, the smartphone will display the BLE pairing/passkey interaction.&lt;br /&gt;
&lt;br /&gt;
Enter or confirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
123456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE connection becomes secured.&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s BLE documentation demonstrates pairing between an ESP32 BLE server and a mobile phone using LightBlue, including passkey-based pairing.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: View Sensor Data ===&lt;br /&gt;
&lt;br /&gt;
After connecting, LightBlue displays the BLE service and its characteristics.&lt;br /&gt;
&lt;br /&gt;
The structure will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&lt;br /&gt;
Service&lt;br /&gt;
└── Sensor Service&lt;br /&gt;
      │&lt;br /&gt;
      ├── Temperature&lt;br /&gt;
      │      Value: 27.40&lt;br /&gt;
      │&lt;br /&gt;
      └── Humidity&lt;br /&gt;
             Value: 61.00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact appearance of the LightBlue interface may vary between Android and iOS versions.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Enable Notifications ===&lt;br /&gt;
&lt;br /&gt;
The temperature and humidity characteristics support notifications.&lt;br /&gt;
&lt;br /&gt;
Enable notifications for the characteristics in LightBlue.&lt;br /&gt;
&lt;br /&gt;
The ESP32 will then periodically send updated sensor readings.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 62.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete data flow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             DHT11 Sensor&lt;br /&gt;
                  ↓&lt;br /&gt;
          Temperature / Humidity&lt;br /&gt;
                  ↓&lt;br /&gt;
                ESP32&lt;br /&gt;
                  ↓&lt;br /&gt;
            BLE GATT Server&lt;br /&gt;
                  ↓&lt;br /&gt;
       BLE Pairing &amp;amp; Authentication&lt;br /&gt;
                  ↓&lt;br /&gt;
          Encrypted BLE Link&lt;br /&gt;
                  ↓&lt;br /&gt;
             Smartphone&lt;br /&gt;
                  ↓&lt;br /&gt;
           LightBlue Application&lt;br /&gt;
                  ↓&lt;br /&gt;
       Temperature / Humidity Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the given pin connections.&lt;br /&gt;
# Install the DHT sensor library in Arduino IDE if required.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the LightBlue BLE application on an Android or iOS smartphone.&lt;br /&gt;
# Enter the BLE program into Arduino IDE.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Select the correct ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that the ESP32 starts BLE advertising.&lt;br /&gt;
# Open LightBlue on the smartphone.&lt;br /&gt;
# Scan for nearby BLE devices.&lt;br /&gt;
# Select `ESP32-Secure-Sensor`.&lt;br /&gt;
# Establish the BLE connection.&lt;br /&gt;
# Complete the passkey authentication using `123456`.&lt;br /&gt;
# Verify that the BLE connection is authenticated and secured.&lt;br /&gt;
# Open the sensor service in LightBlue.&lt;br /&gt;
# Locate the temperature and humidity characteristics.&lt;br /&gt;
# Enable notifications for the characteristics.&lt;br /&gt;
# Observe the temperature and humidity values received from the ESP32.&lt;br /&gt;
# Compare the displayed values with the DHT11 readings shown in the Serial Monitor.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor displays information similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smartphone ===&lt;br /&gt;
&lt;br /&gt;
The LightBlue application should show:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Example Observation&lt;br /&gt;
|-&lt;br /&gt;
| BLE Device&lt;br /&gt;
| ESP32-Secure-Sensor&lt;br /&gt;
|-&lt;br /&gt;
| BLE Service&lt;br /&gt;
| Sensor Service&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| 61.00 %&lt;br /&gt;
|-&lt;br /&gt;
| Authentication&lt;br /&gt;
| Successful&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Secure BLE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual temperature and humidity values will depend on the environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32, and temperature and humidity data were transmitted to a smartphone using Bluetooth Low Energy. BLE pairing and security mechanisms were configured to authenticate the smartphone and establish a protected communication link. The sensor values were successfully observed using the LightBlue BLE application.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The BLE passkey used in this experiment is intended for educational demonstration.&lt;br /&gt;
* A fixed passkey such as `123456` should not be used in a real security-sensitive product.&lt;br /&gt;
* Production IoT systems should use appropriate device-specific credentials and security policies.&lt;br /&gt;
* Secure Connections and MITM protection improve the security of BLE pairing, but the overall security of an IoT product also depends on its firmware, credential management and application design.&lt;br /&gt;
* The experiment demonstrates BLE link security; it should not be interpreted as complete end-to-end IoT security.&lt;br /&gt;
* The LightBlue application is being used as a BLE debugging/client tool rather than as a custom end-user IoT application.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE stands for Bluetooth Low Energy. It is a wireless communication technology designed for low-power communication between devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Why is BLE suitable for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE provides short-range wireless communication with relatively low power consumption, making it suitable for sensors and other IoT devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. What is GATT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
GATT stands for Generic Attribute Profile. It defines how BLE devices organize and exchange application data using services and characteristics.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is a BLE service?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A service is a collection of related BLE characteristics that represents a particular function of the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is a BLE characteristic?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A characteristic represents a specific piece of data or functionality and can support operations such as read, write and notify.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is pairing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pairing is the process of establishing security information between two Bluetooth devices so that a secure relationship can be created.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What is BLE encryption?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE encryption protects data exchanged over an established secure BLE connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is a passkey used for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A passkey is used as part of the authentication process during BLE pairing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is MITM protection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MITM stands for Man-in-the-Middle. MITM protection helps prevent an attacker from impersonating one of the devices during the authentication process.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What is bonding?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bonding is the process of storing security information after pairing so that the devices can establish trusted connections again later.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why is LightBlue used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LightBlue provides a convenient BLE client interface for discovering the ESP32, connecting to it, inspecting services and characteristics, and receiving notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Can the same application be used on Android and iOS?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. LightBlue is available for both Android and iOS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the role of the ESP32 in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the DHT11 sensor and acts as a BLE GATT server that provides the sensor data to the smartphone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is the difference between `READ` and `NOTIFY` in BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
`READ` allows the client to request the current value. `NOTIFY` allows the server to send updated values automatically when the client subscribes to notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. How is this experiment different from HTTPS-based cloud communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS protects communication between an IoT device and a web/cloud server over a network. This experiment demonstrates secure short-range BLE communication directly between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates how Bluetooth Low Energy can be used for secure IoT sensor-data transmission. The ESP32 reads temperature and humidity from the DHT11 sensor and exposes the readings through BLE characteristics. The smartphone connects using the LightBlue application, performs secure pairing, and receives the sensor data through an authenticated and encrypted BLE connection.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1357</id>
		<title>AIDS IoT Kits User Manuals</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1357"/>
		<updated>2026-10-07T12:11:43Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Laboratory Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sppu-logo.jpg|200px|SPPU Logo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:200%; font-weight:bold;&amp;quot;&amp;gt;TE AIDS MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:120%;&amp;quot;&amp;gt;Cognifront IoT Kit for MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About the Laboratory ==&lt;br /&gt;
&lt;br /&gt;
The Internet of Things (IoT) laboratory provides hands-on experience in connecting physical devices, sensors, microcontrollers and cloud platforms to develop intelligent, connected systems.&lt;br /&gt;
&lt;br /&gt;
This laboratory manual is designed for students of Third Year B.E. Artificial Intelligence and Data Science Engineering, covering fundamental IoT concepts, embedded programming, sensor interfacing, network communication and cloud-based applications.&lt;br /&gt;
&lt;br /&gt;
== Laboratory Objectives ==&lt;br /&gt;
&lt;br /&gt;
* Understand the architecture and fundamental concepts of the Internet of Things.&lt;br /&gt;
* Interface sensors and actuators with embedded development boards.&lt;br /&gt;
* Develop programs for acquiring and processing sensor data.&lt;br /&gt;
* Implement communication protocols used in IoT systems.&lt;br /&gt;
* Connect IoT devices with cloud platforms for data visualization and monitoring.&lt;br /&gt;
* Design and implement real-world IoT applications.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #&lt;br /&gt;
! Experiment Title&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part A&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| [[MDM331AID/Experiment 1|Develop an application for the connectivity of the Arduino UNO/Raspberry Pi circuit with sensors.]]&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[MDM331AID/Experiment 2|Implement an application to detect obstacles and notify users using LEDs to understand the connectivity of Raspberry Pi / Arduino with IR sensor.]]&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| [[MDM331AID/Experiment 3|Implement a simple IoT application using an Arduino board to control an LED through GPIO pins in order to understand the physical design of IoT devices and device actuation.]]&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| [[MDM331AID/Experiment 4|Develop a program to detect gas leakage in the surrounding environment.]]&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| [[MDM331AID/Experiment 5|Configure and implement an IoT device (Arduino UNO/ESP module/Raspberry Pi) to connect to a Wi-Fi network and transmit sensor data to a remote computer using TCP/IP communication.]]&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| [[MDM331AID/Experiment 6|Implement an edge computing model where sensor data is processed locally on an edge device (Raspberry Pi) before being transmitted to the cloud to reduce latency and bandwidth usage.]]&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[MDM331AID/Experiment 7|Design an RFID-based identification system that reads tag information and displays the ID on a monitoring system to demonstrate short-range communication technologies in IoT.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part B&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| [[MDM331AID/Experiment 8|Develop an IoT application that uses a communication protocol to transmit sensor data between an IoT device and a server.]]&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| [[MDM331AID/Experiment 9|Perform data cleaning, normalization, and visualization on an IoT sensor dataset (any dataset can be considered).]]&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| [[MDM331AID/Experiment 10|Implement an IoT application to collect real-time temperature data using an IoT sensor and apply a machine learning model to predict future temperature values (any machine learning model).]]&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| [[MDM331AID/Experiment 11|Design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts (any security algorithm can be used).]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/1&lt;br /&gt;
| [[MDM331AID/Experiment 12_BLE|(BLE)Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/2&lt;br /&gt;
| [[MDM331AID/Experiment 12_ESPNOW|(ESPNOW) Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| [[MDM331AID/Experiment 13|Develop and implement a machine learning model to perform classification (e.g., activity recognition or device state detection) and anomaly detection (e.g., fault detection in industrial IoT sensors).]]&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| [[MDM331AID/Experiment 14|Case study for data minimization using smart threshold alerts by providing Privacy-by-Design.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part C&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| [[MDM331AID/Experiment 15|Develop a Privacy-Aware Intelligent Smart IoT Application: Design and implementation of an AIoT-based smart sensor system with cloud-based data preprocessing and intelligent decision-making using machine learning techniques, incorporating secure communication protocols with built-in security and privacy mechanisms, with complete deliverables including a working demonstration and technical report.]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1356</id>
		<title>AIDS IoT Kits User Manuals</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=AIDS_IoT_Kits_User_Manuals&amp;diff=1356"/>
		<updated>2026-10-07T12:10:47Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Laboratory Objectives */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Sppu-logo.jpg|200px|SPPU Logo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:200%; font-weight:bold;&amp;quot;&amp;gt;TE AIDS MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:120%;&amp;quot;&amp;gt;Cognifront IoT Kit for MDM331AID : Internet of Things Lab&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== About the Laboratory ==&lt;br /&gt;
&lt;br /&gt;
The Internet of Things (IoT) laboratory provides hands-on experience in connecting physical devices, sensors, microcontrollers and cloud platforms to develop intelligent, connected systems.&lt;br /&gt;
&lt;br /&gt;
This laboratory manual is designed for students of Third Year B.E. Artificial Intelligence and Data Science Engineering, covering fundamental IoT concepts, embedded programming, sensor interfacing, network communication and cloud-based applications.&lt;br /&gt;
&lt;br /&gt;
== Laboratory Objectives ==&lt;br /&gt;
&lt;br /&gt;
* Understand the architecture and fundamental concepts of the Internet of Things.&lt;br /&gt;
* Interface sensors and actuators with embedded development boards.&lt;br /&gt;
* Develop programs for acquiring and processing sensor data.&lt;br /&gt;
* Implement communication protocols used in IoT systems.&lt;br /&gt;
* Connect IoT devices with cloud platforms for data visualization and monitoring.&lt;br /&gt;
* Design and implement real-world IoT applications.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! #&lt;br /&gt;
! Experiment Title&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part A&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| [[MDM331AID/Experiment 1|Develop an application for the connectivity of the Arduino UNO/Raspberry Pi circuit with sensors.]]&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[MDM331AID/Experiment 2|Implement an application to detect obstacles and notify users using LEDs to understand the connectivity of Raspberry Pi / Arduino with IR sensor.]]&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| [[MDM331AID/Experiment 3|Implement a simple IoT application using an Arduino board to control an LED through GPIO pins in order to understand the physical design of IoT devices and device actuation.]]&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| [[MDM331AID/Experiment 4|Develop a program to detect gas leakage in the surrounding environment.]]&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| [[MDM331AID/Experiment 5|Configure and implement an IoT device (Arduino UNO/ESP module/Raspberry Pi) to connect to a Wi-Fi network and transmit sensor data to a remote computer using TCP/IP communication.]]&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| [[MDM331AID/Experiment 6|Implement an edge computing model where sensor data is processed locally on an edge device (Raspberry Pi) before being transmitted to the cloud to reduce latency and bandwidth usage.]]&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[MDM331AID/Experiment 7|Design an RFID-based identification system that reads tag information and displays the ID on a monitoring system to demonstrate short-range communication technologies in IoT.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part B&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| [[MDM331AID/Experiment 8|Develop an IoT application that uses a communication protocol to transmit sensor data between an IoT device and a server.]]&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| [[MDM331AID/Experiment 9|Perform data cleaning, normalization, and visualization on an IoT sensor dataset (any dataset can be considered).]]&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| [[MDM331AID/Experiment 10|Implement an IoT application to collect real-time temperature data using an IoT sensor and apply a machine learning model to predict future temperature values (any machine learning model).]]&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| [[MDM331AID/Experiment 11|Design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts (any security algorithm can be used).]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/1&lt;br /&gt;
| [[MDM331AID/Experiment 12|(BLE)Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 12/2&lt;br /&gt;
| [[MDM331AID/Experiment 12|(ESPNOW) Implement secure data transmission in an IoT system using a sensor and any communication security protocol.]]&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| [[MDM331AID/Experiment 13|Develop and implement a machine learning model to perform classification (e.g., activity recognition or device state detection) and anomaly detection (e.g., fault detection in industrial IoT sensors).]]&lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| [[MDM331AID/Experiment 14|Case study for data minimization using smart threshold alerts by providing Privacy-by-Design.]]&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; | Part C&lt;br /&gt;
|-&lt;br /&gt;
| 15&lt;br /&gt;
| [[MDM331AID/Experiment 15|Develop a Privacy-Aware Intelligent Smart IoT Application: Design and implementation of an AIoT-based smart sensor system with cloud-based data preprocessing and intelligent decision-making using machine learning techniques, incorporating secure communication protocols with built-in security and privacy mechanisms, with complete deliverables including a working demonstration and technical report.]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12&amp;diff=1355</id>
		<title>MDM331AID/Experiment 12</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_12&amp;diff=1355"/>
		<updated>2026-10-07T12:05:47Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =  == Aim ==  To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.  == Objectives ==  * To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems. * To interface a DHT11 temperature and humidity sensor with an ESP32....&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Secure Sensor Data Transmission Using Bluetooth Low Energy =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
&lt;br /&gt;
To implement secure transmission of temperature and humidity data from an IoT sensor using Bluetooth Low Energy (BLE) and demonstrate authenticated and encrypted communication between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
* To understand the concept of Bluetooth Low Energy (BLE) communication in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To configure the ESP32 as a BLE server.&lt;br /&gt;
* To transmit real-time sensor data from the ESP32 to a smartphone using BLE.&lt;br /&gt;
* To understand BLE services and characteristics.&lt;br /&gt;
* To implement BLE pairing and authentication using a passkey.&lt;br /&gt;
* To understand how BLE encryption protects transmitted sensor data.&lt;br /&gt;
* To verify secure sensor-data communication using a smartphone BLE application.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 80%;&amp;quot;&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 Development Board&lt;br /&gt;
| 1&lt;br /&gt;
| IoT controller and BLE server&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 Sensor&lt;br /&gt;
| 1&lt;br /&gt;
| Measures temperature and humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB Cable&lt;br /&gt;
| 1&lt;br /&gt;
| Programming and power supply&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jumper Wires&lt;br /&gt;
| As required&lt;br /&gt;
| Electrical connections&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Smartphone&lt;br /&gt;
| 1&lt;br /&gt;
| BLE client for receiving sensor data&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| LightBlue® BLE Application&lt;br /&gt;
| 1&lt;br /&gt;
| Scanning, connecting and monitoring BLE data&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 programming&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Smartphone Application ===&lt;br /&gt;
&lt;br /&gt;
The recommended application for this experiment is **LightBlue® by Punch Through**.&lt;br /&gt;
&lt;br /&gt;
LightBlue is a BLE debugging and development application that is available for both Android and iOS. It can scan for BLE peripherals, connect to them, display their services and characteristics, and read or subscribe to characteristic values.&lt;br /&gt;
&lt;br /&gt;
The application can be installed from:&lt;br /&gt;
&lt;br /&gt;
* Android: [LightBlue® on Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
* iPhone/iPad: [LightBlue® on the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth Low Energy ===&lt;br /&gt;
&lt;br /&gt;
Bluetooth Low Energy (BLE) is a wireless communication technology designed for low-power communication between devices. It is widely used in IoT sensors, wearable devices, smart-home devices and other embedded systems.&lt;br /&gt;
&lt;br /&gt;
An ESP32 can operate as a BLE device and communicate with smartphones and other BLE-enabled devices. The Arduino ESP32 framework provides a BLE library for creating BLE servers, services and characteristics.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 operates as a &#039;&#039;&#039;BLE GATT server&#039;&#039;&#039;, while the smartphone operates as the &#039;&#039;&#039;BLE client&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The communication structure is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
     ↓&lt;br /&gt;
   ESP32&lt;br /&gt;
     ↓&lt;br /&gt;
 BLE GATT Server&lt;br /&gt;
     ↓&lt;br /&gt;
 Secure BLE Connection&lt;br /&gt;
     ↓&lt;br /&gt;
 Smartphone&lt;br /&gt;
     ↓&lt;br /&gt;
 LightBlue Application&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== BLE GATT ===&lt;br /&gt;
&lt;br /&gt;
BLE devices commonly organize application data using the Generic Attribute Profile (GATT).&lt;br /&gt;
&lt;br /&gt;
The main components used in this experiment are:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Service:&#039;&#039;&#039;  &lt;br /&gt;
A service groups related functionality of a BLE device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Characteristic:&#039;&#039;&#039;  &lt;br /&gt;
A characteristic contains a particular piece of data that can be read, written or notified.&lt;br /&gt;
&lt;br /&gt;
For this experiment, one BLE service is created containing two characteristics:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Characteristic&lt;br /&gt;
! Data&lt;br /&gt;
! Operation&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature in °C&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity in %&lt;br /&gt;
| Read / Notify&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The smartphone can connect to the ESP32 and subscribe to notifications so that updated sensor values are received automatically.&lt;br /&gt;
&lt;br /&gt;
=== BLE Security ===&lt;br /&gt;
&lt;br /&gt;
BLE provides security mechanisms for authentication, pairing, bonding and encrypted communication.&lt;br /&gt;
&lt;br /&gt;
In this experiment, BLE security is configured using:&lt;br /&gt;
&lt;br /&gt;
* Pairing&lt;br /&gt;
* Bonding&lt;br /&gt;
* MITM (Man-in-the-Middle) protection&lt;br /&gt;
* Secure Connections&lt;br /&gt;
* Passkey authentication&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s ESP32 BLE security documentation supports authentication modes combining bonding, MITM protection and Secure Connections.&lt;br /&gt;
&lt;br /&gt;
=== Pairing ===&lt;br /&gt;
&lt;br /&gt;
Pairing is the process by which two Bluetooth devices establish the information required to create a trusted secure relationship.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the smartphone and ESP32 are paired using a passkey.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32&lt;br /&gt;
  ↓&lt;br /&gt;
BLE connection request&lt;br /&gt;
  ↓&lt;br /&gt;
Pairing request&lt;br /&gt;
  ↓&lt;br /&gt;
Passkey authentication&lt;br /&gt;
  ↓&lt;br /&gt;
Secure key establishment&lt;br /&gt;
  ↓&lt;br /&gt;
Encrypted BLE communication&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bonding ===&lt;br /&gt;
&lt;br /&gt;
Bonding allows the security information established during pairing to be stored so that the devices can recognize each other during future connections.&lt;br /&gt;
&lt;br /&gt;
Espressif distinguishes bonding from encryption: bonding stores long-term keys after successful encryption, while encryption protects the communication link.&lt;br /&gt;
&lt;br /&gt;
=== BLE Encryption ===&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE link can be encrypted.&lt;br /&gt;
&lt;br /&gt;
Therefore, the sensor data transmitted over the BLE connection is protected from simple interception of the communication.&lt;br /&gt;
&lt;br /&gt;
The security flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Sensor Data&lt;br /&gt;
    ↓&lt;br /&gt;
BLE Security / Pairing&lt;br /&gt;
    ↓&lt;br /&gt;
Authentication&lt;br /&gt;
    ↓&lt;br /&gt;
Encryption&lt;br /&gt;
    ↓&lt;br /&gt;
Secure BLE Transmission&lt;br /&gt;
    ↓&lt;br /&gt;
Smartphone&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
=== DHT11 to ESP32 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital sensor data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              +----------------+&lt;br /&gt;
              |     DHT11      |&lt;br /&gt;
              |                |&lt;br /&gt;
              | VCC  DATA  GND |&lt;br /&gt;
              +--+----+-----+--+&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                3.3V GPIO4 GND&lt;br /&gt;
                 |    |     |&lt;br /&gt;
                 |    |     |&lt;br /&gt;
          +------+----+-----+------+&lt;br /&gt;
          |          ESP32         |&lt;br /&gt;
          |                        |&lt;br /&gt;
          |       BLE Server       |&lt;br /&gt;
          |          ))))          |&lt;br /&gt;
          +------------))----------+&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                Secure BLE Link&lt;br /&gt;
                       ))&lt;br /&gt;
                       ))&lt;br /&gt;
                 +-----------+&lt;br /&gt;
                 | Smartphone|&lt;br /&gt;
                 |           |&lt;br /&gt;
                 | LightBlue |&lt;br /&gt;
                 +-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
=== Arduino Program ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;amp;lt;Arduino.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEServer.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLEUtils.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;&lt;br /&gt;
#include &amp;amp;lt;DHT.h&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define DHTPIN 4&lt;br /&gt;
#define DHTTYPE DHT11&lt;br /&gt;
&lt;br /&gt;
#define DEVICE_NAME &amp;quot;ESP32-Secure-Sensor&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define SERVICE_UUID \&lt;br /&gt;
&amp;quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define TEMP_UUID \&lt;br /&gt;
&amp;quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define HUMIDITY_UUID \&lt;br /&gt;
&amp;quot;cba1d466-344c-4be3-ab3f-189f80dd7518&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define BLE_PASSKEY 123456&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHTPIN, DHTTYPE);&lt;br /&gt;
&lt;br /&gt;
BLECharacteristic *temperatureCharacteristic;&lt;br /&gt;
BLECharacteristic *humidityCharacteristic;&lt;br /&gt;
&lt;br /&gt;
class SecurityCallbacks : public BLESecurityCallbacks&lt;br /&gt;
{&lt;br /&gt;
  uint32_t onPassKeyRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Passkey requested&amp;quot;);&lt;br /&gt;
    return BLE_PASSKEY;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onPassKeyNotify(uint32_t passkey)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Passkey: &amp;quot;);&lt;br /&gt;
    Serial.println(passkey);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onConfirmPIN(uint32_t pin)&lt;br /&gt;
  {&lt;br /&gt;
    Serial.print(&amp;quot;Confirm PIN: &amp;quot;);&lt;br /&gt;
    Serial.println(pin);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  bool onSecurityRequest()&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;Security request received&amp;quot;);&lt;br /&gt;
    return true;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  void onAuthenticationComplete(esp_ble_auth_cmpl_t desc)&lt;br /&gt;
  {&lt;br /&gt;
    if (desc.success)&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication successful&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      Serial.println(&amp;quot;BLE authentication failed&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
  dht.begin();&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::init(DEVICE_NAME);&lt;br /&gt;
&lt;br /&gt;
  BLESecurity *security = new BLESecurity();&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setPassKey(true, BLE_PASSKEY);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setCapability(ESP_IO_CAP_OUT);&lt;br /&gt;
&lt;br /&gt;
  security-&amp;gt;setAuthenticationMode(&lt;br /&gt;
    true,   // Bonding&lt;br /&gt;
    true,   // MITM protection&lt;br /&gt;
    true    // Secure Connections&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::setSecurityCallbacks(&lt;br /&gt;
    new SecurityCallbacks()&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  BLEServer *server = BLEDevice::createServer();&lt;br /&gt;
&lt;br /&gt;
  BLEService *service =&lt;br /&gt;
    server-&amp;gt;createService(SERVICE_UUID);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      TEMP_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic =&lt;br /&gt;
    service-&amp;gt;createCharacteristic(&lt;br /&gt;
      HUMIDITY_UUID,&lt;br /&gt;
      BLECharacteristic::PROPERTY_READ |&lt;br /&gt;
      BLECharacteristic::PROPERTY_NOTIFY&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&amp;quot;0.0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  service-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
  BLEAdvertising *advertising =&lt;br /&gt;
    BLEDevice::getAdvertising();&lt;br /&gt;
&lt;br /&gt;
  advertising-&amp;gt;addServiceUUID(SERVICE_UUID);&lt;br /&gt;
  advertising-&amp;gt;setScanResponse(true);&lt;br /&gt;
&lt;br /&gt;
  BLEDevice::startAdvertising();&lt;br /&gt;
&lt;br /&gt;
  Serial.println();&lt;br /&gt;
  Serial.println(&amp;quot;Secure BLE Sensor Started&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Device Name: ESP32-Secure-Sensor&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Passkey: 123456&amp;quot;);&lt;br /&gt;
  Serial.println(&amp;quot;Waiting for BLE connection...&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  float temperature = dht.readTemperature();&lt;br /&gt;
  float humidity = dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
  if (isnan(temperature) || isnan(humidity))&lt;br /&gt;
  {&lt;br /&gt;
    Serial.println(&amp;quot;DHT11 reading failed&amp;quot;);&lt;br /&gt;
    delay(2000);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  char temperatureValue[10];&lt;br /&gt;
  char humidityValue[10];&lt;br /&gt;
&lt;br /&gt;
  dtostrf(temperature, 1, 2, temperatureValue);&lt;br /&gt;
  dtostrf(humidity, 1, 2, humidityValue);&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    temperatureValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  humidityCharacteristic-&amp;gt;setValue(&lt;br /&gt;
    humidityValue&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
  temperatureCharacteristic-&amp;gt;notify();&lt;br /&gt;
  humidityCharacteristic-&amp;gt;notify();&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
  Serial.print(temperature);&lt;br /&gt;
  Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;Humidity: &amp;quot;);&lt;br /&gt;
  Serial.print(humidity);&lt;br /&gt;
  Serial.println(&amp;quot; %&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  Serial.println(&amp;quot;Sensor data sent using secure BLE&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code&lt;br /&gt;
! Explanation&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEDevice.h&amp;amp;gt;`&lt;br /&gt;
| Provides the main BLE device functionality.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLEServer.h&amp;amp;gt;`&lt;br /&gt;
| Provides functionality for creating a BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;BLESecurity.h&amp;amp;gt;`&lt;br /&gt;
| Provides BLE pairing and security configuration.&lt;br /&gt;
|-&lt;br /&gt;
| `#include &amp;amp;lt;DHT.h&amp;amp;gt;`&lt;br /&gt;
| Provides functions for interfacing with the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `DHTPIN 4`&lt;br /&gt;
| Defines GPIO 4 as the DHT11 data pin.&lt;br /&gt;
|-&lt;br /&gt;
| `DEVICE_NAME`&lt;br /&gt;
| Defines the name advertised by the ESP32.&lt;br /&gt;
|-&lt;br /&gt;
| `SERVICE_UUID`&lt;br /&gt;
| Uniquely identifies the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `TEMP_UUID`&lt;br /&gt;
| Identifies the temperature characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `HUMIDITY_UUID`&lt;br /&gt;
| Identifies the humidity characteristic.&lt;br /&gt;
|-&lt;br /&gt;
| `BLE_PASSKEY 123456`&lt;br /&gt;
| Defines the passkey used for BLE authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.begin()`&lt;br /&gt;
| Initializes the DHT11 sensor.&lt;br /&gt;
|-&lt;br /&gt;
| `BLEDevice::init()`&lt;br /&gt;
| Initializes BLE and assigns the device name.&lt;br /&gt;
|-&lt;br /&gt;
| `setPassKey()`&lt;br /&gt;
| Configures the BLE passkey.&lt;br /&gt;
|-&lt;br /&gt;
| `setCapability()`&lt;br /&gt;
| Defines the input/output capability used during authentication.&lt;br /&gt;
|-&lt;br /&gt;
| `setAuthenticationMode(true, true, true)`&lt;br /&gt;
| Enables bonding, MITM protection and Secure Connections.&lt;br /&gt;
|-&lt;br /&gt;
| `createServer()`&lt;br /&gt;
| Creates the ESP32 BLE server.&lt;br /&gt;
|-&lt;br /&gt;
| `createService()`&lt;br /&gt;
| Creates the BLE sensor service.&lt;br /&gt;
|-&lt;br /&gt;
| `createCharacteristic()`&lt;br /&gt;
| Creates temperature and humidity characteristics.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_READ`&lt;br /&gt;
| Allows the smartphone to read the sensor value.&lt;br /&gt;
|-&lt;br /&gt;
| `PROPERTY_NOTIFY`&lt;br /&gt;
| Allows the ESP32 to send updated sensor values to the smartphone.&lt;br /&gt;
|-&lt;br /&gt;
| `service-&amp;gt;start()`&lt;br /&gt;
| Starts the BLE service.&lt;br /&gt;
|-&lt;br /&gt;
| `startAdvertising()`&lt;br /&gt;
| Makes the ESP32 discoverable by BLE clients.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readTemperature()`&lt;br /&gt;
| Reads temperature from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `dht.readHumidity()`&lt;br /&gt;
| Reads humidity from the DHT11.&lt;br /&gt;
|-&lt;br /&gt;
| `setValue()`&lt;br /&gt;
| Updates the BLE characteristic value.&lt;br /&gt;
|-&lt;br /&gt;
| `notify()`&lt;br /&gt;
| Sends the updated value to subscribed BLE clients.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Security Configuration ==&lt;br /&gt;
&lt;br /&gt;
The following security settings are used in the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Security Feature&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Passkey&lt;br /&gt;
| Provides authentication during pairing.&lt;br /&gt;
|-&lt;br /&gt;
| MITM Protection&lt;br /&gt;
| Provides protection against certain man-in-the-middle attacks during authenticated pairing.&lt;br /&gt;
|-&lt;br /&gt;
| Secure Connections&lt;br /&gt;
| Uses the BLE Secure Connections pairing mechanism.&lt;br /&gt;
|-&lt;br /&gt;
| Bonding&lt;br /&gt;
| Allows security information to be retained for future connections.&lt;br /&gt;
|-&lt;br /&gt;
| Encryption&lt;br /&gt;
| Protects data transmitted over the established BLE link.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Espressif documents BLE security configurations including bonding, MITM protection and Secure Connections, and provides dedicated BLE security examples.&lt;br /&gt;
&lt;br /&gt;
== Smartphone Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Step 1: Install LightBlue ===&lt;br /&gt;
&lt;br /&gt;
Install &#039;&#039;&#039;LightBlue® by Punch Through&#039;&#039;&#039; on the smartphone.&lt;br /&gt;
&lt;br /&gt;
For Android:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from Google Play](https://play.google.com/store/apps/details?hl=en&amp;amp;id=com.punchthrough.lightblueexplorer&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
For iPhone/iPad:&lt;br /&gt;
&lt;br /&gt;
[Download LightBlue from the App Store](https://apps.apple.com/in/app/lightblue/id557428110?platform=vision&amp;amp;utm_source=chatgpt.com)&lt;br /&gt;
&lt;br /&gt;
The same application is available on both platforms.&lt;br /&gt;
&lt;br /&gt;
=== Step 2: Upload the Program ===&lt;br /&gt;
&lt;br /&gt;
1. Connect the ESP32 to the computer using the USB cable.&lt;br /&gt;
2. Open Arduino IDE.&lt;br /&gt;
3. Select the appropriate ESP32 board.&lt;br /&gt;
4. Select the correct COM port.&lt;br /&gt;
5. Upload the program.&lt;br /&gt;
6. Open the Serial Monitor at &#039;&#039;&#039;115200 baud&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor should display:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Step 3: Start LightBlue ===&lt;br /&gt;
&lt;br /&gt;
1. Enable Bluetooth on the smartphone.&lt;br /&gt;
2. Open the LightBlue application.&lt;br /&gt;
3. Allow the required Bluetooth permissions.&lt;br /&gt;
4. Start scanning for nearby BLE devices.&lt;br /&gt;
5. Locate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
6. Select the device and tap &#039;&#039;&#039;Connect&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
LightBlue supports BLE scanning, connection, service/characteristic inspection, reading, writing and notifications.&lt;br /&gt;
&lt;br /&gt;
=== Step 4: Pair the Device ===&lt;br /&gt;
&lt;br /&gt;
When the ESP32 requests secure pairing, the smartphone will display the BLE pairing/passkey interaction.&lt;br /&gt;
&lt;br /&gt;
Enter or confirm:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
123456&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication, the BLE connection becomes secured.&lt;br /&gt;
&lt;br /&gt;
Espressif&#039;s BLE documentation demonstrates pairing between an ESP32 BLE server and a mobile phone using LightBlue, including passkey-based pairing.&lt;br /&gt;
&lt;br /&gt;
=== Step 5: View Sensor Data ===&lt;br /&gt;
&lt;br /&gt;
After connecting, LightBlue displays the BLE service and its characteristics.&lt;br /&gt;
&lt;br /&gt;
The structure will be similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ESP32-Secure-Sensor&lt;br /&gt;
&lt;br /&gt;
Service&lt;br /&gt;
└── Sensor Service&lt;br /&gt;
      │&lt;br /&gt;
      ├── Temperature&lt;br /&gt;
      │      Value: 27.40&lt;br /&gt;
      │&lt;br /&gt;
      └── Humidity&lt;br /&gt;
             Value: 61.00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact appearance of the LightBlue interface may vary between Android and iOS versions.&lt;br /&gt;
&lt;br /&gt;
=== Step 6: Enable Notifications ===&lt;br /&gt;
&lt;br /&gt;
The temperature and humidity characteristics support notifications.&lt;br /&gt;
&lt;br /&gt;
Enable notifications for the characteristics in LightBlue.&lt;br /&gt;
&lt;br /&gt;
The ESP32 will then periodically send updated sensor readings.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 62.00 %&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Data Flow ==&lt;br /&gt;
&lt;br /&gt;
The complete data flow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
             DHT11 Sensor&lt;br /&gt;
                  ↓&lt;br /&gt;
          Temperature / Humidity&lt;br /&gt;
                  ↓&lt;br /&gt;
                ESP32&lt;br /&gt;
                  ↓&lt;br /&gt;
            BLE GATT Server&lt;br /&gt;
                  ↓&lt;br /&gt;
       BLE Pairing &amp;amp; Authentication&lt;br /&gt;
                  ↓&lt;br /&gt;
          Encrypted BLE Link&lt;br /&gt;
                  ↓&lt;br /&gt;
             Smartphone&lt;br /&gt;
                  ↓&lt;br /&gt;
           LightBlue Application&lt;br /&gt;
                  ↓&lt;br /&gt;
       Temperature / Humidity Data&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the given pin connections.&lt;br /&gt;
# Install the DHT sensor library in Arduino IDE if required.&lt;br /&gt;
# Install the ESP32 board package in Arduino IDE.&lt;br /&gt;
# Install the LightBlue BLE application on an Android or iOS smartphone.&lt;br /&gt;
# Enter the BLE program into Arduino IDE.&lt;br /&gt;
# Connect the ESP32 to the computer.&lt;br /&gt;
# Select the correct ESP32 board and COM port.&lt;br /&gt;
# Upload the program.&lt;br /&gt;
# Open the Serial Monitor at 115200 baud.&lt;br /&gt;
# Verify that the ESP32 starts BLE advertising.&lt;br /&gt;
# Open LightBlue on the smartphone.&lt;br /&gt;
# Scan for nearby BLE devices.&lt;br /&gt;
# Select `ESP32-Secure-Sensor`.&lt;br /&gt;
# Establish the BLE connection.&lt;br /&gt;
# Complete the passkey authentication using `123456`.&lt;br /&gt;
# Verify that the BLE connection is authenticated and secured.&lt;br /&gt;
# Open the sensor service in LightBlue.&lt;br /&gt;
# Locate the temperature and humidity characteristics.&lt;br /&gt;
# Enable notifications for the characteristics.&lt;br /&gt;
# Observe the temperature and humidity values received from the ESP32.&lt;br /&gt;
# Compare the displayed values with the DHT11 readings shown in the Serial Monitor.&lt;br /&gt;
# Record the observed values.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Serial Monitor ===&lt;br /&gt;
&lt;br /&gt;
The Serial Monitor displays information similar to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Secure BLE Sensor Started&lt;br /&gt;
Device Name: ESP32-Secure-Sensor&lt;br /&gt;
Passkey: 123456&lt;br /&gt;
Waiting for BLE connection...&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.40 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.50 °C&lt;br /&gt;
Humidity: 61.00 %&lt;br /&gt;
Sensor data sent using secure BLE&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Smartphone ===&lt;br /&gt;
&lt;br /&gt;
The LightBlue application should show:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Parameter&lt;br /&gt;
! Example Observation&lt;br /&gt;
|-&lt;br /&gt;
| BLE Device&lt;br /&gt;
| ESP32-Secure-Sensor&lt;br /&gt;
|-&lt;br /&gt;
| BLE Service&lt;br /&gt;
| Sensor Service&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| 27.40 °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| 61.00 %&lt;br /&gt;
|-&lt;br /&gt;
| Authentication&lt;br /&gt;
| Successful&lt;br /&gt;
|-&lt;br /&gt;
| Communication&lt;br /&gt;
| Secure BLE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual temperature and humidity values will depend on the environmental conditions.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor was successfully interfaced with the ESP32, and temperature and humidity data were transmitted to a smartphone using Bluetooth Low Energy. BLE pairing and security mechanisms were configured to authenticate the smartphone and establish a protected communication link. The sensor values were successfully observed using the LightBlue BLE application.&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
* The BLE passkey used in this experiment is intended for educational demonstration.&lt;br /&gt;
* A fixed passkey such as `123456` should not be used in a real security-sensitive product.&lt;br /&gt;
* Production IoT systems should use appropriate device-specific credentials and security policies.&lt;br /&gt;
* Secure Connections and MITM protection improve the security of BLE pairing, but the overall security of an IoT product also depends on its firmware, credential management and application design.&lt;br /&gt;
* The experiment demonstrates BLE link security; it should not be interpreted as complete end-to-end IoT security.&lt;br /&gt;
* The LightBlue application is being used as a BLE debugging/client tool rather than as a custom end-user IoT application.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q1. What is BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE stands for Bluetooth Low Energy. It is a wireless communication technology designed for low-power communication between devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q2. Why is BLE suitable for IoT applications?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE provides short-range wireless communication with relatively low power consumption, making it suitable for sensors and other IoT devices.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q3. What is GATT?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
GATT stands for Generic Attribute Profile. It defines how BLE devices organize and exchange application data using services and characteristics.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q4. What is a BLE service?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A service is a collection of related BLE characteristics that represents a particular function of the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q5. What is a BLE characteristic?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A characteristic represents a specific piece of data or functionality and can support operations such as read, write and notify.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q6. What is pairing?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pairing is the process of establishing security information between two Bluetooth devices so that a secure relationship can be created.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q7. What is BLE encryption?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
BLE encryption protects data exchanged over an established secure BLE connection.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q8. What is a passkey used for?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A passkey is used as part of the authentication process during BLE pairing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q9. What is MITM protection?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
MITM stands for Man-in-the-Middle. MITM protection helps prevent an attacker from impersonating one of the devices during the authentication process.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q10. What is bonding?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Bonding is the process of storing security information after pairing so that the devices can establish trusted connections again later.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q11. Why is LightBlue used in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LightBlue provides a convenient BLE client interface for discovering the ESP32, connecting to it, inspecting services and characteristics, and receiving notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q12. Can the same application be used on Android and iOS?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Yes. LightBlue is available for both Android and iOS.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q13. What is the role of the ESP32 in this experiment?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ESP32 reads the DHT11 sensor and acts as a BLE GATT server that provides the sensor data to the smartphone.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q14. What is the difference between `READ` and `NOTIFY` in BLE?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
`READ` allows the client to request the current value. `NOTIFY` allows the server to send updated values automatically when the client subscribes to notifications.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Q15. How is this experiment different from HTTPS-based cloud communication?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
HTTPS protects communication between an IoT device and a web/cloud server over a network. This experiment demonstrates secure short-range BLE communication directly between an ESP32 and a smartphone.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates how Bluetooth Low Energy can be used for secure IoT sensor-data transmission. The ESP32 reads temperature and humidity from the DHT11 sensor and exposes the readings through BLE characteristics. The smartphone connects using the LightBlue application, performs secure pairing, and receives the sensor data through an authenticated and encrypted BLE connection.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1354</id>
		<title>MDM331AID/Experiment 11</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_11&amp;diff=1354"/>
		<updated>2026-10-07T11:37:52Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Password-Protected Smart Sensor System =  == Aim == To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.  == Objectives == * To understand the importance of security in IoT systems. * To interface a DHT11 temperature and humidity sensor with an ESP32. * To connect the ESP32 to a Wi-Fi network. * To implement a web server on the ESP3...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Password-Protected Smart Sensor System =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To design and implement a password-protected smart sensor system that allows access to sensor data only after successful authentication, demonstrating basic IoT security concepts.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of security in IoT systems.&lt;br /&gt;
* To interface a DHT11 temperature and humidity sensor with an ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
* To implement a web server on the ESP32 for accessing sensor data.&lt;br /&gt;
* To implement password-based authentication for protecting sensor data.&lt;br /&gt;
* To use the SHA-256 hashing algorithm for secure password verification.&lt;br /&gt;
* To allow access to sensor data only after successful authentication.&lt;br /&gt;
* To demonstrate access denial when incorrect authentication credentials are provided.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi router / hotspot&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or smartphone with a web browser&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| DHT sensor library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| ESP32 Arduino core / Wi-Fi library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. Since IoT devices are often connected to networks, protecting their data and controlling access to the devices are important security requirements.&lt;br /&gt;
&lt;br /&gt;
An IoT security system should ensure that only authorized users can access protected sensor data or device functions. &#039;&#039;&#039;Authentication&#039;&#039;&#039; is the process of verifying the identity of a user or device before granting access to a protected resource.&lt;br /&gt;
&lt;br /&gt;
In this experiment, an ESP32 is connected to a DHT11 temperature and humidity sensor. The ESP32 connects to a Wi-Fi network and operates as a small web server. A user can access the ESP32 using a web browser by entering its IP address.&lt;br /&gt;
&lt;br /&gt;
The sensor data is not displayed immediately. The user must first provide valid authentication credentials. If authentication is successful, the ESP32 provides access to the sensor dashboard. If the credentials are incorrect, access to the sensor data is denied.&lt;br /&gt;
&lt;br /&gt;
The basic operation of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
  Web Server&lt;br /&gt;
      ↓&lt;br /&gt;
Authentication&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────┐&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Valid          Invalid&lt;br /&gt;
Password       Password&lt;br /&gt;
 │               │&lt;br /&gt;
 ↓               ↓&lt;br /&gt;
Sensor         Access&lt;br /&gt;
Data           Denied&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Password Authentication ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Password authentication&#039;&#039;&#039; is a method of verifying a user&#039;s identity by comparing credentials provided by the user with the credentials stored by the system.&lt;br /&gt;
&lt;br /&gt;
A simple implementation could directly compare the entered password with a stored password. However, storing passwords directly is not considered a good security practice.&lt;br /&gt;
&lt;br /&gt;
Instead, this experiment demonstrates &#039;&#039;&#039;password hashing&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== SHA-256 Hashing ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHA-256 (Secure Hash Algorithm 256-bit)&#039;&#039;&#039; is a cryptographic hash function that converts input data into a fixed-length 256-bit hash value, normally represented as a 64-character hexadecimal string.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Password&lt;br /&gt;
   ↓&lt;br /&gt;
SHA-256&lt;br /&gt;
   ↓&lt;br /&gt;
64-character hash&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The original password does not need to be stored directly. During authentication, the password entered by the user is hashed using SHA-256 and the resulting hash is compared with the stored hash.&lt;br /&gt;
&lt;br /&gt;
The authentication process is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
User enters password&lt;br /&gt;
        ↓&lt;br /&gt;
   SHA-256 Hash&lt;br /&gt;
        ↓&lt;br /&gt;
Compare with stored hash&lt;br /&gt;
        ↓&lt;br /&gt;
     Match?&lt;br /&gt;
     /     \&lt;br /&gt;
   Yes      No&lt;br /&gt;
   ↓         ↓&lt;br /&gt;
Allow      Deny&lt;br /&gt;
access     access&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the calculated hash matches the stored hash, the user is considered authenticated.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; SHA-256 is used in this experiment to demonstrate the basic concept of password hashing. A production IoT system should use stronger password-storage practices such as salted password hashing and should protect network communication using HTTPS/TLS.&lt;br /&gt;
&lt;br /&gt;
=== ESP32 Web Server ===&lt;br /&gt;
&lt;br /&gt;
The ESP32 contains built-in Wi-Fi capability and can operate as a web server. A web server listens for requests from a client such as a web browser and sends an appropriate response.&lt;br /&gt;
&lt;br /&gt;
In this experiment, the ESP32 provides:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Login page:&#039;&#039;&#039; Allows the user to enter authentication credentials.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Verifies the entered password.&lt;br /&gt;
* &#039;&#039;&#039;Sensor dashboard:&#039;&#039;&#039; Displays temperature and humidity after successful authentication.&lt;br /&gt;
* &#039;&#039;&#039;Access denial:&#039;&#039;&#039; Prevents unauthorized users from accessing the sensor data.&lt;br /&gt;
&lt;br /&gt;
The user can access the system using the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://192.168.1.105&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact IP address depends on the network to which the ESP32 is connected.&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are used to interface the DHT11 sensor with the ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the corresponding pin number is changed in the program.&lt;br /&gt;
&lt;br /&gt;
== Connection Diagram ==&lt;br /&gt;
&lt;br /&gt;
The DHT11 sensor is connected to the ESP32 according to the pin connection table. The ESP32 connects to the Wi-Fi network and hosts the authentication and sensor-data web pages.&lt;br /&gt;
&lt;br /&gt;
The overall connection is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
        DHT11&lt;br /&gt;
     ┌─────────┐&lt;br /&gt;
     │         │&lt;br /&gt;
VCC ─┤ VCC     │&lt;br /&gt;
3.3V │         │&lt;br /&gt;
     │ DATA ───────── GPIO 4&lt;br /&gt;
GND ─┤ GND     │&lt;br /&gt;
     └─────────┘&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
        ESP32&lt;br /&gt;
           │&lt;br /&gt;
         Wi-Fi&lt;br /&gt;
           │&lt;br /&gt;
           ↓&lt;br /&gt;
      Web Browser&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the &#039;&#039;&#039;DHT sensor library&#039;&#039;&#039; and the required ESP32 board support package using the Arduino IDE.&lt;br /&gt;
&lt;br /&gt;
The program creates a web server on the ESP32, reads temperature and humidity from the DHT11 and protects the sensor dashboard using password authentication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;lt;WiFi.h&amp;gt;&lt;br /&gt;
#include &amp;lt;WebServer.h&amp;gt;&lt;br /&gt;
#include &amp;lt;DHT.h&amp;gt;&lt;br /&gt;
#include &amp;quot;mbedtls/sha256.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
WebServer server(80);&lt;br /&gt;
&lt;br /&gt;
// Wi-Fi credentials&lt;br /&gt;
const char* ssid = &amp;quot;YOUR_WIFI_NAME&amp;quot;;&lt;br /&gt;
const char* password = &amp;quot;YOUR_WIFI_PASSWORD&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Login credentials&lt;br /&gt;
const char* username = &amp;quot;admin&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// SHA-256 hash of the password&lt;br /&gt;
// Password used for this experiment: admin123&lt;br /&gt;
const char* storedPasswordHash =&lt;br /&gt;
    &amp;quot;240be518fabd27242f2e4c59b8c9b0d9&amp;quot;&lt;br /&gt;
    &amp;quot;8f0f6f5e8a9a9b7e7b5f4f7f9a5d5e6f&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Authentication status&lt;br /&gt;
bool authenticated = false;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// SHA-256 function&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
String sha256(String input)&lt;br /&gt;
{&lt;br /&gt;
    byte hash[32];&lt;br /&gt;
&lt;br /&gt;
    mbedtls_sha256_context ctx;&lt;br /&gt;
&lt;br /&gt;
    mbedtls_sha256_init(&amp;amp;ctx);&lt;br /&gt;
    mbedtls_sha256_starts(&amp;amp;ctx, 0);&lt;br /&gt;
    mbedtls_sha256_update(&lt;br /&gt;
        &amp;amp;ctx,&lt;br /&gt;
        (const unsigned char*)input.c_str(),&lt;br /&gt;
        input.length()&lt;br /&gt;
    );&lt;br /&gt;
    mbedtls_sha256_finish(&amp;amp;ctx, hash);&lt;br /&gt;
    mbedtls_sha256_free(&amp;amp;ctx);&lt;br /&gt;
&lt;br /&gt;
    String result = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    for (int i = 0; i &amp;lt; 32; i++)&lt;br /&gt;
    {&lt;br /&gt;
        if (hash[i] &amp;lt; 16)&lt;br /&gt;
            result += &amp;quot;0&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        result += String(hash[i], HEX);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Login page&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void handleRoot()&lt;br /&gt;
{&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Smart Sensor System&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;form action=&#039;/login&#039; method=&#039;POST&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;Username:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;input type=&#039;text&#039; name=&#039;username&#039;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;Password:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;input type=&#039;password&#039; name=&#039;password&#039;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;input type=&#039;submit&#039; value=&#039;Login&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
        200,&lt;br /&gt;
        &amp;quot;text/html&amp;quot;,&lt;br /&gt;
        html&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Login authentication&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void handleLogin()&lt;br /&gt;
{&lt;br /&gt;
    String enteredUsername =&lt;br /&gt;
        server.arg(&amp;quot;username&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String enteredPassword =&lt;br /&gt;
        server.arg(&amp;quot;password&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    String enteredHash =&lt;br /&gt;
        sha256(enteredPassword);&lt;br /&gt;
&lt;br /&gt;
    if (&lt;br /&gt;
        enteredUsername == username &amp;amp;&amp;amp;&lt;br /&gt;
        enteredHash == storedPasswordHash&lt;br /&gt;
    )&lt;br /&gt;
    {&lt;br /&gt;
        authenticated = true;&lt;br /&gt;
&lt;br /&gt;
        server.sendHeader(&lt;br /&gt;
            &amp;quot;Location&amp;quot;,&lt;br /&gt;
            &amp;quot;/sensor&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        server.send(&lt;br /&gt;
            302,&lt;br /&gt;
            &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
            &amp;quot;Login successful&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        authenticated = false;&lt;br /&gt;
&lt;br /&gt;
        String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
        html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        html += &amp;quot;&amp;lt;h1&amp;gt;Access Denied&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        html += &amp;quot;&amp;lt;p&amp;gt;&amp;quot;;&lt;br /&gt;
        html += &amp;quot;Invalid username or password.&amp;quot;;&lt;br /&gt;
        html += &amp;quot;&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        html += &amp;quot;&amp;lt;a href=&#039;/&#039;&amp;gt;Try Again&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
        html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        server.send(&lt;br /&gt;
            401,&lt;br /&gt;
            &amp;quot;text/html&amp;quot;,&lt;br /&gt;
            html&lt;br /&gt;
        );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Protected sensor page&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void handleSensor()&lt;br /&gt;
{&lt;br /&gt;
    if (!authenticated)&lt;br /&gt;
    {&lt;br /&gt;
        server.sendHeader(&lt;br /&gt;
            &amp;quot;Location&amp;quot;,&lt;br /&gt;
            &amp;quot;/&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        server.send(&lt;br /&gt;
            302,&lt;br /&gt;
            &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
            &amp;quot;Authentication required&amp;quot;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    float temperature =&lt;br /&gt;
        dht.readTemperature();&lt;br /&gt;
&lt;br /&gt;
    float humidity =&lt;br /&gt;
        dht.readHumidity();&lt;br /&gt;
&lt;br /&gt;
    String html = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;html&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;head&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;title&amp;gt;Sensor Dashboard&amp;lt;/title&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/head&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;body&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h1&amp;gt;Smart Sensor System&amp;lt;/h1&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;h2&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;Authentication Successful&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;Temperature: &amp;quot;;&lt;br /&gt;
    html += String(temperature, 1);&lt;br /&gt;
    html += &amp;quot; &amp;amp;deg;C&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;p&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;Humidity: &amp;quot;;&lt;br /&gt;
    html += String(humidity, 1);&lt;br /&gt;
    html += &amp;quot; %&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/p&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/sensor&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;Refresh Sensor Data&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;a href=&#039;/logout&#039;&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;Logout&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    html += &amp;quot;&amp;lt;/body&amp;gt;&amp;quot;;&lt;br /&gt;
    html += &amp;quot;&amp;lt;/html&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
        200,&lt;br /&gt;
        &amp;quot;text/html&amp;quot;,&lt;br /&gt;
        html&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Logout&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void handleLogout()&lt;br /&gt;
{&lt;br /&gt;
    authenticated = false;&lt;br /&gt;
&lt;br /&gt;
    server.sendHeader(&lt;br /&gt;
        &amp;quot;Location&amp;quot;,&lt;br /&gt;
        &amp;quot;/&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.send(&lt;br /&gt;
        302,&lt;br /&gt;
        &amp;quot;text/plain&amp;quot;,&lt;br /&gt;
        &amp;quot;Logged out&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Setup&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
    dht.begin();&lt;br /&gt;
&lt;br /&gt;
    Serial.println();&lt;br /&gt;
    Serial.println(&amp;quot;Smart Sensor Security System&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    WiFi.begin(&lt;br /&gt;
        ssid,&lt;br /&gt;
        password&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&lt;br /&gt;
        &amp;quot;Connecting to Wi-Fi&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    while (&lt;br /&gt;
        WiFi.status() != WL_CONNECTED&lt;br /&gt;
    )&lt;br /&gt;
    {&lt;br /&gt;
        delay(500);&lt;br /&gt;
        Serial.print(&amp;quot;.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.println();&lt;br /&gt;
    Serial.println(&lt;br /&gt;
        &amp;quot;Wi-Fi connected&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&lt;br /&gt;
        &amp;quot;ESP32 IP address: &amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
        WiFi.localIP()&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.on(&lt;br /&gt;
        &amp;quot;/&amp;quot;,&lt;br /&gt;
        HTTP_GET,&lt;br /&gt;
        handleRoot&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.on(&lt;br /&gt;
        &amp;quot;/login&amp;quot;,&lt;br /&gt;
        HTTP_POST,&lt;br /&gt;
        handleLogin&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.on(&lt;br /&gt;
        &amp;quot;/sensor&amp;quot;,&lt;br /&gt;
        HTTP_GET,&lt;br /&gt;
        handleSensor&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.on(&lt;br /&gt;
        &amp;quot;/logout&amp;quot;,&lt;br /&gt;
        HTTP_GET,&lt;br /&gt;
        handleLogout&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    server.begin();&lt;br /&gt;
&lt;br /&gt;
    Serial.println(&lt;br /&gt;
        &amp;quot;Web server started&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
// Main loop&lt;br /&gt;
// -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    server.handleClient();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.h:&#039;&#039;&#039; Provides functions required to connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer.h:&#039;&#039;&#039; Provides the functionality required to create a web server on the ESP32 and handle HTTP requests.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT.h:&#039;&#039;&#039; Provides functions for communicating with the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;mbedtls/sha256.h:&#039;&#039;&#039; Provides the SHA-256 cryptographic hashing functionality available in the ESP32 environment.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DHT():&#039;&#039;&#039; Creates the DHT11 sensor object using the configured GPIO pin and sensor type.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WebServer server(80):&#039;&#039;&#039; Creates a web server that listens for HTTP requests on port 80.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;ssid and password:&#039;&#039;&#039; Store the Wi-Fi network credentials required by the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;username:&#039;&#039;&#039; Stores the username required for authentication.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;storedPasswordHash:&#039;&#039;&#039; Stores the SHA-256 hash used for password verification instead of storing the plaintext password.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;sha256():&#039;&#039;&#039; Converts the entered password into a SHA-256 hash.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleRoot():&#039;&#039;&#039; Displays the login page to the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogin():&#039;&#039;&#039; Receives the username and password entered by the user and verifies the credentials.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.arg():&#039;&#039;&#039; Retrieves form data submitted by the browser.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;authenticated:&#039;&#039;&#039; Stores the current authentication state of the user.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleSensor():&#039;&#039;&#039; Displays the protected sensor dashboard only when authentication has been successful.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readTemperature():&#039;&#039;&#039; Reads the temperature measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dht.readHumidity():&#039;&#039;&#039; Reads the relative humidity measured by the DHT11.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;handleLogout():&#039;&#039;&#039; Ends the current authentication state and redirects the user to the login page.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WiFi.localIP():&#039;&#039;&#039; Displays the IP address assigned to the ESP32.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.on():&#039;&#039;&#039; Associates a URL path with a particular function that handles the request.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.begin():&#039;&#039;&#039; Starts the ESP32 web server.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;server.handleClient():&#039;&#039;&#039; Processes incoming HTTP requests from connected clients.&lt;br /&gt;
&lt;br /&gt;
== Authentication Process ==&lt;br /&gt;
&lt;br /&gt;
The authentication process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
# The user connects the computer or smartphone to the same Wi-Fi network as the ESP32.&lt;br /&gt;
# The user enters the IP address of the ESP32 into a web browser.&lt;br /&gt;
# The ESP32 displays the login page.&lt;br /&gt;
# The user enters the username and password.&lt;br /&gt;
# The ESP32 receives the submitted credentials.&lt;br /&gt;
# The entered password is processed using the SHA-256 hashing algorithm.&lt;br /&gt;
# The resulting hash is compared with the stored password hash.&lt;br /&gt;
# If both the username and password hash match, authentication is successful.&lt;br /&gt;
# The ESP32 allows access to the sensor dashboard.&lt;br /&gt;
# If the credentials do not match, access is denied.&lt;br /&gt;
# The user can log out to terminate the authenticated state.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Open the Arduino IDE.&lt;br /&gt;
# Install the ESP32 board support package if it is not already installed.&lt;br /&gt;
# Install the DHT sensor library using the Arduino IDE Library Manager.&lt;br /&gt;
# Enter the Wi-Fi network name and password in the program.&lt;br /&gt;
# Configure the username and stored password hash.&lt;br /&gt;
# Select the appropriate ESP32 board and COM port.&lt;br /&gt;
# Compile and upload the program to the ESP32.&lt;br /&gt;
# Open the Serial Monitor and set the baud rate to 115200.&lt;br /&gt;
# Wait for the ESP32 to connect to the Wi-Fi network.&lt;br /&gt;
# Note the IP address displayed in the Serial Monitor.&lt;br /&gt;
# Connect a computer or smartphone to the same Wi-Fi network.&lt;br /&gt;
# Open a web browser and enter the ESP32 IP address.&lt;br /&gt;
# Observe the login page.&lt;br /&gt;
# Enter an incorrect username or password and observe that access is denied.&lt;br /&gt;
# Return to the login page and enter the correct credentials.&lt;br /&gt;
# Observe that the sensor dashboard becomes accessible after successful authentication.&lt;br /&gt;
# Observe the temperature and humidity values displayed on the dashboard.&lt;br /&gt;
# Change the environmental conditions around the sensor if required and refresh the dashboard.&lt;br /&gt;
# Observe the updated sensor readings.&lt;br /&gt;
# Select the Logout option.&lt;br /&gt;
# Verify that the system returns to the login page and requires authentication again.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Test Condition&lt;br /&gt;
! Expected Result&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 connected to Wi-Fi&lt;br /&gt;
| ESP32 obtains an IP address&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Open ESP32 IP address&lt;br /&gt;
| Login page is displayed&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Incorrect username&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Incorrect password&lt;br /&gt;
| Access denied&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Correct username and password&lt;br /&gt;
| Authentication successful&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Access protected sensor page&lt;br /&gt;
| Temperature and humidity are displayed&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Logout&lt;br /&gt;
| User is returned to login page&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative Serial Monitor output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Smart Sensor Security System&lt;br /&gt;
Connecting to Wi-Fi....&lt;br /&gt;
Wi-Fi connected&lt;br /&gt;
ESP32 IP address: 192.168.1.105&lt;br /&gt;
Web server started&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial browser page displays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Username: [____________]&lt;br /&gt;
&lt;br /&gt;
Password: [____________]&lt;br /&gt;
&lt;br /&gt;
          [ Login ]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When an incorrect password is entered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Access Denied&lt;br /&gt;
&lt;br /&gt;
Invalid username or password.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After successful authentication:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
--------------------------------&lt;br /&gt;
       Smart Sensor System&lt;br /&gt;
&lt;br /&gt;
Authentication Successful&lt;br /&gt;
&lt;br /&gt;
Temperature: 27.6 °C&lt;br /&gt;
Humidity: 61.0 %&lt;br /&gt;
&lt;br /&gt;
[Refresh Sensor Data]&lt;br /&gt;
&lt;br /&gt;
[Logout]&lt;br /&gt;
--------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security Considerations ==&lt;br /&gt;
&lt;br /&gt;
The experiment demonstrates basic authentication and password hashing, but the implementation is intended for educational purposes.&lt;br /&gt;
&lt;br /&gt;
The following security considerations should be understood:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Password hashing:&#039;&#039;&#039; The password is converted into a SHA-256 hash before comparison.&lt;br /&gt;
* &#039;&#039;&#039;Authentication:&#039;&#039;&#039; Sensor data is not displayed until valid credentials are provided.&lt;br /&gt;
* &#039;&#039;&#039;Access control:&#039;&#039;&#039; The protected sensor page checks the authentication state before displaying sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Logout:&#039;&#039;&#039; The authentication state is cleared when the user logs out.&lt;br /&gt;
* &#039;&#039;&#039;Network security:&#039;&#039;&#039; The demonstration uses HTTP on a local Wi-Fi network. HTTP does not encrypt network traffic.&lt;br /&gt;
* &#039;&#039;&#039;HTTPS/TLS:&#039;&#039;&#039; A production IoT application should use HTTPS/TLS to protect credentials and sensor data while they are transmitted.&lt;br /&gt;
* &#039;&#039;&#039;Password storage:&#039;&#039;&#039; Production systems should use a properly salted password-hashing scheme rather than relying on a simple stored SHA-256 hash.&lt;br /&gt;
* &#039;&#039;&#039;Session management:&#039;&#039;&#039; A production system should use secure sessions or authentication tokens rather than a simple boolean authentication state.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
A password-protected smart sensor system was successfully designed and implemented using an ESP32 and DHT11 sensor. The ESP32 connected to a Wi-Fi network and operated as a web server for providing access to temperature and humidity data.&lt;br /&gt;
&lt;br /&gt;
Password-based authentication was implemented using SHA-256 hashing. Incorrect credentials resulted in access denial, while successful authentication allowed the user to access the protected sensor dashboard.&lt;br /&gt;
&lt;br /&gt;
Thus, the experiment demonstrated basic IoT security concepts including authentication, password hashing and access control for sensor data.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is IoT security?&lt;br /&gt;
# Why is security important in IoT systems?&lt;br /&gt;
# What is authentication?&lt;br /&gt;
# What is the difference between authentication and authorization?&lt;br /&gt;
# What is password hashing?&lt;br /&gt;
# What is SHA-256?&lt;br /&gt;
# Why should passwords not be stored directly in plaintext?&lt;br /&gt;
# What is the purpose of hashing the entered password?&lt;br /&gt;
# What is the role of the ESP32 web server in this experiment?&lt;br /&gt;
# What is an HTTP request?&lt;br /&gt;
# What is the purpose of port 80?&lt;br /&gt;
# How does the ESP32 obtain its IP address?&lt;br /&gt;
# What happens when an incorrect password is entered?&lt;br /&gt;
# What happens after successful authentication?&lt;br /&gt;
# What is the purpose of the logout operation?&lt;br /&gt;
# Why is a boolean authentication variable used in this experiment?&lt;br /&gt;
# Is SHA-256 encryption?&lt;br /&gt;
# What is the difference between hashing and encryption?&lt;br /&gt;
# Why is HTTPS preferred over HTTP for real IoT applications?&lt;br /&gt;
# What is TLS?&lt;br /&gt;
# Why is the implemented system considered a basic security demonstration rather than a production security system?&lt;br /&gt;
# What is a salted password hash?&lt;br /&gt;
# What other security mechanisms can be used in IoT systems?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_13&amp;diff=1353</id>
		<title>MDM331AID/Experiment 13</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_13&amp;diff=1353"/>
		<updated>2026-10-07T08:26:31Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Classification and Anomaly Detection on IoT Sensor Data =  == Aim == To develop and implement machine learning models to classify IoT sensor data into different device or environmental states and detect anomalous sensor readings.  == Objectives == * To understand the application of machine learning in IoT systems. * To collect and prepare temperature and humidity sensor data for machine learning. * To classify IoT sensor readings into Normal, Warning and Cr...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Classification and Anomaly Detection on IoT Sensor Data =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop and implement machine learning models to classify IoT sensor data into different device or environmental states and detect anomalous sensor readings.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the application of machine learning in IoT systems.&lt;br /&gt;
* To collect and prepare temperature and humidity sensor data for machine learning.&lt;br /&gt;
* To classify IoT sensor readings into Normal, Warning and Critical states.&lt;br /&gt;
* To implement a Decision Tree classification model.&lt;br /&gt;
* To evaluate the performance of the classification model.&lt;br /&gt;
* To understand the concept of anomaly detection in IoT sensor data.&lt;br /&gt;
* To implement an Isolation Forest model for detecting anomalous sensor readings.&lt;br /&gt;
* To visualize the classification results and detected anomalies.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cognifront Cloud platform&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Jupyter Notebook / Google Colab / VS Code&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| Pandas library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| NumPy library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Matplotlib library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Scikit-learn library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT systems continuously generate sensor data that can be transmitted to cloud platforms and used for monitoring, analysis and intelligent decision-making.&lt;br /&gt;
&lt;br /&gt;
In this experiment, a DHT11 sensor is used to measure temperature and humidity. The sensor is connected to an ESP32 development board. The ESP32 reads the sensor values and can transmit the collected data to a cloud platform using Wi-Fi. The collected sensor data can be exported as a CSV file and used as input for machine learning.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Machine Learning (ML)&#039;&#039;&#039; is a branch of artificial intelligence in which computer systems learn patterns from data and use those patterns to make predictions or decisions.&lt;br /&gt;
&lt;br /&gt;
Machine learning techniques can be used in IoT systems for applications such as device-state classification, activity recognition, fault detection and abnormal-condition detection.&lt;br /&gt;
&lt;br /&gt;
This experiment demonstrates two machine learning tasks:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Classification&#039;&#039;&#039; using a Decision Tree.&lt;br /&gt;
# &#039;&#039;&#039;Anomaly Detection&#039;&#039;&#039; using Isolation Forest.&lt;br /&gt;
&lt;br /&gt;
=== Classification ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Classification&#039;&#039;&#039; is a supervised machine learning task in which a model learns to assign input data to predefined classes.&lt;br /&gt;
&lt;br /&gt;
In this experiment, temperature and humidity values are used as input features. The sensor readings are classified into three environmental states:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Class&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| Normal&lt;br /&gt;
| Temperature and humidity values are within the normal operating range.&lt;br /&gt;
|-&lt;br /&gt;
| Warning&lt;br /&gt;
| Temperature or humidity values indicate a condition that requires attention.&lt;br /&gt;
|-&lt;br /&gt;
| Critical&lt;br /&gt;
| Temperature or humidity values indicate a significantly abnormal condition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;&#039;Decision Tree Classifier&#039;&#039;&#039; is used for classification. A decision tree makes decisions by applying a sequence of conditions to the input features.&lt;br /&gt;
&lt;br /&gt;
For example, a simplified decision process may be represented as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
              Temperature&lt;br /&gt;
                  |&lt;br /&gt;
        ┌─────────┼─────────┐&lt;br /&gt;
        ↓         ↓         ↓&lt;br /&gt;
      Normal    Warning   Critical&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The actual model uses temperature and humidity together to learn the classification boundaries from the training data.&lt;br /&gt;
&lt;br /&gt;
=== Anomaly Detection ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anomaly detection&#039;&#039;&#039; is the process of identifying observations that differ significantly from the normal pattern of data.&lt;br /&gt;
&lt;br /&gt;
An anomaly in an IoT sensor dataset may occur because of:&lt;br /&gt;
&lt;br /&gt;
* Sensor malfunction.&lt;br /&gt;
* Communication errors.&lt;br /&gt;
* Incorrect sensor readings.&lt;br /&gt;
* Environmental disturbances.&lt;br /&gt;
* Hardware faults.&lt;br /&gt;
* Data transmission errors.&lt;br /&gt;
&lt;br /&gt;
Unlike classification, anomaly detection does not require every abnormal observation to have a predefined class label.&lt;br /&gt;
&lt;br /&gt;
In this experiment, &#039;&#039;&#039;Isolation Forest&#039;&#039;&#039; is used for anomaly detection.&lt;br /&gt;
&lt;br /&gt;
Isolation Forest is an unsupervised machine learning algorithm that identifies unusual observations by isolating them from the rest of the dataset. Observations that are significantly different from normal observations are more easily isolated and are therefore considered potential anomalies.&lt;br /&gt;
&lt;br /&gt;
For example, if normal temperature readings are approximately between 23 °C and 32 °C, values such as 80 °C or -10 °C may be identified as anomalous.&lt;br /&gt;
&lt;br /&gt;
The classification and anomaly-detection processes are therefore different:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Classification:&lt;br /&gt;
&lt;br /&gt;
Temperature + Humidity&lt;br /&gt;
          ↓&lt;br /&gt;
   Decision Tree&lt;br /&gt;
          ↓&lt;br /&gt;
Normal / Warning / Critical&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anomaly Detection:&lt;br /&gt;
&lt;br /&gt;
Temperature + Humidity&lt;br /&gt;
          ↓&lt;br /&gt;
   Isolation Forest&lt;br /&gt;
          ↓&lt;br /&gt;
Normal / Anomaly&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The overall workflow of the experiment is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
 IoT Dataset&lt;br /&gt;
      ↓&lt;br /&gt;
Data Preprocessing&lt;br /&gt;
      ↓&lt;br /&gt;
 ┌───────────────────────┐&lt;br /&gt;
 │                       │&lt;br /&gt;
 ↓                       ↓&lt;br /&gt;
Classification       Anomaly Detection&lt;br /&gt;
 │                       │&lt;br /&gt;
 ↓                       ↓&lt;br /&gt;
Decision Tree       Isolation Forest&lt;br /&gt;
 │                       │&lt;br /&gt;
 ↓                       ↓&lt;br /&gt;
Normal/Warning/      Normal/Anomaly&lt;br /&gt;
Critical&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== DHT11 Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections can be used when collecting the temperature and humidity data using an ESP32.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the program is modified accordingly.&lt;br /&gt;
&lt;br /&gt;
== Dataset ==&lt;br /&gt;
&lt;br /&gt;
The dataset used in this experiment contains temperature and humidity readings obtained from a DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
The dataset contains the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Column&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| ID&lt;br /&gt;
| Unique record identifier&lt;br /&gt;
|-&lt;br /&gt;
| Temperature&lt;br /&gt;
| Temperature measured by the DHT11 sensor in °C&lt;br /&gt;
|-&lt;br /&gt;
| Humidity&lt;br /&gt;
| Relative humidity measured by the DHT11 sensor in %&lt;br /&gt;
|-&lt;br /&gt;
| Date&lt;br /&gt;
| Date and time of the sensor reading&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The clean dataset is used as the original reference dataset.&lt;br /&gt;
&lt;br /&gt;
A separate copy of the dataset can be created for anomaly detection. Controlled anomalous values can be introduced into this copy to demonstrate the ability of the Isolation Forest model to detect abnormal sensor readings.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; The original clean dataset should not be modified. The anomalous dataset should be created as a separate copy.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Dataset ==&lt;br /&gt;
&lt;br /&gt;
For the classification task, a class label named &#039;&#039;&#039;State&#039;&#039;&#039; is generated from the temperature and humidity values.&lt;br /&gt;
&lt;br /&gt;
The following example rules are used to generate the labels:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Condition&lt;br /&gt;
! State&lt;br /&gt;
|-&lt;br /&gt;
| Temperature &amp;lt; 30 °C and Humidity &amp;lt; 70 %&lt;br /&gt;
| Normal&lt;br /&gt;
|-&lt;br /&gt;
| Temperature ≥ 30 °C or Humidity ≥ 70 %&lt;br /&gt;
| Warning&lt;br /&gt;
|-&lt;br /&gt;
| Temperature ≥ 33 °C or Humidity ≥ 80 %&lt;br /&gt;
| Critical&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;Critical&#039;&#039;&#039; condition is checked before the Warning condition so that a critical reading is not incorrectly classified as Warning.&lt;br /&gt;
&lt;br /&gt;
These labels are used only to create the labelled dataset required for demonstrating supervised classification.&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries before running the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib scikit-learn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program can be executed using Jupyter Notebook, Google Colab or VS Code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
from sklearn.model_selection import train_test_split&lt;br /&gt;
from sklearn.tree import DecisionTreeClassifier, plot_tree&lt;br /&gt;
from sklearn.metrics import (&lt;br /&gt;
    accuracy_score,&lt;br /&gt;
    confusion_matrix,&lt;br /&gt;
    classification_report&lt;br /&gt;
)&lt;br /&gt;
from sklearn.ensemble import IsolationForest&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 1. Load the dataset&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
df = pd.read_csv(&amp;quot;clean-dht11-temperature-humidity.csv&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDataset Information&amp;quot;)&lt;br /&gt;
print(df.info())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nMissing Values&amp;quot;)&lt;br /&gt;
print(df.isnull().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDuplicate Records&amp;quot;)&lt;br /&gt;
print(df.duplicated().sum())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 2. Data preprocessing&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;Temperature&amp;quot;] = pd.to_numeric(&lt;br /&gt;
    df[&amp;quot;Temperature&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;Humidity&amp;quot;] = pd.to_numeric(&lt;br /&gt;
    df[&amp;quot;Humidity&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove invalid records&lt;br /&gt;
df = df.dropna(&lt;br /&gt;
    subset=[&amp;quot;Temperature&amp;quot;, &amp;quot;Humidity&amp;quot;, &amp;quot;Date&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove duplicate records&lt;br /&gt;
df = df.drop_duplicates()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 3. Create classification labels&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
def classify_state(row):&lt;br /&gt;
&lt;br /&gt;
    temperature = row[&amp;quot;Temperature&amp;quot;]&lt;br /&gt;
    humidity = row[&amp;quot;Humidity&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
    if temperature &amp;gt;= 33 or humidity &amp;gt;= 80:&lt;br /&gt;
        return &amp;quot;Critical&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    elif temperature &amp;gt;= 30 or humidity &amp;gt;= 70:&lt;br /&gt;
        return &amp;quot;Warning&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    else:&lt;br /&gt;
        return &amp;quot;Normal&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
df[&amp;quot;State&amp;quot;] = df.apply(&lt;br /&gt;
    classify_state,&lt;br /&gt;
    axis=1&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nClass Distribution&amp;quot;)&lt;br /&gt;
print(df[&amp;quot;State&amp;quot;].value_counts())&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 4. Classification&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
# Input features&lt;br /&gt;
X = df[&lt;br /&gt;
    [&amp;quot;Temperature&amp;quot;, &amp;quot;Humidity&amp;quot;]&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
# Target class&lt;br /&gt;
y = df[&amp;quot;State&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
# Split data into training and testing sets&lt;br /&gt;
X_train, X_test, y_train, y_test = train_test_split(&lt;br /&gt;
    X,&lt;br /&gt;
    y,&lt;br /&gt;
    test_size=0.2,&lt;br /&gt;
    random_state=42,&lt;br /&gt;
    stratify=y&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Create Decision Tree model&lt;br /&gt;
classifier = DecisionTreeClassifier(&lt;br /&gt;
    max_depth=4,&lt;br /&gt;
    random_state=42&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Train the model&lt;br /&gt;
classifier.fit(&lt;br /&gt;
    X_train,&lt;br /&gt;
    y_train&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Predict test data&lt;br /&gt;
y_pred = classifier.predict(X_test)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 5. Classification evaluation&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
accuracy = accuracy_score(&lt;br /&gt;
    y_test,&lt;br /&gt;
    y_pred&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nClassification Accuracy:&amp;quot;)&lt;br /&gt;
print(accuracy)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nClassification Report:&amp;quot;)&lt;br /&gt;
print(&lt;br /&gt;
    classification_report(&lt;br /&gt;
        y_test,&lt;br /&gt;
        y_pred&lt;br /&gt;
    )&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nConfusion Matrix:&amp;quot;)&lt;br /&gt;
cm = confusion_matrix(&lt;br /&gt;
    y_test,&lt;br /&gt;
    y_pred&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(cm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 6. Visualize the Decision Tree&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
plt.figure(figsize=(14, 8))&lt;br /&gt;
&lt;br /&gt;
plot_tree(&lt;br /&gt;
    classifier,&lt;br /&gt;
    feature_names=[&lt;br /&gt;
        &amp;quot;Temperature&amp;quot;,&lt;br /&gt;
        &amp;quot;Humidity&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
    class_names=classifier.classes_,&lt;br /&gt;
    filled=True&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;Decision Tree for IoT Sensor Classification&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 7. Load anomalous dataset&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
anomaly_df = pd.read_csv(&lt;br /&gt;
    &amp;quot;anomalous-dht11-temperature-humidity.csv&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
anomaly_df[&amp;quot;Temperature&amp;quot;] = pd.to_numeric(&lt;br /&gt;
    anomaly_df[&amp;quot;Temperature&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
anomaly_df[&amp;quot;Humidity&amp;quot;] = pd.to_numeric(&lt;br /&gt;
    anomaly_df[&amp;quot;Humidity&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
anomaly_df = anomaly_df.dropna(&lt;br /&gt;
    subset=[&lt;br /&gt;
        &amp;quot;Temperature&amp;quot;,&lt;br /&gt;
        &amp;quot;Humidity&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 8. Isolation Forest anomaly detection&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
features = anomaly_df[&lt;br /&gt;
    [&amp;quot;Temperature&amp;quot;, &amp;quot;Humidity&amp;quot;]&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
isolation_model = IsolationForest(&lt;br /&gt;
    contamination=0.02,&lt;br /&gt;
    random_state=42&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
isolation_model.fit(&lt;br /&gt;
    features&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Predict anomalies&lt;br /&gt;
anomaly_prediction = isolation_model.predict(&lt;br /&gt;
    features&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
anomaly_df[&amp;quot;Anomaly&amp;quot;] = anomaly_prediction&lt;br /&gt;
&lt;br /&gt;
# Convert prediction to readable labels&lt;br /&gt;
anomaly_df[&amp;quot;Status&amp;quot;] = anomaly_df[&lt;br /&gt;
    &amp;quot;Anomaly&amp;quot;&lt;br /&gt;
].map({&lt;br /&gt;
    1: &amp;quot;Normal&amp;quot;,&lt;br /&gt;
    -1: &amp;quot;Anomaly&amp;quot;&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 9. Display detected anomalies&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
detected_anomalies = anomaly_df[&lt;br /&gt;
    anomaly_df[&amp;quot;Status&amp;quot;] == &amp;quot;Anomaly&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDetected Anomalies:&amp;quot;)&lt;br /&gt;
print(&lt;br /&gt;
    detected_anomalies[&lt;br /&gt;
        [&lt;br /&gt;
            &amp;quot;ID&amp;quot;,&lt;br /&gt;
            &amp;quot;Temperature&amp;quot;,&lt;br /&gt;
            &amp;quot;Humidity&amp;quot;,&lt;br /&gt;
            &amp;quot;Date&amp;quot;,&lt;br /&gt;
            &amp;quot;Status&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
    ]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nNumber of detected anomalies:&amp;quot;,&lt;br /&gt;
    len(detected_anomalies)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 10. Visualize anomaly detection&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
plt.figure(figsize=(10, 6))&lt;br /&gt;
&lt;br /&gt;
normal_data = anomaly_df[&lt;br /&gt;
    anomaly_df[&amp;quot;Status&amp;quot;] == &amp;quot;Normal&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
anomaly_data = anomaly_df[&lt;br /&gt;
    anomaly_df[&amp;quot;Status&amp;quot;] == &amp;quot;Anomaly&amp;quot;&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
plt.scatter(&lt;br /&gt;
    normal_data[&amp;quot;Temperature&amp;quot;],&lt;br /&gt;
    normal_data[&amp;quot;Humidity&amp;quot;],&lt;br /&gt;
    label=&amp;quot;Normal&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.scatter(&lt;br /&gt;
    anomaly_data[&amp;quot;Temperature&amp;quot;],&lt;br /&gt;
    anomaly_data[&amp;quot;Humidity&amp;quot;],&lt;br /&gt;
    label=&amp;quot;Anomaly&amp;quot;,&lt;br /&gt;
    marker=&amp;quot;x&amp;quot;,&lt;br /&gt;
    s=80&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Humidity (%)&amp;quot;)&lt;br /&gt;
plt.title(&lt;br /&gt;
    &amp;quot;IoT Sensor Anomaly Detection&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.legend()&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
# 11. Save classification dataset&lt;br /&gt;
# -------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
df.to_csv(&lt;br /&gt;
    &amp;quot;classified-dht11-data.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Save anomaly detection results&lt;br /&gt;
anomaly_df.to_csv(&lt;br /&gt;
    &amp;quot;dht11-anomaly-detection-results.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&lt;br /&gt;
    &amp;quot;\nProcessed datasets saved successfully.&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the IoT temperature and humidity dataset from a CSV file.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the Temperature and Humidity columns into numerical values. Invalid values are converted to missing values.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a date-time format.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records containing invalid or missing temperature, humidity or date values.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;drop_duplicates():&#039;&#039;&#039; Removes duplicate records from the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;classify_state():&#039;&#039;&#039; Generates the target class label based on the temperature and humidity values.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;State:&#039;&#039;&#039; Represents the class assigned to each sensor reading. The classes used are Normal, Warning and Critical.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;train_test_split():&#039;&#039;&#039; Divides the labelled dataset into training and testing datasets.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;stratify:&#039;&#039;&#039; Maintains approximately the same proportion of each class in the training and testing datasets.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;DecisionTreeClassifier():&#039;&#039;&#039; Creates a Decision Tree machine learning classification model.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;max_depth:&#039;&#039;&#039; Limits the maximum depth of the decision tree and helps keep the model simple and interpretable.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;fit():&#039;&#039;&#039; Trains the Decision Tree model using the training data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;predict():&#039;&#039;&#039; Uses the trained model to predict the class of unseen sensor readings.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;accuracy_score():&#039;&#039;&#039; Calculates the percentage of correctly classified test samples.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;classification_report():&#039;&#039;&#039; Displays precision, recall and F1-score for each class.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;confusion_matrix():&#039;&#039;&#039; Shows the number of correctly and incorrectly classified observations for each class.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plot_tree():&#039;&#039;&#039; Displays the structure of the trained Decision Tree.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IsolationForest():&#039;&#039;&#039; Creates an unsupervised machine learning model for detecting anomalous sensor observations.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;contamination:&#039;&#039;&#039; Specifies the approximate proportion of observations expected to be anomalous. In this experiment, 0.02 represents approximately 2% of the data.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;fit():&#039;&#039;&#039; Trains the Isolation Forest model using the temperature and humidity features.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Isolation Forest prediction:&#039;&#039;&#039; A value of &#039;&#039;&#039;1&#039;&#039;&#039; represents a normal observation, while &#039;&#039;&#039;-1&#039;&#039;&#039; represents a potential anomaly.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Status:&#039;&#039;&#039; Converts the numerical Isolation Forest output into readable labels such as Normal and Anomaly.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;detected_anomalies:&#039;&#039;&#039; Contains only the sensor observations identified as anomalous by the Isolation Forest model.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plt.scatter():&#039;&#039;&#039; Creates a scatter plot showing the relationship between temperature and humidity and highlights detected anomalies.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;to_csv():&#039;&#039;&#039; Saves the classification results and anomaly-detection results as CSV files.&lt;br /&gt;
&lt;br /&gt;
== Introducing Manual Anomalies ==&lt;br /&gt;
&lt;br /&gt;
The original clean dataset should be preserved.&lt;br /&gt;
&lt;br /&gt;
Create a copy of the original dataset and rename it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
anomalous-dht11-temperature-humidity.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Artificial anomalies can then be introduced into this copy.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Anomaly Type&lt;br /&gt;
! Example Temperature&lt;br /&gt;
! Example Humidity&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Normal reading&lt;br /&gt;
| 27.5 °C&lt;br /&gt;
| 60 %&lt;br /&gt;
| Represents normal sensor operation&lt;br /&gt;
|-&lt;br /&gt;
| High temperature&lt;br /&gt;
| 80 °C&lt;br /&gt;
| 60 %&lt;br /&gt;
| Demonstrates abnormal temperature&lt;br /&gt;
|-&lt;br /&gt;
| Very low temperature&lt;br /&gt;
| -10 °C&lt;br /&gt;
| 60 %&lt;br /&gt;
| Demonstrates abnormal temperature&lt;br /&gt;
|-&lt;br /&gt;
| High humidity&lt;br /&gt;
| 27 °C&lt;br /&gt;
| 98 %&lt;br /&gt;
| Demonstrates abnormal humidity&lt;br /&gt;
|-&lt;br /&gt;
| Unusual combination&lt;br /&gt;
| 80 °C&lt;br /&gt;
| 10 %&lt;br /&gt;
| Demonstrates an unusual sensor condition&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Only a small number of anomalous records should be introduced. For example, approximately 10–15 anomalous records can be added or modified in a dataset containing several hundred records.&lt;br /&gt;
&lt;br /&gt;
The anomalies should be distributed at different positions in the dataset rather than placed together.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Important:&#039;&#039;&#039; These values are intentionally introduced for demonstrating anomaly detection. They should not be presented as actual DHT11 sensor faults.&lt;br /&gt;
&lt;br /&gt;
The original dataset remains unchanged:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
clean-dht11-temperature-humidity.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The modified dataset is used for anomaly detection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
anomalous-dht11-temperature-humidity.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The output of the anomaly-detection program is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dht11-anomaly-detection-results.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Configure the ESP32 to read temperature and humidity from the DHT11 sensor.&lt;br /&gt;
# Connect the ESP32 to a Wi-Fi network.&lt;br /&gt;
# Transmit the sensor readings to the cloud platform if real-time data collection is being performed.&lt;br /&gt;
# Export the collected sensor data as a CSV file.&lt;br /&gt;
# Alternatively, use the provided clean DHT11 temperature and humidity dataset.&lt;br /&gt;
# Preserve the original clean dataset.&lt;br /&gt;
# Create a copy of the dataset for anomaly-detection experiments.&lt;br /&gt;
# Introduce a small number of controlled anomalous temperature and humidity values into the copied dataset.&lt;br /&gt;
# Open Jupyter Notebook, Google Colab or VS Code.&lt;br /&gt;
# Install Pandas, NumPy, Matplotlib and Scikit-learn.&lt;br /&gt;
# Load the clean dataset using Pandas.&lt;br /&gt;
# Inspect the dataset for missing values and duplicate records.&lt;br /&gt;
# Convert the temperature, humidity and date columns into appropriate data types.&lt;br /&gt;
# Generate Normal, Warning and Critical class labels.&lt;br /&gt;
# Separate the temperature and humidity columns as input features.&lt;br /&gt;
# Split the labelled data into training and testing datasets.&lt;br /&gt;
# Create and train the Decision Tree classification model.&lt;br /&gt;
# Predict the classes of the testing data.&lt;br /&gt;
# Calculate the classification accuracy.&lt;br /&gt;
# Generate the classification report and confusion matrix.&lt;br /&gt;
# Visualize the trained Decision Tree.&lt;br /&gt;
# Load the anomalous dataset.&lt;br /&gt;
# Select temperature and humidity as the features for anomaly detection.&lt;br /&gt;
# Create and train the Isolation Forest model.&lt;br /&gt;
# Predict normal and anomalous observations.&lt;br /&gt;
# Display the sensor readings identified as anomalies.&lt;br /&gt;
# Visualize normal and anomalous observations using a scatter plot.&lt;br /&gt;
# Save the classification and anomaly-detection results as CSV files.&lt;br /&gt;
# Observe and compare the machine learning results.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
=== Classification ===&lt;br /&gt;
&lt;br /&gt;
The following table can be used to record the classification results:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Parameter&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Input features&lt;br /&gt;
| Temperature and Humidity&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Classification model&lt;br /&gt;
| Decision Tree&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Number of classes&lt;br /&gt;
| 3&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Classes&lt;br /&gt;
| Normal, Warning, Critical&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Training samples&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Testing samples&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Accuracy&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Precision&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Recall&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| F1-score&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative classification output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Class Distribution&lt;br /&gt;
&lt;br /&gt;
Normal       ...&lt;br /&gt;
Warning      ...&lt;br /&gt;
Critical     ...&lt;br /&gt;
&lt;br /&gt;
Classification Accuracy:&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Classification Report:&lt;br /&gt;
&lt;br /&gt;
              precision    recall    f1-score&lt;br /&gt;
&lt;br /&gt;
Normal           ...        ...        ...&lt;br /&gt;
Warning          ...        ...        ...&lt;br /&gt;
Critical         ...        ...        ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anomaly Detection ===&lt;br /&gt;
&lt;br /&gt;
The following table can be used to record the anomaly-detection results:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Parameter&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Anomaly detection model&lt;br /&gt;
| Isolation Forest&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Input features&lt;br /&gt;
| Temperature and Humidity&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Contamination&lt;br /&gt;
| 2%&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Total records&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Detected anomalies&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Normal observations&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative output is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Detected Anomalies:&lt;br /&gt;
&lt;br /&gt;
ID     Temperature     Humidity       Status&lt;br /&gt;
...       80.0            60          Anomaly&lt;br /&gt;
...      -10.0            60          Anomaly&lt;br /&gt;
...       27.0            98          Anomaly&lt;br /&gt;
&lt;br /&gt;
Number of detected anomalies: ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The scatter plot represents temperature and humidity observations. Normal observations and observations identified as anomalies are displayed using different markers.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT sensor dataset was successfully prepared for machine learning. A Decision Tree classification model was implemented to classify sensor readings into Normal, Warning and Critical states. The classification model was evaluated using accuracy, precision, recall, F1-score and a confusion matrix.&lt;br /&gt;
&lt;br /&gt;
An Isolation Forest model was also implemented to identify anomalous temperature and humidity readings. The detected anomalies were visualized and the processed classification and anomaly-detection results were exported as CSV files.&lt;br /&gt;
&lt;br /&gt;
Thus, machine learning techniques were successfully applied to IoT sensor data for both classification and anomaly detection.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is machine learning?&lt;br /&gt;
# What is the difference between supervised and unsupervised learning?&lt;br /&gt;
# What is classification?&lt;br /&gt;
# What is anomaly detection?&lt;br /&gt;
# What is the difference between classification and anomaly detection?&lt;br /&gt;
# What are the input features used in this experiment?&lt;br /&gt;
# What is the target variable in the classification task?&lt;br /&gt;
# What is a Decision Tree?&lt;br /&gt;
# Why is a Decision Tree used for classification?&lt;br /&gt;
# What is the purpose of training and testing datasets?&lt;br /&gt;
# What is classification accuracy?&lt;br /&gt;
# What is precision?&lt;br /&gt;
# What is recall?&lt;br /&gt;
# What is an F1-score?&lt;br /&gt;
# What is a confusion matrix?&lt;br /&gt;
# What is Isolation Forest?&lt;br /&gt;
# Why is Isolation Forest suitable for anomaly detection?&lt;br /&gt;
# What does an Isolation Forest prediction of -1 represent?&lt;br /&gt;
# What does an Isolation Forest prediction of 1 represent?&lt;br /&gt;
# What is the contamination parameter?&lt;br /&gt;
# Why are artificial anomalies introduced into the dataset?&lt;br /&gt;
# Give examples of anomalies in IoT sensor data.&lt;br /&gt;
# How can anomaly detection be useful in industrial IoT?&lt;br /&gt;
# What is the difference between an actual sensor fault and an artificially introduced anomaly?&lt;br /&gt;
# How can the classification model be improved?&lt;br /&gt;
# How can the anomaly-detection system be improved?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_10&amp;diff=1352</id>
		<title>MDM331AID/Experiment 10</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_10&amp;diff=1352"/>
		<updated>2026-10-07T07:52:34Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Real-Time IoT Temperature Data Collection and Machine Learning-Based Prediction =  == Aim == To implement an IoT application to collect temperature data using a DHT11 sensor and ESP32, and apply a machine learning model to predict future temperature values.  == Objectives == * To understand the integration of IoT sensor data with machine learning. * To collect temperature data from a DHT11 sensor using an ESP32. * To transmit the sensor data to a cloud plat...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Real-Time IoT Temperature Data Collection and Machine Learning-Based Prediction =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To implement an IoT application to collect temperature data using a DHT11 sensor and ESP32, and apply a machine learning model to predict future temperature values.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the integration of IoT sensor data with machine learning.&lt;br /&gt;
* To collect temperature data from a DHT11 sensor using an ESP32.&lt;br /&gt;
* To transmit the sensor data to a cloud platform using Wi-Fi.&lt;br /&gt;
* To obtain the collected temperature dataset in CSV format.&lt;br /&gt;
* To preprocess the IoT temperature dataset for machine learning.&lt;br /&gt;
* To train a machine learning model using historical temperature data.&lt;br /&gt;
* To predict future temperature values using the trained model.&lt;br /&gt;
* To visualize the actual and predicted temperature values.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature and humidity sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cognifront Cloud platform&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Jupyter Notebook / Google Colab / VS Code&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| Pandas, NumPy, Matplotlib and Scikit-learn libraries&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. In an IoT system, sensor data can be transmitted to a cloud platform for storage and further processing.&lt;br /&gt;
&lt;br /&gt;
In this experiment, a DHT11 sensor is connected to an ESP32 development board. The DHT11 measures the temperature of the surrounding environment and provides the sensor reading to the ESP32. The ESP32 uses its built-in Wi-Fi capability to transmit the collected temperature data to the Cognifront Cloud platform.&lt;br /&gt;
&lt;br /&gt;
The collected temperature readings are stored on the cloud platform and can be exported as a CSV file. The historical temperature data is then used as input for a machine learning model.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Machine Learning (ML)&#039;&#039;&#039; is a branch of artificial intelligence in which computer systems learn patterns from data and use those patterns to make predictions or decisions without being explicitly programmed for every individual case.&lt;br /&gt;
&lt;br /&gt;
For temperature prediction, historical sensor readings can be used to train a machine learning model. The model learns the relationship between the input data and the corresponding temperature values. After training, the model can be given a future time value and can estimate the corresponding temperature.&lt;br /&gt;
&lt;br /&gt;
In this experiment, &#039;&#039;&#039;Linear Regression&#039;&#039;&#039; is used as the machine learning model. Linear Regression is a supervised machine learning algorithm used to model the relationship between an independent variable and a dependent variable.&lt;br /&gt;
&lt;br /&gt;
The basic equation of Linear Regression is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
y = mx + c&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;y&#039;&#039;&#039; is the predicted temperature.&lt;br /&gt;
* &#039;&#039;&#039;x&#039;&#039;&#039; is the input time or time index.&lt;br /&gt;
* &#039;&#039;&#039;m&#039;&#039;&#039; is the slope of the regression line.&lt;br /&gt;
* &#039;&#039;&#039;c&#039;&#039;&#039; is the intercept.&lt;br /&gt;
&lt;br /&gt;
For this experiment, the timestamp of each temperature reading is converted into a numerical time representation or time index. The machine learning model uses the historical time and temperature relationship to predict future temperature values.&lt;br /&gt;
&lt;br /&gt;
The overall system consists of two major stages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stage 1 — IoT Data Collection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Sensor&lt;br /&gt;
      ↓&lt;br /&gt;
    ESP32&lt;br /&gt;
      ↓&lt;br /&gt;
    Wi-Fi&lt;br /&gt;
      ↓&lt;br /&gt;
Cognifront Cloud&lt;br /&gt;
      ↓&lt;br /&gt;
 Temperature CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Stage 2 — Machine Learning Prediction&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Historical Temperature CSV&lt;br /&gt;
          ↓&lt;br /&gt;
     Data Preprocessing&lt;br /&gt;
          ↓&lt;br /&gt;
   Feature Preparation&lt;br /&gt;
          ↓&lt;br /&gt;
   Train-Test Split&lt;br /&gt;
          ↓&lt;br /&gt;
   Linear Regression&lt;br /&gt;
          ↓&lt;br /&gt;
   Future Prediction&lt;br /&gt;
          ↓&lt;br /&gt;
Actual vs Predicted Graph&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The accuracy of the prediction depends on the amount and quality of historical sensor data and the behavior of the temperature during the data-collection period. A simple Linear Regression model is suitable for demonstrating the machine learning workflow, but more advanced models may be required for complex temperature patterns.&lt;br /&gt;
&lt;br /&gt;
== DHT11 and ESP32 Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA&lt;br /&gt;
| GPIO 4&lt;br /&gt;
| Digital temperature and humidity data&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The DATA pin can be connected to another suitable ESP32 GPIO if the program is modified accordingly.&lt;br /&gt;
&lt;br /&gt;
== IoT Data Collection Program ==&lt;br /&gt;
&lt;br /&gt;
The ESP32 is programmed to read the temperature from the DHT11 and transmit the sensor data to the Cognifront Cloud platform.&lt;br /&gt;
&lt;br /&gt;
A typical data collection program follows the same cloud communication mechanism used in the previous experiment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
#include &amp;quot;DHT.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#define DHT_PIN 4&lt;br /&gt;
#define DHT_TYPE DHT11&lt;br /&gt;
&lt;br /&gt;
DHT dht(DHT_PIN, DHT_TYPE);&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;;&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;;&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    Serial.begin(115200);&lt;br /&gt;
&lt;br /&gt;
    dht.begin();&lt;br /&gt;
&lt;br /&gt;
    cogInitCloud(ssid, pass, apikey);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
    cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
    float temperature = dht.readTemperature();&lt;br /&gt;
&lt;br /&gt;
    if (isnan(temperature))&lt;br /&gt;
    {&lt;br /&gt;
        Serial.println(&amp;quot;Failed to read temperature&amp;quot;);&lt;br /&gt;
        delay(2000);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Serial.print(&amp;quot;Temperature: &amp;quot;);&lt;br /&gt;
    Serial.print(temperature);&lt;br /&gt;
    Serial.println(&amp;quot; °C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    cogStoreCloudVariable(&lt;br /&gt;
        &amp;quot;DHT-Temp&amp;quot;,&lt;br /&gt;
        String(temperature, 2)&lt;br /&gt;
    );&lt;br /&gt;
&lt;br /&gt;
    delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Machine Learning Program ==&lt;br /&gt;
&lt;br /&gt;
The following Python program loads the temperature dataset exported from the Cognifront Cloud platform, preprocesses the data, trains a Linear Regression model and predicts future temperature values.&lt;br /&gt;
&lt;br /&gt;
Install the required libraries if they are not already available:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib scikit-learn&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program can be executed using Jupyter Notebook, Google Colab or VS Code.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
from sklearn.model_selection import train_test_split&lt;br /&gt;
from sklearn.linear_model import LinearRegression&lt;br /&gt;
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score&lt;br /&gt;
&lt;br /&gt;
# Load the IoT temperature dataset&lt;br /&gt;
df = pd.read_csv(&amp;quot;dht11-data-logger-dht-temp.csv&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
# Convert Date column to datetime&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(&lt;br /&gt;
    df[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Convert temperature values to numeric&lt;br /&gt;
df[&amp;quot;Value&amp;quot;] = pd.to_numeric(&lt;br /&gt;
    df[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    errors=&amp;quot;coerce&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Remove invalid records&lt;br /&gt;
df = df.dropna(&lt;br /&gt;
    subset=[&amp;quot;Date&amp;quot;, &amp;quot;Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Sort data according to time&lt;br /&gt;
df = df.sort_values(&amp;quot;Date&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Create a time index&lt;br /&gt;
df[&amp;quot;Time_Index&amp;quot;] = np.arange(len(df))&lt;br /&gt;
&lt;br /&gt;
# Input and output variables&lt;br /&gt;
X = df[[&amp;quot;Time_Index&amp;quot;]]&lt;br /&gt;
y = df[&amp;quot;Value&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
# Split data into training and testing sets&lt;br /&gt;
X_train, X_test, y_train, y_test = train_test_split(&lt;br /&gt;
    X,&lt;br /&gt;
    y,&lt;br /&gt;
    test_size=0.2,&lt;br /&gt;
    random_state=42&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Create Linear Regression model&lt;br /&gt;
model = LinearRegression()&lt;br /&gt;
&lt;br /&gt;
# Train the model&lt;br /&gt;
model.fit(X_train, y_train)&lt;br /&gt;
&lt;br /&gt;
# Predict test values&lt;br /&gt;
y_pred = model.predict(X_test)&lt;br /&gt;
&lt;br /&gt;
# Calculate evaluation metrics&lt;br /&gt;
mae = mean_absolute_error(y_test, y_pred)&lt;br /&gt;
mse = mean_squared_error(y_test, y_pred)&lt;br /&gt;
rmse = np.sqrt(mse)&lt;br /&gt;
r2 = r2_score(y_test, y_pred)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nModel Evaluation&amp;quot;)&lt;br /&gt;
print(&amp;quot;MAE:&amp;quot;, mae)&lt;br /&gt;
print(&amp;quot;MSE:&amp;quot;, mse)&lt;br /&gt;
print(&amp;quot;RMSE:&amp;quot;, rmse)&lt;br /&gt;
print(&amp;quot;R2 Score:&amp;quot;, r2)&lt;br /&gt;
&lt;br /&gt;
# Predict future temperature values&lt;br /&gt;
future_steps = 10&lt;br /&gt;
&lt;br /&gt;
last_index = df[&amp;quot;Time_Index&amp;quot;].max()&lt;br /&gt;
&lt;br /&gt;
future_index = np.arange(&lt;br /&gt;
    last_index + 1,&lt;br /&gt;
    last_index + 1 + future_steps&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
future_df = pd.DataFrame({&lt;br /&gt;
    &amp;quot;Time_Index&amp;quot;: future_index&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
future_predictions = model.predict(&lt;br /&gt;
    future_df[[&amp;quot;Time_Index&amp;quot;]]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
future_df[&amp;quot;Predicted_Temperature&amp;quot;] = future_predictions&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nFuture Temperature Predictions&amp;quot;)&lt;br /&gt;
print(future_df)&lt;br /&gt;
&lt;br /&gt;
# Plot actual temperature data&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df[&amp;quot;Time_Index&amp;quot;],&lt;br /&gt;
    df[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    label=&amp;quot;Actual Temperature&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Plot regression prediction&lt;br /&gt;
plt.plot(&lt;br /&gt;
    X_test[&amp;quot;Time_Index&amp;quot;],&lt;br /&gt;
    y_pred,&lt;br /&gt;
    label=&amp;quot;Predicted Temperature&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Time Index&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Actual vs Predicted Temperature&amp;quot;)&lt;br /&gt;
plt.legend()&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Plot future predictions&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df[&amp;quot;Time_Index&amp;quot;],&lt;br /&gt;
    df[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    label=&amp;quot;Historical Temperature&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    future_df[&amp;quot;Time_Index&amp;quot;],&lt;br /&gt;
    future_df[&amp;quot;Predicted_Temperature&amp;quot;],&lt;br /&gt;
    label=&amp;quot;Future Prediction&amp;quot;&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Time Index&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Future Temperature Prediction&amp;quot;)&lt;br /&gt;
plt.legend()&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the historical IoT temperature dataset from the CSV file.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a date-time format.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the temperature values into numerical data.&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records with invalid or missing date or temperature values.&lt;br /&gt;
* &#039;&#039;&#039;sort_values():&#039;&#039;&#039; Arranges the sensor readings chronologically.&lt;br /&gt;
* &#039;&#039;&#039;Time_Index:&#039;&#039;&#039; Creates a numerical representation of the sequence of temperature readings.&lt;br /&gt;
* &#039;&#039;&#039;train_test_split():&#039;&#039;&#039; Divides the dataset into training and testing subsets.&lt;br /&gt;
* &#039;&#039;&#039;LinearRegression():&#039;&#039;&#039; Creates the Linear Regression machine learning model.&lt;br /&gt;
* &#039;&#039;&#039;fit():&#039;&#039;&#039; Trains the model using the training data.&lt;br /&gt;
* &#039;&#039;&#039;predict():&#039;&#039;&#039; Generates temperature predictions using the trained model.&lt;br /&gt;
* &#039;&#039;&#039;MAE:&#039;&#039;&#039; Measures the average absolute difference between actual and predicted temperature values.&lt;br /&gt;
* &#039;&#039;&#039;MSE:&#039;&#039;&#039; Measures the average squared difference between actual and predicted values.&lt;br /&gt;
* &#039;&#039;&#039;RMSE:&#039;&#039;&#039; Represents the square root of the Mean Squared Error and indicates the typical prediction error in the same unit as temperature.&lt;br /&gt;
* &#039;&#039;&#039;R² Score:&#039;&#039;&#039; Indicates how well the model explains the variation in the target temperature values.&lt;br /&gt;
* &#039;&#039;&#039;future_index:&#039;&#039;&#039; Generates future time-index values for prediction.&lt;br /&gt;
* &#039;&#039;&#039;future_predictions:&#039;&#039;&#039; Contains the temperature values predicted by the trained model.&lt;br /&gt;
* &#039;&#039;&#039;plt.plot():&#039;&#039;&#039; Creates graphs showing the actual, predicted and future temperature values.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Connect the DHT11 sensor to the ESP32 according to the pin connection table.&lt;br /&gt;
# Connect the ESP32 to the computer using a USB cable.&lt;br /&gt;
# Configure the Wi-Fi network and Cognifront Cloud API key in the ESP32 program.&lt;br /&gt;
# Upload the IoT data collection program to the ESP32.&lt;br /&gt;
# Allow the ESP32 to collect temperature readings from the DHT11 sensor.&lt;br /&gt;
# Verify that the temperature readings are being transmitted to the Cognifront Cloud platform.&lt;br /&gt;
# Collect a sufficient number of temperature readings.&lt;br /&gt;
# Export the collected sensor data from the cloud platform as a CSV file.&lt;br /&gt;
# Open Jupyter Notebook, Google Colab or VS Code.&lt;br /&gt;
# Install the required Python libraries.&lt;br /&gt;
# Load the exported temperature dataset using Pandas.&lt;br /&gt;
# Convert the Date and Value columns into suitable data types.&lt;br /&gt;
# Remove invalid or missing records.&lt;br /&gt;
# Sort the dataset according to the timestamp.&lt;br /&gt;
# Create a numerical time index for the machine learning model.&lt;br /&gt;
# Divide the dataset into training and testing subsets.&lt;br /&gt;
# Create and train the Linear Regression model.&lt;br /&gt;
# Predict the temperature values for the testing dataset.&lt;br /&gt;
# Calculate the MAE, MSE, RMSE and R² evaluation metrics.&lt;br /&gt;
# Generate future time-index values.&lt;br /&gt;
# Use the trained model to predict future temperature values.&lt;br /&gt;
# Plot the actual and predicted temperature values.&lt;br /&gt;
# Plot the future temperature predictions.&lt;br /&gt;
# Observe the performance of the machine learning model.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Parameter&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Sensor&lt;br /&gt;
| DHT11&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| IoT device&lt;br /&gt;
| ESP32&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Communication&lt;br /&gt;
| Wi-Fi&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Cloud platform&lt;br /&gt;
| Cognifront Cloud&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Dataset&lt;br /&gt;
| DHT11 temperature CSV dataset&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Machine learning model&lt;br /&gt;
| Linear Regression&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Training data&lt;br /&gt;
| Record the number of training samples&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Testing data&lt;br /&gt;
| Record the number of testing samples&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| MAE&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| RMSE&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| R² Score&lt;br /&gt;
| Record the calculated value&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Future temperature&lt;br /&gt;
| Record the predicted values&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An illustrative output may appear as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Model Evaluation&lt;br /&gt;
MAE: [calculated value]&lt;br /&gt;
MSE: [calculated value]&lt;br /&gt;
RMSE: [calculated value]&lt;br /&gt;
R2 Score: [calculated value]&lt;br /&gt;
&lt;br /&gt;
Future Temperature Predictions&lt;br /&gt;
&lt;br /&gt;
   Time_Index   Predicted_Temperature&lt;br /&gt;
0        ...             ...&lt;br /&gt;
1        ...             ...&lt;br /&gt;
2        ...             ...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The actual values depend on the temperature dataset collected from the IoT sensor.&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT application successfully collected temperature data from the DHT11 sensor using the ESP32 and transmitted the data to the Cognifront Cloud platform. The collected sensor data was exported as a CSV dataset and used to train a Linear Regression machine learning model. The trained model was used to predict future temperature values, and the actual and predicted temperature values were visualized.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is an IoT system?&lt;br /&gt;
# What is the role of the DHT11 sensor in this experiment?&lt;br /&gt;
# Why is an ESP32 used as the IoT device?&lt;br /&gt;
# How is the sensor data transmitted to the cloud?&lt;br /&gt;
# What is machine learning?&lt;br /&gt;
# What is supervised learning?&lt;br /&gt;
# What is Linear Regression?&lt;br /&gt;
# What are the independent and dependent variables in this experiment?&lt;br /&gt;
# Why is the timestamp converted into a numerical time index?&lt;br /&gt;
# What is the purpose of splitting the dataset into training and testing data?&lt;br /&gt;
# What is the purpose of the training dataset?&lt;br /&gt;
# What is the purpose of the testing dataset?&lt;br /&gt;
# What is MAE?&lt;br /&gt;
# What is MSE?&lt;br /&gt;
# What is RMSE?&lt;br /&gt;
# What does the R² score represent?&lt;br /&gt;
# What is the difference between prediction and actual sensor measurement?&lt;br /&gt;
# Why is historical sensor data required for machine learning?&lt;br /&gt;
# What factors can affect the accuracy of temperature prediction?&lt;br /&gt;
# Why might Linear Regression not perform well for rapidly changing temperature data?&lt;br /&gt;
# How could the prediction system be improved using another machine learning model?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1351</id>
		<title>MDM331AID/Experiment 9</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1351"/>
		<updated>2026-10-07T06:53:27Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Code Explanation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Perform Data Cleaning, Normalization, and Visualization on IoT Sensor Dataset =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To perform data cleaning, normalization, and visualization on an IoT sensor dataset and prepare the data for further analysis.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of data preprocessing in IoT applications.&lt;br /&gt;
* To inspect and identify missing, duplicate, inconsistent, and anomalous sensor data.&lt;br /&gt;
* To clean an IoT sensor dataset using appropriate data-cleaning techniques.&lt;br /&gt;
* To normalize sensor values to a standard numerical range.&lt;br /&gt;
* To visualize sensor data using suitable graphs.&lt;br /&gt;
* To compare the dataset before and after data cleaning and normalization.&lt;br /&gt;
* To understand how data preprocessing improves the quality and usability of IoT sensor data.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| IoT sensor dataset in CSV format&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jupyter Notebook / Google Colab / Python IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Pandas library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| NumPy library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Matplotlib library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data preprocessing&#039;&#039;&#039; is the process of preparing raw data for analysis by identifying and correcting problems such as missing values, duplicate records, incorrect data types, inconsistent values, and anomalous observations.&lt;br /&gt;
&lt;br /&gt;
IoT systems continuously generate sensor data. The collected data may contain errors due to sensor limitations, communication problems, transmission errors, incorrect entries, or abnormal operating conditions. Therefore, raw IoT data should be cleaned and transformed before it is used for analysis or visualization.&lt;br /&gt;
&lt;br /&gt;
The main stages of data preprocessing performed in this experiment are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Data inspection:&#039;&#039;&#039; Examining the structure, columns, data types, number of records, and statistical properties of the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Data cleaning:&#039;&#039;&#039; Identifying and handling missing values, duplicate records, invalid values, and anomalous observations.&lt;br /&gt;
* &#039;&#039;&#039;Data transformation:&#039;&#039;&#039; Converting data into suitable formats for analysis, such as converting timestamp values into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;Data normalization:&#039;&#039;&#039; Scaling numerical sensor values to a standard range so that they can be compared and processed more easily.&lt;br /&gt;
* &#039;&#039;&#039;Data visualization:&#039;&#039;&#039; Representing the processed data graphically to identify patterns, trends, variations, and anomalies.&lt;br /&gt;
&lt;br /&gt;
The dataset used in this experiment is an IoT temperature dataset obtained from the Cognifront cloud platform. The dataset contains the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Column&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| ID&lt;br /&gt;
| Unique record identifier generated for the sensor data record&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| Name of the sensor variable. In this dataset, it is DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Value&lt;br /&gt;
| Temperature value recorded by the sensor&lt;br /&gt;
|-&lt;br /&gt;
| Date&lt;br /&gt;
| Date and time at which the sensor reading was recorded&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The original dataset contains &#039;&#039;&#039;547 records&#039;&#039;&#039; and four columns: ID, Name, Value and Date. The Value column contains temperature readings, while the Date column contains the corresponding timestamps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing values&#039;&#039;&#039; are records where one or more required fields contain no valid value. Missing values may be removed or replaced depending on the nature of the dataset and the purpose of the analysis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Duplicate records&#039;&#039;&#039; are repeated records that contain the same data more than once. Duplicate records can occur because of repeated data transmission or storage operations and may need to be removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anomalies&#039;&#039;&#039; are observations that differ significantly from the normal pattern of the dataset. In a temperature dataset, an unusually high or low value may represent a sensor error, transmission error, or abnormal environmental condition. Anomalies should be investigated before deciding whether they should be removed, corrected, or retained.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normalization&#039;&#039;&#039; is the process of transforming numerical values to a common scale. In this experiment, Min-Max normalization is used to transform the temperature values into the range 0 to 1.&lt;br /&gt;
&lt;br /&gt;
The Min-Max normalization formula is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;X&#039;&#039;&#039; is the original sensor value.&lt;br /&gt;
* &#039;&#039;&#039;Xmin&#039;&#039;&#039; is the minimum value in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Xmax&#039;&#039;&#039; is the maximum value in the dataset.&lt;br /&gt;
&lt;br /&gt;
After normalization, the smallest value becomes 0 and the largest value becomes 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data visualization&#039;&#039;&#039; is used to represent the processed sensor data graphically. A line graph can be used to show temperature variation with time, while a histogram can be used to observe the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
The overall data-processing flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raw IoT CSV Dataset&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Inspection&lt;br /&gt;
        ↓&lt;br /&gt;
    Data Cleaning&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Transformation&lt;br /&gt;
        ↓&lt;br /&gt;
     Normalization&lt;br /&gt;
        ↓&lt;br /&gt;
     Visualization&lt;br /&gt;
        ↓&lt;br /&gt;
  Processed Dataset&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dataset Used ==&lt;br /&gt;
&lt;br /&gt;
The dataset used for this experiment is a DHT11 temperature dataset exported from the Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
The original dataset contains:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Number of records&lt;br /&gt;
| 547&lt;br /&gt;
|-&lt;br /&gt;
| Number of columns&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| Sensor variable&lt;br /&gt;
| DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Minimum temperature&lt;br /&gt;
| 27.1 °C&lt;br /&gt;
|-&lt;br /&gt;
| Maximum temperature&lt;br /&gt;
| 27.8 °C&lt;br /&gt;
|-&lt;br /&gt;
| Missing values&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate timestamps&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries before running the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program loads the IoT dataset, inspects the data, performs data cleaning, normalizes the temperature values using Min-Max normalization, and generates visualizations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from google.colab import files&lt;br /&gt;
dht_data = files.upload()&lt;br /&gt;
&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
# Load the dataset&lt;br /&gt;
df = pd.read_csv(&#039;anomalous-dht11-data.csv&#039;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDataset Information&amp;quot;)&lt;br /&gt;
print(df.info())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nMissing Values&amp;quot;)&lt;br /&gt;
print(df.isnull().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDuplicate Records&amp;quot;)&lt;br /&gt;
print(df.duplicated().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nStatistical Summary&amp;quot;)&lt;br /&gt;
print(df.describe())&lt;br /&gt;
&lt;br /&gt;
# Convert Date column to datetime&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(df[&amp;quot;Date&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Convert Value column to numeric&lt;br /&gt;
df[&amp;quot;Value&amp;quot;] = pd.to_numeric(df[&amp;quot;Value&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remove rows with missing required values&lt;br /&gt;
df = df.dropna(subset=[&amp;quot;ID&amp;quot;, &amp;quot;Name&amp;quot;, &amp;quot;Value&amp;quot;, &amp;quot;Date&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
# Remove duplicate records&lt;br /&gt;
df = df.drop_duplicates()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;# Now to remove *outliers*, we will use 2 methods:&lt;br /&gt;
&lt;br /&gt;
1.  Using IQR (Interquartile Range) method&lt;br /&gt;
2.  Using Domain-based method&lt;br /&gt;
&lt;br /&gt;
For our particular dataset, you will see why Domain-based method is more applicable by looking at the output of IQR method.&lt;br /&gt;
&lt;br /&gt;
**1) IQR (Interquartile Range) method**&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Detect temperature outliers using IQR&lt;br /&gt;
Q1 = df[&amp;quot;Value&amp;quot;].quantile(0.25)&lt;br /&gt;
Q3 = df[&amp;quot;Value&amp;quot;].quantile(0.75)&lt;br /&gt;
IQR = Q3 - Q1&lt;br /&gt;
&lt;br /&gt;
lower_limit = Q1 - 1.5 * IQR&lt;br /&gt;
upper_limit = Q3 + 1.5 * IQR&lt;br /&gt;
&lt;br /&gt;
outliers = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt; lower_limit) |&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt; upper_limit)&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDetected Outliers&amp;quot;)&lt;br /&gt;
print(outliers)&lt;br /&gt;
&lt;br /&gt;
# Remove detected outliers&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;**2) Domain-based method**&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lower_limit = 15&lt;br /&gt;
upper_limit = 50&lt;br /&gt;
&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
# Min-Max normalization&lt;br /&gt;
min_value = df_clean[&amp;quot;Value&amp;quot;].min()&lt;br /&gt;
max_value = df_clean[&amp;quot;Value&amp;quot;].max()&lt;br /&gt;
&lt;br /&gt;
df_clean[&amp;quot;Normalized_Value&amp;quot;] = (&lt;br /&gt;
    (df_clean[&amp;quot;Value&amp;quot;] - min_value) /&lt;br /&gt;
    (max_value - min_value)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Save cleaned and normalized dataset&lt;br /&gt;
df_clean.to_csv(&lt;br /&gt;
    &amp;quot;cleaned_normalized_dht11_data.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nCleaned Dataset&amp;quot;)&lt;br /&gt;
print(df_clean.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nNormalized Dataset&amp;quot;)&lt;br /&gt;
print(df_clean[[&amp;quot;Value&amp;quot;, &amp;quot;Normalized_Value&amp;quot;]].head())&lt;br /&gt;
&lt;br /&gt;
# Visualization 1: Temperature vs Time&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 2: Temperature distribution&lt;br /&gt;
plt.figure(figsize=(8, 5))&lt;br /&gt;
&lt;br /&gt;
plt.hist(&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    bins=10&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Frequency&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Distribution of DHT11 Temperature Values&amp;quot;)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 3: Normalized temperature&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Normalized_Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Normalized Temperature&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Normalized DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;files.upload():&#039;&#039;&#039; Opens a file-upload interface in Google Colab so that the IoT sensor CSV dataset can be uploaded.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the uploaded CSV dataset into a Pandas DataFrame.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.head():&#039;&#039;&#039; Displays the first few records of the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.info():&#039;&#039;&#039; Displays information about the columns, data types and number of non-null records.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;isnull().sum():&#039;&#039;&#039; Counts the number of missing values in each column.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;duplicated().sum():&#039;&#039;&#039; Counts the number of duplicate records in the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df.describe():&#039;&#039;&#039; Displays statistical information such as count, mean, standard deviation, minimum and maximum values of numerical columns.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a proper date-time format. Invalid date values are converted to missing values using &#039;&#039;&#039;errors=&amp;quot;coerce&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the Value column into numerical data. Invalid values are converted to missing values using &#039;&#039;&#039;errors=&amp;quot;coerce&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records containing missing values in the required ID, Name, Value or Date fields.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;drop_duplicates():&#039;&#039;&#039; Removes duplicate records from the dataset.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Q1 and Q3:&#039;&#039;&#039; Represent the first and third quartiles of the temperature data and are used for IQR-based outlier detection.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR:&#039;&#039;&#039; Represents the Interquartile Range and is calculated as Q3 − Q1.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR outlier limits:&#039;&#039;&#039; Values below Q1 − 1.5 × IQR or above Q3 + 1.5 × IQR are identified as potential outliers.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;IQR outlier detection:&#039;&#039;&#039; Identifies and displays potential outliers using the statistical IQR method. In this experiment, the IQR method is demonstrated for comparison but is not used for the final cleaning because the normal temperature readings are closely clustered.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Domain-based outlier detection:&#039;&#039;&#039; Defines an acceptable temperature range of 15 °C to 50 °C. Values outside this range are treated as anomalous temperature readings.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;df_clean:&#039;&#039;&#039; Stores the final cleaned dataset after applying the domain-based temperature limits.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Min-Max normalization:&#039;&#039;&#039; Transforms the cleaned temperature values into the range 0 to 1 using the formula:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;to_csv():&#039;&#039;&#039; Saves the cleaned and normalized dataset as a new CSV file named &#039;&#039;&#039;cleaned_normalized_dht11_data.csv&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plt.plot():&#039;&#039;&#039; Creates a line graph showing the variation of temperature with respect to date and time.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;plt.hist():&#039;&#039;&#039; Creates a histogram showing the distribution and frequency of the cleaned temperature values.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Normalized temperature plot:&#039;&#039;&#039; Displays the normalized temperature values against time to show the sensor readings after Min-Max normalization.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Obtain the DHT11 sensor dataset in CSV format from the Cognifront cloud platform.&lt;br /&gt;
# Make a copy of the original CSV file and use the copy for data-cleaning experiments.&lt;br /&gt;
# Open the Python environment such as Jupyter Notebook, Google Colab or a Python IDE.&lt;br /&gt;
# Install the required Pandas, NumPy and Matplotlib libraries.&lt;br /&gt;
# Load the CSV dataset using Pandas.&lt;br /&gt;
# Inspect the dataset and identify its columns, data types and number of records.&lt;br /&gt;
# Check the dataset for missing values.&lt;br /&gt;
# Check the dataset for duplicate records.&lt;br /&gt;
# Convert the Date column into the appropriate date-time format.&lt;br /&gt;
# Convert the sensor Value column into numerical format.&lt;br /&gt;
# Identify anomalous sensor values using statistical methods such as the IQR method.&lt;br /&gt;
# Remove or handle the identified invalid or anomalous records as required.&lt;br /&gt;
# Normalize the cleaned sensor values using Min-Max normalization.&lt;br /&gt;
# Save the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
# Plot the temperature values against time using a line graph.&lt;br /&gt;
# Plot the distribution of temperature values using a histogram.&lt;br /&gt;
# Plot the normalized temperature values against time.&lt;br /&gt;
# Compare the original and processed datasets and observe the effect of data cleaning and normalization.&lt;br /&gt;
&lt;br /&gt;
== Introducing Manual Anomalies ==&lt;br /&gt;
&lt;br /&gt;
The original Cognifront dataset is relatively clean. Therefore, for demonstrating data-cleaning techniques, controlled anomalies can be introduced into a &#039;&#039;&#039;copy&#039;&#039;&#039; of the original dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not modify the original downloaded dataset.&#039;&#039;&#039; Keep the original file as the raw dataset and create a separate file such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dht11-data-logger-dht-temp-anomalous.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following anomalies can be introduced for demonstration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Anomaly&lt;br /&gt;
! Example&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Missing value&lt;br /&gt;
| Replace a Value entry with an empty cell&lt;br /&gt;
| Demonstrates missing-value handling&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate record&lt;br /&gt;
| Copy one complete row and insert it again&lt;br /&gt;
| Demonstrates duplicate detection&lt;br /&gt;
|-&lt;br /&gt;
| Extreme temperature&lt;br /&gt;
| Change one Value to 80 °C&lt;br /&gt;
| Demonstrates outlier detection&lt;br /&gt;
|-&lt;br /&gt;
| Very low temperature&lt;br /&gt;
| Change one Value to -20 °C&lt;br /&gt;
| Demonstrates anomalous-value detection&lt;br /&gt;
|-&lt;br /&gt;
| Invalid value&lt;br /&gt;
| Replace one Value with text such as &amp;quot;ERROR&amp;quot;&lt;br /&gt;
| Demonstrates invalid data handling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, if the original data contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,27.5,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the Value can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,80,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, another record can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296950,DHT-Temp,,2026-10-07 08:51:15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to demonstrate a missing sensor value.&lt;br /&gt;
&lt;br /&gt;
An existing row can also be copied and inserted again to create a duplicate record.&lt;br /&gt;
&lt;br /&gt;
The modified dataset can then be processed using the Python program. The program should identify the missing, duplicate and anomalous records and produce a cleaned dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These manually introduced anomalies are artificial and are used only to demonstrate data-cleaning techniques. They should not be presented as actual errors produced by the DHT11 sensor or Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Operation&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Dataset inspection&lt;br /&gt;
| Dataset contains 547 records and 4 columns&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Missing-value check&lt;br /&gt;
| Original dataset contains no missing values&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Duplicate check&lt;br /&gt;
| Original dataset contains no duplicate records&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Data type conversion&lt;br /&gt;
| Date converted to datetime and Value converted to numeric&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Anomaly detection&lt;br /&gt;
| Artificial anomalous records are identified in the modified dataset&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Data cleaning&lt;br /&gt;
| Missing, duplicate and anomalous records are handled&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Normalization&lt;br /&gt;
| Temperature values are converted to the range 0 to 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Visualization&lt;br /&gt;
| Temperature variation and distribution are represented graphically&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| CSV export&lt;br /&gt;
| Cleaned and normalized data is saved as a new CSV file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT sensor dataset was successfully inspected, cleaned and normalized using Python. Missing values, duplicate records and anomalous sensor readings were identified and handled. The temperature values were normalized using Min-Max normalization, and the processed data was visualized using suitable graphs. The cleaned and normalized dataset was successfully exported as a CSV file.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is data preprocessing?&lt;br /&gt;
# Why is data cleaning required for IoT sensor data?&lt;br /&gt;
# What is the difference between raw data and cleaned data?&lt;br /&gt;
# What is a missing value?&lt;br /&gt;
# What is a duplicate record?&lt;br /&gt;
# What is an anomaly in a sensor dataset?&lt;br /&gt;
# Why are artificial anomalies introduced during this experiment?&lt;br /&gt;
# What is the IQR method?&lt;br /&gt;
# How is an outlier detected using the IQR method?&lt;br /&gt;
# What is data normalization?&lt;br /&gt;
# What is Min-Max normalization?&lt;br /&gt;
# What is the range of values produced by Min-Max normalization?&lt;br /&gt;
# Why is the Date column converted into datetime format?&lt;br /&gt;
# What is the purpose of the Pandas library?&lt;br /&gt;
# What is the purpose of NumPy?&lt;br /&gt;
# What is Matplotlib used for?&lt;br /&gt;
# What is the purpose of a histogram?&lt;br /&gt;
# What information can be obtained from a line graph of sensor data?&lt;br /&gt;
# Why should the original dataset be preserved before data cleaning?&lt;br /&gt;
# Why should manually introduced anomalies not be considered actual sensor errors?&lt;br /&gt;
# What is the purpose of exporting the processed dataset as a CSV file?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1350</id>
		<title>MDM331AID/Experiment 9</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1350"/>
		<updated>2026-10-07T06:49:31Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Program */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Perform Data Cleaning, Normalization, and Visualization on IoT Sensor Dataset =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To perform data cleaning, normalization, and visualization on an IoT sensor dataset and prepare the data for further analysis.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of data preprocessing in IoT applications.&lt;br /&gt;
* To inspect and identify missing, duplicate, inconsistent, and anomalous sensor data.&lt;br /&gt;
* To clean an IoT sensor dataset using appropriate data-cleaning techniques.&lt;br /&gt;
* To normalize sensor values to a standard numerical range.&lt;br /&gt;
* To visualize sensor data using suitable graphs.&lt;br /&gt;
* To compare the dataset before and after data cleaning and normalization.&lt;br /&gt;
* To understand how data preprocessing improves the quality and usability of IoT sensor data.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| IoT sensor dataset in CSV format&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jupyter Notebook / Google Colab / Python IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Pandas library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| NumPy library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Matplotlib library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data preprocessing&#039;&#039;&#039; is the process of preparing raw data for analysis by identifying and correcting problems such as missing values, duplicate records, incorrect data types, inconsistent values, and anomalous observations.&lt;br /&gt;
&lt;br /&gt;
IoT systems continuously generate sensor data. The collected data may contain errors due to sensor limitations, communication problems, transmission errors, incorrect entries, or abnormal operating conditions. Therefore, raw IoT data should be cleaned and transformed before it is used for analysis or visualization.&lt;br /&gt;
&lt;br /&gt;
The main stages of data preprocessing performed in this experiment are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Data inspection:&#039;&#039;&#039; Examining the structure, columns, data types, number of records, and statistical properties of the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Data cleaning:&#039;&#039;&#039; Identifying and handling missing values, duplicate records, invalid values, and anomalous observations.&lt;br /&gt;
* &#039;&#039;&#039;Data transformation:&#039;&#039;&#039; Converting data into suitable formats for analysis, such as converting timestamp values into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;Data normalization:&#039;&#039;&#039; Scaling numerical sensor values to a standard range so that they can be compared and processed more easily.&lt;br /&gt;
* &#039;&#039;&#039;Data visualization:&#039;&#039;&#039; Representing the processed data graphically to identify patterns, trends, variations, and anomalies.&lt;br /&gt;
&lt;br /&gt;
The dataset used in this experiment is an IoT temperature dataset obtained from the Cognifront cloud platform. The dataset contains the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Column&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| ID&lt;br /&gt;
| Unique record identifier generated for the sensor data record&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| Name of the sensor variable. In this dataset, it is DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Value&lt;br /&gt;
| Temperature value recorded by the sensor&lt;br /&gt;
|-&lt;br /&gt;
| Date&lt;br /&gt;
| Date and time at which the sensor reading was recorded&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The original dataset contains &#039;&#039;&#039;547 records&#039;&#039;&#039; and four columns: ID, Name, Value and Date. The Value column contains temperature readings, while the Date column contains the corresponding timestamps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing values&#039;&#039;&#039; are records where one or more required fields contain no valid value. Missing values may be removed or replaced depending on the nature of the dataset and the purpose of the analysis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Duplicate records&#039;&#039;&#039; are repeated records that contain the same data more than once. Duplicate records can occur because of repeated data transmission or storage operations and may need to be removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anomalies&#039;&#039;&#039; are observations that differ significantly from the normal pattern of the dataset. In a temperature dataset, an unusually high or low value may represent a sensor error, transmission error, or abnormal environmental condition. Anomalies should be investigated before deciding whether they should be removed, corrected, or retained.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normalization&#039;&#039;&#039; is the process of transforming numerical values to a common scale. In this experiment, Min-Max normalization is used to transform the temperature values into the range 0 to 1.&lt;br /&gt;
&lt;br /&gt;
The Min-Max normalization formula is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;X&#039;&#039;&#039; is the original sensor value.&lt;br /&gt;
* &#039;&#039;&#039;Xmin&#039;&#039;&#039; is the minimum value in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Xmax&#039;&#039;&#039; is the maximum value in the dataset.&lt;br /&gt;
&lt;br /&gt;
After normalization, the smallest value becomes 0 and the largest value becomes 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data visualization&#039;&#039;&#039; is used to represent the processed sensor data graphically. A line graph can be used to show temperature variation with time, while a histogram can be used to observe the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
The overall data-processing flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raw IoT CSV Dataset&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Inspection&lt;br /&gt;
        ↓&lt;br /&gt;
    Data Cleaning&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Transformation&lt;br /&gt;
        ↓&lt;br /&gt;
     Normalization&lt;br /&gt;
        ↓&lt;br /&gt;
     Visualization&lt;br /&gt;
        ↓&lt;br /&gt;
  Processed Dataset&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dataset Used ==&lt;br /&gt;
&lt;br /&gt;
The dataset used for this experiment is a DHT11 temperature dataset exported from the Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
The original dataset contains:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Number of records&lt;br /&gt;
| 547&lt;br /&gt;
|-&lt;br /&gt;
| Number of columns&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| Sensor variable&lt;br /&gt;
| DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Minimum temperature&lt;br /&gt;
| 27.1 °C&lt;br /&gt;
|-&lt;br /&gt;
| Maximum temperature&lt;br /&gt;
| 27.8 °C&lt;br /&gt;
|-&lt;br /&gt;
| Missing values&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate timestamps&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries before running the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program loads the IoT dataset, inspects the data, performs data cleaning, normalizes the temperature values using Min-Max normalization, and generates visualizations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from google.colab import files&lt;br /&gt;
dht_data = files.upload()&lt;br /&gt;
&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
# Load the dataset&lt;br /&gt;
df = pd.read_csv(&#039;anomalous-dht11-data.csv&#039;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDataset Information&amp;quot;)&lt;br /&gt;
print(df.info())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nMissing Values&amp;quot;)&lt;br /&gt;
print(df.isnull().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDuplicate Records&amp;quot;)&lt;br /&gt;
print(df.duplicated().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nStatistical Summary&amp;quot;)&lt;br /&gt;
print(df.describe())&lt;br /&gt;
&lt;br /&gt;
# Convert Date column to datetime&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(df[&amp;quot;Date&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Convert Value column to numeric&lt;br /&gt;
df[&amp;quot;Value&amp;quot;] = pd.to_numeric(df[&amp;quot;Value&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remove rows with missing required values&lt;br /&gt;
df = df.dropna(subset=[&amp;quot;ID&amp;quot;, &amp;quot;Name&amp;quot;, &amp;quot;Value&amp;quot;, &amp;quot;Date&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
# Remove duplicate records&lt;br /&gt;
df = df.drop_duplicates()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;# Now to remove *outliers*, we will use 2 methods:&lt;br /&gt;
&lt;br /&gt;
1.  Using IQR (Interquartile Range) method&lt;br /&gt;
2.  Using Domain-based method&lt;br /&gt;
&lt;br /&gt;
For our particular dataset, you will see why Domain-based method is more applicable by looking at the output of IQR method.&lt;br /&gt;
&lt;br /&gt;
**1) IQR (Interquartile Range) method**&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# Detect temperature outliers using IQR&lt;br /&gt;
Q1 = df[&amp;quot;Value&amp;quot;].quantile(0.25)&lt;br /&gt;
Q3 = df[&amp;quot;Value&amp;quot;].quantile(0.75)&lt;br /&gt;
IQR = Q3 - Q1&lt;br /&gt;
&lt;br /&gt;
lower_limit = Q1 - 1.5 * IQR&lt;br /&gt;
upper_limit = Q3 + 1.5 * IQR&lt;br /&gt;
&lt;br /&gt;
outliers = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt; lower_limit) |&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt; upper_limit)&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDetected Outliers&amp;quot;)&lt;br /&gt;
print(outliers)&lt;br /&gt;
&lt;br /&gt;
# Remove detected outliers&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;**2) Domain-based method**&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
lower_limit = 15&lt;br /&gt;
upper_limit = 50&lt;br /&gt;
&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
# Min-Max normalization&lt;br /&gt;
min_value = df_clean[&amp;quot;Value&amp;quot;].min()&lt;br /&gt;
max_value = df_clean[&amp;quot;Value&amp;quot;].max()&lt;br /&gt;
&lt;br /&gt;
df_clean[&amp;quot;Normalized_Value&amp;quot;] = (&lt;br /&gt;
    (df_clean[&amp;quot;Value&amp;quot;] - min_value) /&lt;br /&gt;
    (max_value - min_value)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Save cleaned and normalized dataset&lt;br /&gt;
df_clean.to_csv(&lt;br /&gt;
    &amp;quot;cleaned_normalized_dht11_data.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nCleaned Dataset&amp;quot;)&lt;br /&gt;
print(df_clean.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nNormalized Dataset&amp;quot;)&lt;br /&gt;
print(df_clean[[&amp;quot;Value&amp;quot;, &amp;quot;Normalized_Value&amp;quot;]].head())&lt;br /&gt;
&lt;br /&gt;
# Visualization 1: Temperature vs Time&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 2: Temperature distribution&lt;br /&gt;
plt.figure(figsize=(8, 5))&lt;br /&gt;
&lt;br /&gt;
plt.hist(&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    bins=10&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Frequency&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Distribution of DHT11 Temperature Values&amp;quot;)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 3: Normalized temperature&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Normalized_Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Normalized Temperature&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Normalized DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the IoT sensor dataset from the CSV file.&lt;br /&gt;
* &#039;&#039;&#039;df.info():&#039;&#039;&#039; Displays information about the columns, data types and number of non-null records.&lt;br /&gt;
* &#039;&#039;&#039;isnull().sum():&#039;&#039;&#039; Counts the missing values in each column.&lt;br /&gt;
* &#039;&#039;&#039;duplicated():&#039;&#039;&#039; Identifies duplicate records in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the sensor Value column into numerical data.&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records containing missing values in required fields.&lt;br /&gt;
* &#039;&#039;&#039;drop_duplicates():&#039;&#039;&#039; Removes duplicate records.&lt;br /&gt;
* &#039;&#039;&#039;Q1 and Q3:&#039;&#039;&#039; Represent the first and third quartiles of the temperature data.&lt;br /&gt;
* &#039;&#039;&#039;IQR:&#039;&#039;&#039; Represents the interquartile range and is calculated as Q3 − Q1.&lt;br /&gt;
* &#039;&#039;&#039;Outlier limits:&#039;&#039;&#039; Values outside Q1 − 1.5 × IQR and Q3 + 1.5 × IQR are identified as potential outliers.&lt;br /&gt;
* &#039;&#039;&#039;Min-Max normalization:&#039;&#039;&#039; Converts the temperature values into the range 0 to 1.&lt;br /&gt;
* &#039;&#039;&#039;to_csv():&#039;&#039;&#039; Saves the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
* &#039;&#039;&#039;plt.plot():&#039;&#039;&#039; Creates a line graph showing the variation of sensor values.&lt;br /&gt;
* &#039;&#039;&#039;plt.hist():&#039;&#039;&#039; Creates a histogram showing the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Obtain the DHT11 sensor dataset in CSV format from the Cognifront cloud platform.&lt;br /&gt;
# Make a copy of the original CSV file and use the copy for data-cleaning experiments.&lt;br /&gt;
# Open the Python environment such as Jupyter Notebook, Google Colab or a Python IDE.&lt;br /&gt;
# Install the required Pandas, NumPy and Matplotlib libraries.&lt;br /&gt;
# Load the CSV dataset using Pandas.&lt;br /&gt;
# Inspect the dataset and identify its columns, data types and number of records.&lt;br /&gt;
# Check the dataset for missing values.&lt;br /&gt;
# Check the dataset for duplicate records.&lt;br /&gt;
# Convert the Date column into the appropriate date-time format.&lt;br /&gt;
# Convert the sensor Value column into numerical format.&lt;br /&gt;
# Identify anomalous sensor values using statistical methods such as the IQR method.&lt;br /&gt;
# Remove or handle the identified invalid or anomalous records as required.&lt;br /&gt;
# Normalize the cleaned sensor values using Min-Max normalization.&lt;br /&gt;
# Save the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
# Plot the temperature values against time using a line graph.&lt;br /&gt;
# Plot the distribution of temperature values using a histogram.&lt;br /&gt;
# Plot the normalized temperature values against time.&lt;br /&gt;
# Compare the original and processed datasets and observe the effect of data cleaning and normalization.&lt;br /&gt;
&lt;br /&gt;
== Introducing Manual Anomalies ==&lt;br /&gt;
&lt;br /&gt;
The original Cognifront dataset is relatively clean. Therefore, for demonstrating data-cleaning techniques, controlled anomalies can be introduced into a &#039;&#039;&#039;copy&#039;&#039;&#039; of the original dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not modify the original downloaded dataset.&#039;&#039;&#039; Keep the original file as the raw dataset and create a separate file such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dht11-data-logger-dht-temp-anomalous.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following anomalies can be introduced for demonstration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Anomaly&lt;br /&gt;
! Example&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Missing value&lt;br /&gt;
| Replace a Value entry with an empty cell&lt;br /&gt;
| Demonstrates missing-value handling&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate record&lt;br /&gt;
| Copy one complete row and insert it again&lt;br /&gt;
| Demonstrates duplicate detection&lt;br /&gt;
|-&lt;br /&gt;
| Extreme temperature&lt;br /&gt;
| Change one Value to 80 °C&lt;br /&gt;
| Demonstrates outlier detection&lt;br /&gt;
|-&lt;br /&gt;
| Very low temperature&lt;br /&gt;
| Change one Value to -20 °C&lt;br /&gt;
| Demonstrates anomalous-value detection&lt;br /&gt;
|-&lt;br /&gt;
| Invalid value&lt;br /&gt;
| Replace one Value with text such as &amp;quot;ERROR&amp;quot;&lt;br /&gt;
| Demonstrates invalid data handling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, if the original data contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,27.5,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the Value can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,80,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, another record can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296950,DHT-Temp,,2026-10-07 08:51:15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to demonstrate a missing sensor value.&lt;br /&gt;
&lt;br /&gt;
An existing row can also be copied and inserted again to create a duplicate record.&lt;br /&gt;
&lt;br /&gt;
The modified dataset can then be processed using the Python program. The program should identify the missing, duplicate and anomalous records and produce a cleaned dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These manually introduced anomalies are artificial and are used only to demonstrate data-cleaning techniques. They should not be presented as actual errors produced by the DHT11 sensor or Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Operation&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Dataset inspection&lt;br /&gt;
| Dataset contains 547 records and 4 columns&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Missing-value check&lt;br /&gt;
| Original dataset contains no missing values&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Duplicate check&lt;br /&gt;
| Original dataset contains no duplicate records&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Data type conversion&lt;br /&gt;
| Date converted to datetime and Value converted to numeric&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Anomaly detection&lt;br /&gt;
| Artificial anomalous records are identified in the modified dataset&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Data cleaning&lt;br /&gt;
| Missing, duplicate and anomalous records are handled&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Normalization&lt;br /&gt;
| Temperature values are converted to the range 0 to 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Visualization&lt;br /&gt;
| Temperature variation and distribution are represented graphically&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| CSV export&lt;br /&gt;
| Cleaned and normalized data is saved as a new CSV file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT sensor dataset was successfully inspected, cleaned and normalized using Python. Missing values, duplicate records and anomalous sensor readings were identified and handled. The temperature values were normalized using Min-Max normalization, and the processed data was visualized using suitable graphs. The cleaned and normalized dataset was successfully exported as a CSV file.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is data preprocessing?&lt;br /&gt;
# Why is data cleaning required for IoT sensor data?&lt;br /&gt;
# What is the difference between raw data and cleaned data?&lt;br /&gt;
# What is a missing value?&lt;br /&gt;
# What is a duplicate record?&lt;br /&gt;
# What is an anomaly in a sensor dataset?&lt;br /&gt;
# Why are artificial anomalies introduced during this experiment?&lt;br /&gt;
# What is the IQR method?&lt;br /&gt;
# How is an outlier detected using the IQR method?&lt;br /&gt;
# What is data normalization?&lt;br /&gt;
# What is Min-Max normalization?&lt;br /&gt;
# What is the range of values produced by Min-Max normalization?&lt;br /&gt;
# Why is the Date column converted into datetime format?&lt;br /&gt;
# What is the purpose of the Pandas library?&lt;br /&gt;
# What is the purpose of NumPy?&lt;br /&gt;
# What is Matplotlib used for?&lt;br /&gt;
# What is the purpose of a histogram?&lt;br /&gt;
# What information can be obtained from a line graph of sensor data?&lt;br /&gt;
# Why should the original dataset be preserved before data cleaning?&lt;br /&gt;
# Why should manually introduced anomalies not be considered actual sensor errors?&lt;br /&gt;
# What is the purpose of exporting the processed dataset as a CSV file?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1349</id>
		<title>MDM331AID/Experiment 9</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_9&amp;diff=1349"/>
		<updated>2026-10-07T05:37:10Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: Created page with &amp;quot;= Experiment: Perform Data Cleaning, Normalization, and Visualization on IoT Sensor Dataset =  == Aim == To perform data cleaning, normalization, and visualization on an IoT sensor dataset and prepare the data for further analysis.  == Objectives == * To understand the importance of data preprocessing in IoT applications. * To inspect and identify missing, duplicate, inconsistent, and anomalous sensor data. * To clean an IoT sensor dataset using appropriate data-cleaning...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Experiment: Perform Data Cleaning, Normalization, and Visualization on IoT Sensor Dataset =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To perform data cleaning, normalization, and visualization on an IoT sensor dataset and prepare the data for further analysis.&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the importance of data preprocessing in IoT applications.&lt;br /&gt;
* To inspect and identify missing, duplicate, inconsistent, and anomalous sensor data.&lt;br /&gt;
* To clean an IoT sensor dataset using appropriate data-cleaning techniques.&lt;br /&gt;
* To normalize sensor values to a standard numerical range.&lt;br /&gt;
* To visualize sensor data using suitable graphs.&lt;br /&gt;
* To compare the dataset before and after data cleaning and normalization.&lt;br /&gt;
* To understand how data preprocessing improves the quality and usability of IoT sensor data.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component / Software&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Computer or laptop&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| IoT sensor dataset in CSV format&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Python&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Jupyter Notebook / Google Colab / Python IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Pandas library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| NumPy library&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Matplotlib library&lt;br /&gt;
| 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data preprocessing&#039;&#039;&#039; is the process of preparing raw data for analysis by identifying and correcting problems such as missing values, duplicate records, incorrect data types, inconsistent values, and anomalous observations.&lt;br /&gt;
&lt;br /&gt;
IoT systems continuously generate sensor data. The collected data may contain errors due to sensor limitations, communication problems, transmission errors, incorrect entries, or abnormal operating conditions. Therefore, raw IoT data should be cleaned and transformed before it is used for analysis or visualization.&lt;br /&gt;
&lt;br /&gt;
The main stages of data preprocessing performed in this experiment are:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Data inspection:&#039;&#039;&#039; Examining the structure, columns, data types, number of records, and statistical properties of the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Data cleaning:&#039;&#039;&#039; Identifying and handling missing values, duplicate records, invalid values, and anomalous observations.&lt;br /&gt;
* &#039;&#039;&#039;Data transformation:&#039;&#039;&#039; Converting data into suitable formats for analysis, such as converting timestamp values into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;Data normalization:&#039;&#039;&#039; Scaling numerical sensor values to a standard range so that they can be compared and processed more easily.&lt;br /&gt;
* &#039;&#039;&#039;Data visualization:&#039;&#039;&#039; Representing the processed data graphically to identify patterns, trends, variations, and anomalies.&lt;br /&gt;
&lt;br /&gt;
The dataset used in this experiment is an IoT temperature dataset obtained from the Cognifront cloud platform. The dataset contains the following fields:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Column&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| ID&lt;br /&gt;
| Unique record identifier generated for the sensor data record&lt;br /&gt;
|-&lt;br /&gt;
| Name&lt;br /&gt;
| Name of the sensor variable. In this dataset, it is DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Value&lt;br /&gt;
| Temperature value recorded by the sensor&lt;br /&gt;
|-&lt;br /&gt;
| Date&lt;br /&gt;
| Date and time at which the sensor reading was recorded&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The original dataset contains &#039;&#039;&#039;547 records&#039;&#039;&#039; and four columns: ID, Name, Value and Date. The Value column contains temperature readings, while the Date column contains the corresponding timestamps.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Missing values&#039;&#039;&#039; are records where one or more required fields contain no valid value. Missing values may be removed or replaced depending on the nature of the dataset and the purpose of the analysis.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Duplicate records&#039;&#039;&#039; are repeated records that contain the same data more than once. Duplicate records can occur because of repeated data transmission or storage operations and may need to be removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anomalies&#039;&#039;&#039; are observations that differ significantly from the normal pattern of the dataset. In a temperature dataset, an unusually high or low value may represent a sensor error, transmission error, or abnormal environmental condition. Anomalies should be investigated before deciding whether they should be removed, corrected, or retained.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Normalization&#039;&#039;&#039; is the process of transforming numerical values to a common scale. In this experiment, Min-Max normalization is used to transform the temperature values into the range 0 to 1.&lt;br /&gt;
&lt;br /&gt;
The Min-Max normalization formula is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Normalized Value = (X - Xmin) / (Xmax - Xmin)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;X&#039;&#039;&#039; is the original sensor value.&lt;br /&gt;
* &#039;&#039;&#039;Xmin&#039;&#039;&#039; is the minimum value in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;Xmax&#039;&#039;&#039; is the maximum value in the dataset.&lt;br /&gt;
&lt;br /&gt;
After normalization, the smallest value becomes 0 and the largest value becomes 1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data visualization&#039;&#039;&#039; is used to represent the processed sensor data graphically. A line graph can be used to show temperature variation with time, while a histogram can be used to observe the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
The overall data-processing flow is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Raw IoT CSV Dataset&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Inspection&lt;br /&gt;
        ↓&lt;br /&gt;
    Data Cleaning&lt;br /&gt;
        ↓&lt;br /&gt;
   Data Transformation&lt;br /&gt;
        ↓&lt;br /&gt;
     Normalization&lt;br /&gt;
        ↓&lt;br /&gt;
     Visualization&lt;br /&gt;
        ↓&lt;br /&gt;
  Processed Dataset&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Dataset Used ==&lt;br /&gt;
&lt;br /&gt;
The dataset used for this experiment is a DHT11 temperature dataset exported from the Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
The original dataset contains:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Parameter&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| Number of records&lt;br /&gt;
| 547&lt;br /&gt;
|-&lt;br /&gt;
| Number of columns&lt;br /&gt;
| 4&lt;br /&gt;
|-&lt;br /&gt;
| Sensor variable&lt;br /&gt;
| DHT-Temp&lt;br /&gt;
|-&lt;br /&gt;
| Minimum temperature&lt;br /&gt;
| 27.1 °C&lt;br /&gt;
|-&lt;br /&gt;
| Maximum temperature&lt;br /&gt;
| 27.8 °C&lt;br /&gt;
|-&lt;br /&gt;
| Missing values&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate timestamps&lt;br /&gt;
| None in the original dataset&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Program ==&lt;br /&gt;
&lt;br /&gt;
Install the required Python libraries before running the program.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
pip install pandas numpy matplotlib&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following program loads the IoT dataset, inspects the data, performs data cleaning, normalizes the temperature values using Min-Max normalization, and generates visualizations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import pandas as pd&lt;br /&gt;
import numpy as np&lt;br /&gt;
import matplotlib.pyplot as plt&lt;br /&gt;
&lt;br /&gt;
# Load the dataset&lt;br /&gt;
df = pd.read_csv(&amp;quot;dht11-data-logger-dht-temp.csv&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;Original Dataset&amp;quot;)&lt;br /&gt;
print(df.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDataset Information&amp;quot;)&lt;br /&gt;
print(df.info())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nMissing Values&amp;quot;)&lt;br /&gt;
print(df.isnull().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDuplicate Records&amp;quot;)&lt;br /&gt;
print(df.duplicated().sum())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nStatistical Summary&amp;quot;)&lt;br /&gt;
print(df.describe())&lt;br /&gt;
&lt;br /&gt;
# Convert Date column to datetime&lt;br /&gt;
df[&amp;quot;Date&amp;quot;] = pd.to_datetime(df[&amp;quot;Date&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Convert Value column to numeric&lt;br /&gt;
df[&amp;quot;Value&amp;quot;] = pd.to_numeric(df[&amp;quot;Value&amp;quot;], errors=&amp;quot;coerce&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Remove rows with missing required values&lt;br /&gt;
df = df.dropna(subset=[&amp;quot;ID&amp;quot;, &amp;quot;Name&amp;quot;, &amp;quot;Value&amp;quot;, &amp;quot;Date&amp;quot;])&lt;br /&gt;
&lt;br /&gt;
# Remove duplicate records&lt;br /&gt;
df = df.drop_duplicates()&lt;br /&gt;
&lt;br /&gt;
# Detect temperature outliers using IQR&lt;br /&gt;
Q1 = df[&amp;quot;Value&amp;quot;].quantile(0.25)&lt;br /&gt;
Q3 = df[&amp;quot;Value&amp;quot;].quantile(0.75)&lt;br /&gt;
&lt;br /&gt;
IQR = Q3 - Q1&lt;br /&gt;
&lt;br /&gt;
lower_limit = Q1 - 1.5 * IQR&lt;br /&gt;
upper_limit = Q3 + 1.5 * IQR&lt;br /&gt;
&lt;br /&gt;
outliers = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt; lower_limit) |&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt; upper_limit)&lt;br /&gt;
]&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nDetected Outliers&amp;quot;)&lt;br /&gt;
print(outliers)&lt;br /&gt;
&lt;br /&gt;
# Remove detected outliers&lt;br /&gt;
df_clean = df[&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;gt;= lower_limit) &amp;amp;&lt;br /&gt;
    (df[&amp;quot;Value&amp;quot;] &amp;lt;= upper_limit)&lt;br /&gt;
].copy()&lt;br /&gt;
&lt;br /&gt;
# Min-Max normalization&lt;br /&gt;
min_value = df_clean[&amp;quot;Value&amp;quot;].min()&lt;br /&gt;
max_value = df_clean[&amp;quot;Value&amp;quot;].max()&lt;br /&gt;
&lt;br /&gt;
df_clean[&amp;quot;Normalized_Value&amp;quot;] = (&lt;br /&gt;
    (df_clean[&amp;quot;Value&amp;quot;] - min_value) /&lt;br /&gt;
    (max_value - min_value)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
# Save cleaned and normalized dataset&lt;br /&gt;
df_clean.to_csv(&lt;br /&gt;
    &amp;quot;cleaned_normalized_dht11_data.csv&amp;quot;,&lt;br /&gt;
    index=False&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nCleaned Dataset&amp;quot;)&lt;br /&gt;
print(df_clean.head())&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;\nNormalized Dataset&amp;quot;)&lt;br /&gt;
print(df_clean[[&amp;quot;Value&amp;quot;, &amp;quot;Normalized_Value&amp;quot;]].head())&lt;br /&gt;
&lt;br /&gt;
# Visualization 1: Temperature vs Time&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 2: Temperature distribution&lt;br /&gt;
plt.figure(figsize=(8, 5))&lt;br /&gt;
&lt;br /&gt;
plt.hist(&lt;br /&gt;
    df_clean[&amp;quot;Value&amp;quot;],&lt;br /&gt;
    bins=10&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Temperature (°C)&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Frequency&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Distribution of DHT11 Temperature Values&amp;quot;)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&lt;br /&gt;
# Visualization 3: Normalized temperature&lt;br /&gt;
plt.figure(figsize=(10, 5))&lt;br /&gt;
&lt;br /&gt;
plt.plot(&lt;br /&gt;
    df_clean[&amp;quot;Date&amp;quot;],&lt;br /&gt;
    df_clean[&amp;quot;Normalized_Value&amp;quot;]&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
plt.xlabel(&amp;quot;Date and Time&amp;quot;)&lt;br /&gt;
plt.ylabel(&amp;quot;Normalized Temperature&amp;quot;)&lt;br /&gt;
plt.title(&amp;quot;Normalized DHT11 Temperature vs Time&amp;quot;)&lt;br /&gt;
plt.xticks(rotation=45)&lt;br /&gt;
plt.tight_layout()&lt;br /&gt;
plt.show()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Code Explanation ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;pd.read_csv():&#039;&#039;&#039; Loads the IoT sensor dataset from the CSV file.&lt;br /&gt;
* &#039;&#039;&#039;df.info():&#039;&#039;&#039; Displays information about the columns, data types and number of non-null records.&lt;br /&gt;
* &#039;&#039;&#039;isnull().sum():&#039;&#039;&#039; Counts the missing values in each column.&lt;br /&gt;
* &#039;&#039;&#039;duplicated():&#039;&#039;&#039; Identifies duplicate records in the dataset.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_datetime():&#039;&#039;&#039; Converts the Date column into a proper date-time format.&lt;br /&gt;
* &#039;&#039;&#039;pd.to_numeric():&#039;&#039;&#039; Converts the sensor Value column into numerical data.&lt;br /&gt;
* &#039;&#039;&#039;dropna():&#039;&#039;&#039; Removes records containing missing values in required fields.&lt;br /&gt;
* &#039;&#039;&#039;drop_duplicates():&#039;&#039;&#039; Removes duplicate records.&lt;br /&gt;
* &#039;&#039;&#039;Q1 and Q3:&#039;&#039;&#039; Represent the first and third quartiles of the temperature data.&lt;br /&gt;
* &#039;&#039;&#039;IQR:&#039;&#039;&#039; Represents the interquartile range and is calculated as Q3 − Q1.&lt;br /&gt;
* &#039;&#039;&#039;Outlier limits:&#039;&#039;&#039; Values outside Q1 − 1.5 × IQR and Q3 + 1.5 × IQR are identified as potential outliers.&lt;br /&gt;
* &#039;&#039;&#039;Min-Max normalization:&#039;&#039;&#039; Converts the temperature values into the range 0 to 1.&lt;br /&gt;
* &#039;&#039;&#039;to_csv():&#039;&#039;&#039; Saves the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
* &#039;&#039;&#039;plt.plot():&#039;&#039;&#039; Creates a line graph showing the variation of sensor values.&lt;br /&gt;
* &#039;&#039;&#039;plt.hist():&#039;&#039;&#039; Creates a histogram showing the distribution of temperature values.&lt;br /&gt;
&lt;br /&gt;
== Procedure ==&lt;br /&gt;
&lt;br /&gt;
# Obtain the DHT11 sensor dataset in CSV format from the Cognifront cloud platform.&lt;br /&gt;
# Make a copy of the original CSV file and use the copy for data-cleaning experiments.&lt;br /&gt;
# Open the Python environment such as Jupyter Notebook, Google Colab or a Python IDE.&lt;br /&gt;
# Install the required Pandas, NumPy and Matplotlib libraries.&lt;br /&gt;
# Load the CSV dataset using Pandas.&lt;br /&gt;
# Inspect the dataset and identify its columns, data types and number of records.&lt;br /&gt;
# Check the dataset for missing values.&lt;br /&gt;
# Check the dataset for duplicate records.&lt;br /&gt;
# Convert the Date column into the appropriate date-time format.&lt;br /&gt;
# Convert the sensor Value column into numerical format.&lt;br /&gt;
# Identify anomalous sensor values using statistical methods such as the IQR method.&lt;br /&gt;
# Remove or handle the identified invalid or anomalous records as required.&lt;br /&gt;
# Normalize the cleaned sensor values using Min-Max normalization.&lt;br /&gt;
# Save the cleaned and normalized dataset as a new CSV file.&lt;br /&gt;
# Plot the temperature values against time using a line graph.&lt;br /&gt;
# Plot the distribution of temperature values using a histogram.&lt;br /&gt;
# Plot the normalized temperature values against time.&lt;br /&gt;
# Compare the original and processed datasets and observe the effect of data cleaning and normalization.&lt;br /&gt;
&lt;br /&gt;
== Introducing Manual Anomalies ==&lt;br /&gt;
&lt;br /&gt;
The original Cognifront dataset is relatively clean. Therefore, for demonstrating data-cleaning techniques, controlled anomalies can be introduced into a &#039;&#039;&#039;copy&#039;&#039;&#039; of the original dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Do not modify the original downloaded dataset.&#039;&#039;&#039; Keep the original file as the raw dataset and create a separate file such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
dht11-data-logger-dht-temp-anomalous.csv&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following anomalies can be introduced for demonstration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Anomaly&lt;br /&gt;
! Example&lt;br /&gt;
! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| Missing value&lt;br /&gt;
| Replace a Value entry with an empty cell&lt;br /&gt;
| Demonstrates missing-value handling&lt;br /&gt;
|-&lt;br /&gt;
| Duplicate record&lt;br /&gt;
| Copy one complete row and insert it again&lt;br /&gt;
| Demonstrates duplicate detection&lt;br /&gt;
|-&lt;br /&gt;
| Extreme temperature&lt;br /&gt;
| Change one Value to 80 °C&lt;br /&gt;
| Demonstrates outlier detection&lt;br /&gt;
|-&lt;br /&gt;
| Very low temperature&lt;br /&gt;
| Change one Value to -20 °C&lt;br /&gt;
| Demonstrates anomalous-value detection&lt;br /&gt;
|-&lt;br /&gt;
| Invalid value&lt;br /&gt;
| Replace one Value with text such as &amp;quot;ERROR&amp;quot;&lt;br /&gt;
| Demonstrates invalid data handling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, if the original data contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,27.5,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the Value can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296900,DHT-Temp,80,2026-10-07 08:49:35&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Similarly, another record can be changed to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
296950,DHT-Temp,,2026-10-07 08:51:15&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to demonstrate a missing sensor value.&lt;br /&gt;
&lt;br /&gt;
An existing row can also be copied and inserted again to create a duplicate record.&lt;br /&gt;
&lt;br /&gt;
The modified dataset can then be processed using the Python program. The program should identify the missing, duplicate and anomalous records and produce a cleaned dataset.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; These manually introduced anomalies are artificial and are used only to demonstrate data-cleaning techniques. They should not be presented as actual errors produced by the DHT11 sensor or Cognifront cloud platform.&lt;br /&gt;
&lt;br /&gt;
== Observations and Output ==&lt;br /&gt;
&lt;br /&gt;
The following observations can be recorded during the experiment:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Operation&lt;br /&gt;
! Observation&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Dataset inspection&lt;br /&gt;
| Dataset contains 547 records and 4 columns&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Missing-value check&lt;br /&gt;
| Original dataset contains no missing values&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Duplicate check&lt;br /&gt;
| Original dataset contains no duplicate records&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Data type conversion&lt;br /&gt;
| Date converted to datetime and Value converted to numeric&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Anomaly detection&lt;br /&gt;
| Artificial anomalous records are identified in the modified dataset&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Data cleaning&lt;br /&gt;
| Missing, duplicate and anomalous records are handled&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Normalization&lt;br /&gt;
| Temperature values are converted to the range 0 to 1&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Visualization&lt;br /&gt;
| Temperature variation and distribution are represented graphically&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| CSV export&lt;br /&gt;
| Cleaned and normalized data is saved as a new CSV file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Result ==&lt;br /&gt;
&lt;br /&gt;
The IoT sensor dataset was successfully inspected, cleaned and normalized using Python. Missing values, duplicate records and anomalous sensor readings were identified and handled. The temperature values were normalized using Min-Max normalization, and the processed data was visualized using suitable graphs. The cleaned and normalized dataset was successfully exported as a CSV file.&lt;br /&gt;
&lt;br /&gt;
== Viva Questions ==&lt;br /&gt;
&lt;br /&gt;
# What is data preprocessing?&lt;br /&gt;
# Why is data cleaning required for IoT sensor data?&lt;br /&gt;
# What is the difference between raw data and cleaned data?&lt;br /&gt;
# What is a missing value?&lt;br /&gt;
# What is a duplicate record?&lt;br /&gt;
# What is an anomaly in a sensor dataset?&lt;br /&gt;
# Why are artificial anomalies introduced during this experiment?&lt;br /&gt;
# What is the IQR method?&lt;br /&gt;
# How is an outlier detected using the IQR method?&lt;br /&gt;
# What is data normalization?&lt;br /&gt;
# What is Min-Max normalization?&lt;br /&gt;
# What is the range of values produced by Min-Max normalization?&lt;br /&gt;
# Why is the Date column converted into datetime format?&lt;br /&gt;
# What is the purpose of the Pandas library?&lt;br /&gt;
# What is the purpose of NumPy?&lt;br /&gt;
# What is Matplotlib used for?&lt;br /&gt;
# What is the purpose of a histogram?&lt;br /&gt;
# What information can be obtained from a line graph of sensor data?&lt;br /&gt;
# Why should the original dataset be preserved before data cleaning?&lt;br /&gt;
# Why should manually introduced anomalies not be considered actual sensor errors?&lt;br /&gt;
# What is the purpose of exporting the processed dataset as a CSV file?&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1348</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1348"/>
		<updated>2026-10-07T05:32:59Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Pin Connections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| VIN (5V supply)&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the DHT11 sensor.&lt;br /&gt;
* Data is properly being logged in CSV file, and file is downloaded successfully.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1347</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1347"/>
		<updated>2026-10-07T05:31:04Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Real Life Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the DHT11 sensor.&lt;br /&gt;
* Data is properly being logged in CSV file, and file is downloaded successfully.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1346</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1346"/>
		<updated>2026-10-07T05:30:20Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Observation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the DHT11 sensor.&lt;br /&gt;
* Data is properly being logged in CSV file, and file is downloaded successfully.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed in Excel for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1345</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1345"/>
		<updated>2026-10-07T05:29:24Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Observation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the DHT11 sensor.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed in Excel for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1344</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1344"/>
		<updated>2026-10-07T05:28:53Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Pin Connections */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and DHT11 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! DHT11 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO4&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the LM35 sensor.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed in Excel for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
	<entry>
		<id>https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1343</id>
		<title>MDM331AID/Experiment 8</title>
		<link rel="alternate" type="text/html" href="https://www.cognifront.com/docs/index.php?title=MDM331AID/Experiment_8&amp;diff=1343"/>
		<updated>2026-10-07T05:27:37Z</updated>

		<summary type="html">&lt;p&gt;CogWikiEditor: /* Actions: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Experiment: Transmit sensor data between an IoT device and a server =&lt;br /&gt;
&lt;br /&gt;
== Aim ==&lt;br /&gt;
To develop an IoT application that uses the communication protocol to transmit sensor data between an IoT device and a server&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
* To understand the concept of IoT-based sensor data communication.&lt;br /&gt;
* To interface an DHT11 temperature sensor with an ESP32 development board.&lt;br /&gt;
* To read temperature data from the DHT11 sensor using the ESP32.&lt;br /&gt;
* To connect the ESP32 to a Wi-Fi network and transmit sensor data to a cloud server.&lt;br /&gt;
* To store and log the transmitted sensor data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Components Required ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Sr. No.&lt;br /&gt;
! Component&lt;br /&gt;
! Quantity&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| ESP32 development board&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| DHT11 temperature sensor&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| USB cable&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Patch cords / jumper wires&lt;br /&gt;
| As required&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Wi-Fi network / Internet connection&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Computer with Arduino IDE&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Cloud IoT platform / server (Cognifront IoT Cloud)&lt;br /&gt;
| 1 account per user/student&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Theory ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Internet of Things (IoT)&#039;&#039;&#039; is a technology in which physical devices equipped with sensors, processing units and communication capabilities collect and exchange data over a network. IoT enables sensor data to be transmitted to a remote server or cloud platform for storage and monitoring.&lt;br /&gt;
&lt;br /&gt;
An IoT-based sensor data transmission system generally consists of:&lt;br /&gt;
* &#039;&#039;&#039;Sensor:&#039;&#039;&#039; Measures physical parameters and provides the measured data to the IoT device. In this experiment, the DHT11 is used to measure temperature and humidity.&lt;br /&gt;
* &#039;&#039;&#039;IoT device / Controller:&#039;&#039;&#039; Reads the sensor data, processes it and provides network connectivity. In this experiment, the ESP32 acts as the IoT device.&lt;br /&gt;
* &#039;&#039;&#039;Communication network:&#039;&#039;&#039; Provides connectivity between the IoT device and the server or cloud platform. The ESP32 uses Wi-Fi for communication.&lt;br /&gt;
* &#039;&#039;&#039;Cloud server:&#039;&#039;&#039; Receives and stores the sensor data transmitted by the ESP32. The cloud platform used in this experiment provides facilities for storing the sensor data.&lt;br /&gt;
* &#039;&#039;&#039;Data storage:&#039;&#039;&#039; The collected sensor data can be stored on the server and exported in CSV format for further use.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DHT11&#039;&#039;&#039; is a digital temperature and humidity sensor that measures temperature and relative humidity. Unlike an analog temperature sensor such as the LM35, the DHT11 provides digital sensor data through its data pin. The sensor contains temperature and humidity sensing elements along with internal signal-processing circuitry.&lt;br /&gt;
&lt;br /&gt;
The ESP32 communicates with the DHT11 through its digital data pin. It reads the temperature and humidity values from the sensor and processes the received data. The ESP32 then connects to a Wi-Fi network and transmits the sensor data to the cloud server using the configured cloud communication mechanism.&lt;br /&gt;
&lt;br /&gt;
The cloud server receives the temperature and humidity readings and stores them as data records. In this experiment, the sensor readings are collected at regular intervals and stored on the server. The stored data can be exported as a &#039;&#039;&#039;CSV (Comma-Separated Values)&#039;&#039;&#039; file, allowing the collected sensor data to be saved in a standard tabular format.&lt;br /&gt;
&lt;br /&gt;
The overall data flow of the system is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
DHT11 Temperature &amp;amp; Humidity Sensor&lt;br /&gt;
                ↓&lt;br /&gt;
              ESP32&lt;br /&gt;
                ↓&lt;br /&gt;
              Wi-Fi&lt;br /&gt;
                ↓&lt;br /&gt;
          Cloud Server&lt;br /&gt;
                ↓&lt;br /&gt;
        Data Storage / CSV&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This type of IoT-based data logging system can be used for applications such as environmental monitoring, indoor temperature and humidity monitoring, weather monitoring and other systems where sensor measurements need to be collected remotely and stored for later use.&lt;br /&gt;
&lt;br /&gt;
== Actions: ==&lt;br /&gt;
# Write ESP32 code to read temperature data from the DHT11 sensor and send it to a cloud server using Wi-Fi.&lt;br /&gt;
# Display this reading on a web-based dashboard in real-time.&lt;br /&gt;
# Download readings data in CSV format.&lt;br /&gt;
&lt;br /&gt;
== Setting Up Cloud ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 15px; text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-01.png|frameless|300px|alt=Step 1]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 1&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Visit [https://www.cognifront.com www.cognifront.com] and scroll down to the footer section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-02.png|frameless|300px|alt=Step 2]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 2&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on the &amp;lt;b&amp;gt;IoT Cloud&amp;lt;/b&amp;gt; option.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-03.png|frameless|300px|alt=Step 3]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 3&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;i&amp;gt;Login&amp;lt;/i&amp;gt; or &amp;lt;i&amp;gt;Sign Up / Registration&amp;lt;/i&amp;gt; to access your account.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-04.png|frameless|300px|alt=Step 4]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 4&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;After logging in, navigate to the &amp;lt;b&amp;gt;Dashboard&amp;lt;/b&amp;gt; section.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-05.png|frameless|300px|alt=Step 5]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 5&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create New App&amp;lt;/b&amp;gt; to start a new cloud application.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-06.png|frameless|300px|alt=Step 6]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 6&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter your app name — for example, &amp;lt;b&amp;gt;Data Logger&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-07.png|frameless|300px|alt=Step 7]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 7&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Your dashboard will update and display the newly created app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-08.png|frameless|300px|alt=Step 8]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 8&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Each app shows buttons for &amp;lt;i&amp;gt;Edit&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Delete&amp;lt;/i&amp;gt;, &amp;lt;i&amp;gt;Launch&amp;lt;/i&amp;gt;, and &amp;lt;i&amp;gt;API Key&amp;lt;/i&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-09.png|frameless|300px|alt=Step 9]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 9&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click &amp;lt;b&amp;gt;Edit App&amp;lt;/b&amp;gt; to open your app and create variables.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-10.png|frameless|300px|alt=Step 10]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 10&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Click on &amp;lt;b&amp;gt;Create Variable&amp;lt;/b&amp;gt; to define a new data variable.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-11.png|frameless|300px|alt=Step 11]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 11&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Enter a variable name and select its type (defines input/output behavior).&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-12.png|frameless|300px|alt=Step 12]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 12&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;For example: Name – &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;, Type – &amp;lt;b&amp;gt;Continuous&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-13.png|frameless|300px|alt=Step 13]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 13&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Return to the home page and click &amp;lt;b&amp;gt;View App&amp;lt;/b&amp;gt; to launch your application.  &lt;br /&gt;
    Congratulations! Your cloud app is now ready.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-14.png|frameless|400px|alt=Step 14]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 14&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the program folder — you will find two files:  &lt;br /&gt;
    &amp;lt;i&amp;gt;eecit-exp-06-data-logger.ino&amp;lt;/i&amp;gt; (main program) and &amp;lt;i&amp;gt;cogcloudesp.h&amp;lt;/i&amp;gt; (library header file).  &lt;br /&gt;
    Open the &amp;lt;b&amp;gt;.ino&amp;lt;/b&amp;gt; file in Arduino IDE.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-15.png|frameless|400px|alt=Step 15]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 15&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Ensure the &amp;lt;b&amp;gt;cogcloudesp.h&amp;lt;/b&amp;gt; header file is included properly in your project.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-16.png|frameless|300px|alt=Step 16]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 16&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Update your code with your Wi-Fi SSID, password, and API key.  &lt;br /&gt;
    A stable internet connection is required.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-17.png|frameless|300px|alt=Step 17]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 17&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Change the variable name in your code to match the one you created in the cloud app.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:code-esp32-upload-settings.png|frameless|300px|alt=Step 18]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 18&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Connect your ESP32 to your computer and upload the code.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-19.png|frameless|300px|alt=Step 19]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 19&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open or launch your cloud app to visualize real-time sensor data from the &amp;lt;b&amp;gt;LM35&amp;lt;/b&amp;gt;.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-20.png|frameless|300px|alt=Step 20]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 20&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;In the app settings, click the &amp;lt;b&amp;gt;Download .CSV&amp;lt;/b&amp;gt; button to export data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-21.png|frameless|300px|alt=Step 21]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 21&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Set the desired time range for data export, or leave it blank to download all records.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:cloud-22.png|frameless|300px|alt=Step 22]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Step 22&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;Open the downloaded &amp;lt;b&amp;gt;.CSV&amp;lt;/b&amp;gt; file in Microsoft Excel to view the logged data.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Circuit &amp;amp; Board Connections ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; text-align: center; align-items: start;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-esp32-06.png|frameless|400px|alt=Circuit Diagram]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Circuit Diagram&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    The complete connection diagram of ESP32-based setup.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    [[File:eecit-kit-esp32-06.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
    &amp;lt;br /&amp;gt;&amp;lt;b&amp;gt;Board Connections&amp;lt;/b&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
    Actual board wiring layout showing sensor and module connections.&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Pin Connections ==&lt;br /&gt;
&lt;br /&gt;
The following connections are based on the ESP32 and LM35 configuration used in the program.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! LM35 Pin&lt;br /&gt;
! ESP32 Pin&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| GND&lt;br /&gt;
| GND&lt;br /&gt;
| Ground connection&lt;br /&gt;
|-&lt;br /&gt;
| VCC&lt;br /&gt;
| 3.3V&lt;br /&gt;
| Power supply&lt;br /&gt;
|-&lt;br /&gt;
| DATA / VOUT&lt;br /&gt;
| GPIO34&lt;br /&gt;
| Analog temperature output&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The USB cable connects the ESP32 to the computer. The computer runs the Arduino IDE and uploads your code to ESP32.&lt;br /&gt;
&amp;lt;span style=&amp;quot;background-color: #ffcccc; display: inline-block; padding: 5px; border-radius: 5px; font-weight: bold;&amp;quot;&amp;gt;&lt;br /&gt;
⚠️ Disconnect your ESP32 from the computer while making or removing component connections.&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ESP32 Code ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// © 2026, Cognifront. Member of The IoT Kits Family.&lt;br /&gt;
//Experiment 6: Data Logging Using ESP32 and Excel (Cloud Communication) &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;cogcloudesp.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
//int cogLed = 15;&lt;br /&gt;
const int lm35_pin = 34;&lt;br /&gt;
&lt;br /&gt;
String ssid = &amp;quot;********&amp;quot;; // wifi/hotspot name&lt;br /&gt;
String pass = &amp;quot;********&amp;quot;; // wifi/hotspot password 2.4 hz band only&lt;br /&gt;
&lt;br /&gt;
String apikey = &amp;quot;YOUR_API_KEY_HERE&amp;quot;; // API key from app. Keep the &amp;quot;&amp;quot; (quotes)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup ()&lt;br /&gt;
{&lt;br /&gt;
  // pinMode (cogLed,OUTPUT);&lt;br /&gt;
  pinMode (lm35_pin, INPUT);&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(115200);&lt;br /&gt;
  while (!Serial)&lt;br /&gt;
    delay(100);&lt;br /&gt;
  cogInitCloud (ssid,pass,apikey);&lt;br /&gt;
&lt;br /&gt;
  // cogBindPin (cogLed, &amp;quot;LED&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop ()&lt;br /&gt;
{&lt;br /&gt;
  cogAppLoop();&lt;br /&gt;
&lt;br /&gt;
  int voltage_mv = analogReadMilliVolts(lm35_pin);&lt;br /&gt;
  float temp_val = voltage_mv / 10.0;  // LM35 = 10 mV per °C&lt;br /&gt;
&lt;br /&gt;
  // Send value to cloud&lt;br /&gt;
  cogStoreCloudVariable(&amp;quot;LM35&amp;quot;, String(temp_val, 2));&lt;br /&gt;
&lt;br /&gt;
  delay(2000);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; margin-top: 25px;&amp;quot;&amp;gt;&lt;br /&gt;
  [[:Media:eecit-exp-06-data-logger.zip|&amp;lt;span style=&amp;quot;background-color:#007BFF;color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:bold;&amp;quot;&amp;gt;⬇ Click Here to Download Code File&amp;lt;/span&amp;gt;]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  &amp;lt;span style=&amp;quot;font-size: 90%;&amp;quot;&amp;gt;(Contains ESP32 source code)&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
  [[File:Code-esp32-upload-settings.png|frameless|400px|alt=Board Connections]]&lt;br /&gt;
  &amp;lt;br /&amp;gt;&lt;br /&gt;
   Connect your ESP32 to your computer and upload the code make sure right port selected.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Observation ==&lt;br /&gt;
* The ESP32 successfully reads temperature data from the LM35 sensor.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
This experiment demonstrates how to log real-time sensor data from ESP32 to a computer using cloud communication.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Storing data in CSV format enables easy analysis and plotting in Excel or any other data-processing tool. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Real Life Example ==&lt;br /&gt;
Condition Monitoring in Machines and Data Logging: Sensors collect data such as vibration, temperature, or pressure from mechanical systems, which is logged and analysed in Excel for predictive maintenance and fault diagnosis. Also this data can be fed for training a machine learning model.&lt;/div&gt;</summary>
		<author><name>CogWikiEditor</name></author>
	</entry>
</feed>