SEGMENT 1: 8th–9th GRADE (FOUNDATION &
CURIOSITY) – 1 to 20
1. LED Blink (Electric circuit basics)
2. Button Controlled LED (Boolean logic)
3. Traffic Light Controller (Sequencing)
4. LED Chaser Pattern
5. Buzzer Sound Generator (Sound concept)
6. RGB LED Color Mixing (Color theory)
7. Timer-Based LED Blink
8. Serial Monitor Data Display
9. Digital Counter Program
10.Random Number Generator (Probability)
11.LDR Light Detection (Light vs resistance)
12.Day/Night Automatic Light
13.Temperature Measurement (DHT11)
14.Digital Thermometer (°C ↔ °F)
15.Simple Weather Display
16.Speed = Distance / Time Calculator
17.Area & Perimeter Calculator
18.Ohm’s Law Verification (V = IR)
19.Electrical Power Calculation (P = VI)
20.Basic Safety Alarm System
SEGMENT 2: 10th–12th GRADE (SCIENCE, MATH &
REAL-WORLD) – 21 to 45
21.PWM LED Dimming (Duty cycle)
22.Potentiometer Voltage Divider
23.Analog Voltage Measurement (ADC)
24.Battery Percentage Estimation
25.Temperature & Humidity Monitor (DHT22)
26.Soil Moisture Based Irrigation Alert
27.Water Level Monitoring System
28.Ultrasonic Distance Measurement
29.Speed of Sound Experiment
30.IR Obstacle Detection (Reflection)
31.Motion Detection (PIR sensor)
32.Sound Level Meter (Decibel scale)
33.RTC Digital Clock System
34.Time vs Temperature Data Logging
35.Linear Equation Solver (ax + b = 0)
36.Quadratic Equation Solver
37.Discriminant & Nature of Roots
38.Trigonometric Calculator
39.Projectile Motion Calculator
40.Statistical Calculator (mean, max, min)
41.Sensor Graph Plotting (value vs time)
42.Energy Consumption Calculator
43.Gas Detection & Safety Indicator
44.Smart Street Light System
45.Automatic Water Tank Controller
SEGMENT 3: DIPLOMA / FY ENGINEERING (EMBEDDED
& IOT) – 46 to 70
46.OLED Display Data Visualization
47.LCD 16×2 Interface System
48.UART Communication Protocol
49.Bluetooth Serial Communication
50.Bluetooth Home Automation System
51.WiFi Network Scanner
52.WiFi Signal Strength Analyzer
53.Web Server – Device Control
54.Web Dashboard – Live Sensor Data
55.JSON Data Encoding & Parsing
56.SPI Communication Demo
57.I2C Master–Slave Communication
58.SD Card File Read/Write
59.CSV Sensor Data Logger
60.OTA Firmware Update System
61.DC Motor Speed Control (RPM relation)
62.Servo Motor Angle Control
63.Stepper Motor Positioning System
64.Deep Sleep Power Management
65.Interrupt-Based Input Handling
66.Watchdog Timer Fault Recovery
67.Event-Driven Programming Model
68.Error Detection & Logging System
69.Circular / Ring Buffer for Data
70.Internet Time Sync (NTP)
SEGMENT 4: CORE ENGINEERING (DSA, CONTROL,
SIGNALS) – 71 to 105
Data Structures & Algorithms
71.Array Operations
72.String Processing Algorithms
73.Frequency Counter (Hashing)
74.Linear Search Algorithm
75.Binary Search Algorithm
76.Stack Implementation
77.Circular Queue
78.Singly Linked List
79.Doubly Linked List
80.Recursion (Factorial, Fibonacci)
81.Sorting Algorithms (Basic)
82.Sorting Algorithms (Merge, Quick)
83.Prefix Sum Technique
84.Sliding Window Algorithm
85.Hash Table Implementation
86.Binary Tree Traversals
87.Binary Search Tree Operations
88.Heap (Min & Max)
89.Priority Queue Scheduler
90.Graph Representation
91.BFS & DFS Traversals
92.Dijkstra’s Shortest Path
93.Dynamic Programming (Knapsack)
Math, Control & Signal Processing
94.Numerical Integration
95.Numerical Differentiation
96.FFT Spectrum Analyzer
97.FIR Digital Filter
98.IIR Digital Filter
99.PID Temperature Controller
100. PID Motor Speed Controller
101. Kalman Filter (Sensor Fusion)
102. State Space Control System
103. Time Series Analysis
104. Statistical Anomaly Detection
105. Mathematical Expression Parser
SEGMENT 5: FINAL YEAR & INDUSTRIAL LEVEL – 106 to
125
Advanced Sensors & Perception
106. Camera Image Capture (ESP32-CAM)
107. Video Frame Processing
108. Motion Detection using Video
109. Thermal Sensor Heat Mapping
110. LiDAR Distance Mapping
111. GPS Coordinate Parsing & Distance Formula
112. GSM SMS & Data Communication
Networking, RTOS & Industry
113. FreeRTOS Multitasking System
114. FreeRTOS Queues & Semaphores
115. ESP-NOW Peer Communication
116. ESP-NOW Mesh Network
117. MQTT Sensor Publisher
118. MQTT Cloud Dashboard
119. HTTP REST API Client
120. Secure TLS Communication
121. Ethernet Communication (W5500)
122. CAN Bus Communication
123. Modbus RTU / TCP System
AI, NLP, VOICE & SYSTEM INTEGRATION
124. Voice Command Recognition (Sound / NLP)
125. Complete Smart System
(Sensors → Algorithms → AI → Decision → Actuation → Cloud)
1. LED Blink (Electric circuit basics)
Prompt: Create a MicroPython program for ESP32 that blinks an LED connected to GPIO pin 2
with 1 second ON and 1 second OFF intervals continuously.
Hardware Requirements:
● ESP32 development board
● LED
● 220Ω resistor
● Breadboard and jumper wires
● LED anode to GPIO2 through resistor, cathode to GND
MicroPython Program Code:
from machine import Pin
import time
led = Pin(2, [Link])
while True:
[Link]()
[Link](1)
[Link]()
[Link](1)
2. Button Controlled LED (Boolean logic)
Prompt: Create a MicroPython program for ESP32 where pressing a button connected to GPIO
4 turns ON an LED on GPIO 2, and releasing it turns OFF the LED.
Hardware Requirements:
● ESP32 development board
● LED
● Push button
● 220Ω resistor
● 10kΩ pull-down resistor
● Breadboard and jumper wires
● LED to GPIO2, Button to GPIO4
MicroPython Program Code:
from machine import Pin
led = Pin(2, [Link])
button = Pin(4, [Link], Pin.PULL_DOWN)
while True:
if [Link]() == 1:
[Link]()
else:
[Link]()
3. Traffic Light Controller (Sequencing)
Prompt: Create a MicroPython program for ESP32 that simulates a traffic light with RED (GPIO
2) for 5 seconds, YELLOW (GPIO 4) for 2 seconds, and GREEN (GPIO 5) for 5 seconds in a
continuous loop.
Hardware Requirements:
● ESP32 development board
● 3 LEDs (Red, Yellow, Green)
● 3x 220Ω resistors
● Breadboard and jumper wires
● Red LED to GPIO2, Yellow to GPIO4, Green to GPIO5
MicroPython Program Code:
from machine import Pin
import time
red = Pin(2, [Link])
yellow = Pin(4, [Link])
green = Pin(5, [Link])
while True:
[Link]()
[Link]()
[Link]()
[Link](5)
[Link]()
[Link]()
[Link]()
[Link](2)
[Link]()
[Link]()
[Link]()
[Link](5)
4. LED Chaser Pattern
Prompt: Create a MicroPython program for ESP32 that creates a chaser pattern with 4 LEDs
connected to GPIO pins 2, 4, 5, and 18, lighting them one by one in sequence with 0.3 second
delay.
Hardware Requirements:
● ESP32 development board
● 4 LEDs
● 4x 220Ω resistors
● Breadboard and jumper wires
● LEDs to GPIO2, GPIO4, GPIO5, GPIO18
MicroPython Program Code:
from machine import Pin
import time
leds = [Pin(2, [Link]), Pin(4, [Link]), Pin(5, [Link]), Pin(18, [Link])]
while True:
for led in leds:
[Link]()
[Link](0.3)
[Link]()
5. Buzzer Sound Generator (Sound
concept)
Prompt: Create a MicroPython program for ESP32 that generates a beep sound on a buzzer
connected to GPIO 15, beeping for 0.5 seconds ON and 0.5 seconds OFF continuously.
Hardware Requirements:
● ESP32 development board
● Active buzzer or Passive buzzer
● Breadboard and jumper wires
● Buzzer positive to GPIO15, negative to GND
MicroPython Program Code:
from machine import Pin
import time
buzzer = Pin(15, [Link])
while True:
[Link]()
[Link](0.5)
[Link]()
[Link](0.5)
6. RGB LED Color Mixing (Color theory)
Prompt: Create a MicroPython program for ESP32 that cycles through Red, Green, Blue,
Yellow, Cyan, Magenta, and White colors on an RGB LED connected to GPIO pins 2 (Red), 4
(Green), and 5 (Blue) with 1 second delay between colors.
Hardware Requirements:
● ESP32 development board
● Common cathode RGB LED
● 3x 220Ω resistors
● Breadboard and jumper wires
● R to GPIO2, G to GPIO4, B to GPIO5, common cathode to GND
MicroPython Program Code:
from machine import Pin
import time
red = Pin(2, [Link])
green = Pin(4, [Link])
blue = Pin(5, [Link])
colors = [
(1, 0, 0), # Red
(0, 1, 0), # Green
(0, 0, 1), # Blue
(1, 1, 0), # Yellow
(0, 1, 1), # Cyan
(1, 0, 1), # Magenta
(1, 1, 1), # White
]
while True:
for r, g, b in colors:
[Link](r)
[Link](g)
[Link](b)
[Link](1)
7. Timer-Based LED Blink
Prompt: Create a MicroPython program for ESP32 that uses a hardware timer to blink an LED
on GPIO 2 every 500 milliseconds without using sleep().
Hardware Requirements:
● ESP32 development board
● LED
● 220Ω resistor
● Breadboard and jumper wires
● LED to GPIO2
MicroPython Program Code:
from machine import Pin, Timer
led = Pin(2, [Link])
timer = Timer(0)
def toggle(t):
[Link](not [Link]())
[Link](period=500, mode=[Link], callback=toggle)
8. Serial Monitor Data Display
Prompt: Create a MicroPython program for ESP32 that prints "Hello from ESP32" followed by
an incrementing counter value to the serial monitor every second.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import time
counter = 0
while True:
print("Hello from ESP32")
print("Counter:", counter)
counter += 1
[Link](1)
9. Digital Counter Program
Prompt: Create a MicroPython program for ESP32 that increments a counter each time a
button on GPIO 4 is pressed and displays the count on the serial monitor, with debounce
handling.
Hardware Requirements:
● ESP32 development board
● Push button
● 10kΩ pull-down resistor
● Breadboard and jumper wires
● Button to GPIO4
MicroPython Program Code:
from machine import Pin
import time
button = Pin(4, [Link], Pin.PULL_DOWN)
counter = 0
last_state = 0
while True:
current_state = [Link]()
if current_state == 1 and last_state == 0:
counter += 1
print("Count:", counter)
[Link](0.2)
last_state = current_state
10. Random Number Generator
(Probability)
Prompt: Create a MicroPython program for ESP32 that generates and displays a random
number between 1 and 100 on the serial monitor every 2 seconds.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import random
import time
while True:
number = [Link](1, 100)
print("Random Number:", number)
[Link](2)
11. LDR Light Detection (Light vs
resistance)
Prompt: Create a MicroPython program for ESP32 that reads an LDR sensor value connected
to GPIO 34 (ADC) and displays the light level on the serial monitor every second.
Hardware Requirements:
● ESP32 development board
● LDR (Light Dependent Resistor)
● 10kΩ resistor
● Breadboard and jumper wires
● LDR in voltage divider with GPIO34 (ADC1_CH6)
MicroPython Program Code:
from machine import ADC, Pin
import time
ldr = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
while True:
light_value = [Link]()
print("Light Level:", light_value)
[Link](1)
12. Day/Night Automatic Light
Prompt: Create a MicroPython program for ESP32 that automatically turns ON an LED on
GPIO 2 when light level from LDR on GPIO 34 falls below 1500 (night) and turns it OFF when
above 1500 (day).
Hardware Requirements:
● ESP32 development board
● LDR (Light Dependent Resistor)
● 10kΩ resistor
● LED
● 220Ω resistor
● Breadboard and jumper wires
● LDR to GPIO34, LED to GPIO2
MicroPython Program Code:
from machine import ADC, Pin
import time
ldr = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
led = Pin(2, [Link])
while True:
light_value = [Link]()
if light_value < 1500:
[Link]()
print("Night - LED ON")
else:
[Link]()
print("Day - LED OFF")
[Link](1)
13. Temperature Measurement (DHT11)
Prompt: Create a MicroPython program for ESP32 that reads temperature and humidity from a
DHT11 sensor connected to GPIO 4 and displays values on the serial monitor every 2 seconds.
Hardware Requirements:
● ESP32 development board
● DHT11 temperature and humidity sensor
● 10kΩ pull-up resistor (if not built-in)
● Breadboard and jumper wires
● DHT11 data pin to GPIO4
MicroPython Program Code:
from machine import Pin
import dht
import time
sensor = dht.DHT11(Pin(4))
while True:
[Link]()
temp = [Link]()
humidity = [Link]()
print("Temperature:", temp, "°C")
print("Humidity:", humidity, "%")
[Link](2)
14. Digital Thermometer (°C ↔ °F)
Prompt: Create a MicroPython program for ESP32 that reads temperature from DHT11 on
GPIO 4 and displays it in both Celsius and Fahrenheit on the serial monitor every 2 seconds.
Hardware Requirements:
● ESP32 development board
● DHT11 temperature sensor
● 10kΩ pull-up resistor (if not built-in)
● Breadboard and jumper wires
● DHT11 data pin to GPIO4
MicroPython Program Code:
from machine import Pin
import dht
import time
sensor = dht.DHT11(Pin(4))
while True:
[Link]()
temp_c = [Link]()
temp_f = (temp_c * 9/5) + 32
print("Temperature:", temp_c, "°C /", temp_f, "°F")
[Link](2)
15. Simple Weather Display
Prompt: Create a MicroPython program for ESP32 that reads temperature and humidity from
DHT11 on GPIO 4 and displays weather status (Hot/Comfortable/Cold based on temperature
and Humid/Dry based on humidity) on the serial monitor every 3 seconds.
Hardware Requirements:
● ESP32 development board
● DHT11 temperature and humidity sensor
● 10kΩ pull-up resistor (if not built-in)
● Breadboard and jumper wires
● DHT11 data pin to GPIO4
MicroPython Program Code:
from machine import Pin
import dht
import time
sensor = dht.DHT11(Pin(4))
while True:
[Link]()
temp = [Link]()
humidity = [Link]()
if temp > 30:
temp_status = "Hot"
elif temp > 20:
temp_status = "Comfortable"
else:
temp_status = "Cold"
if humidity > 70:
humid_status = "Humid"
else:
humid_status = "Dry"
print("Weather:", temp_status, "&", humid_status)
print("Temp:", temp, "°C, Humidity:", humidity, "%")
[Link](3)
16. Speed = Distance / Time Calculator
Prompt: Create a MicroPython program for ESP32 that calculates and displays speed when
distance is 100 meters and time is 10 seconds, printing the result to the serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
distance = 100
time_taken = 10
speed = distance / time_taken
print("Distance:", distance, "meters")
print("Time:", time_taken, "seconds")
print("Speed:", speed, "m/s")
17. Area & Perimeter Calculator
Prompt: Create a MicroPython program for ESP32 that calculates and displays the area and
perimeter of a rectangle with length 15 and width 10 on the serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
length = 15
width = 10
area = length * width
perimeter = 2 * (length + width)
print("Length:", length)
print("Width:", width)
print("Area:", area)
print("Perimeter:", perimeter)
18. Ohm's Law Verification (V = IR)
Prompt: Create a MicroPython program for ESP32 that calculates voltage using Ohm's Law
with current 2A and resistance 10Ω, and displays the result on the serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
current = 2
resistance = 10
voltage = current * resistance
print("Current (I):", current, "A")
print("Resistance (R):", resistance, "Ω")
print("Voltage (V):", voltage, "V")
print("Ohm's Law: V = I × R")
19. Electrical Power Calculation (P = VI)
Prompt: Create a MicroPython program for ESP32 that calculates electrical power using
voltage 230V and current 5A, and displays the result on the serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
voltage = 230
current = 5
power = voltage * current
print("Voltage (V):", voltage, "V")
print("Current (I):", current, "A")
print("Power (P):", power, "W")
print("Formula: P = V × I")
20. Basic Safety Alarm System
Prompt: Create a MicroPython program for ESP32 that monitors a PIR motion sensor on GPIO
13 and triggers a buzzer on GPIO 15 and LED on GPIO 2 when motion is detected, displaying
alert messages on the serial monitor.
Hardware Requirements:
● ESP32 development board
● PIR motion sensor
● Buzzer
● LED
● 220Ω resistor
● Breadboard and jumper wires
● PIR to GPIO13, Buzzer to GPIO15, LED to GPIO2
MicroPython Program Code:
from machine import Pin
import time
pir = Pin(13, [Link])
buzzer = Pin(15, [Link])
led = Pin(2, [Link])
print("Safety Alarm System Active")
while True:
if [Link]() == 1:
[Link]()
[Link]()
print("ALERT! Motion Detected!")
[Link](2)
else:
[Link]()
[Link]()
[Link](0.1)
SEGMENT 2: 10th–12th GRADE (SCIENCE, MATH &
REAL-WORLD) – 21 to 45
1. PWM LED Dimming (Duty cycle)
Prompt: Create a MicroPython program for ESP32 that dims an LED on GPIO 2 using PWM,
gradually increasing brightness from 0% to 100% and then decreasing back to 0% continuously.
Hardware Requirements:
● ESP32 development board
● LED
● 220Ω resistor
● Breadboard and jumper wires
● LED to GPIO2
MicroPython Program Code:
from machine import Pin, PWM
import time
led = PWM(Pin(2), freq=1000)
while True:
for duty in range(0, 1024, 10):
[Link](duty)
[Link](0.02)
for duty in range(1023, -1, -10):
[Link](duty)
[Link](0.02)
2. Potentiometer Voltage Divider
Prompt: Create a MicroPython program for ESP32 that reads analog value from a
potentiometer connected to GPIO 34 and displays the voltage on the serial monitor every 0.5
seconds.
Hardware Requirements:
● ESP32 development board
● 10kΩ Potentiometer
● Breadboard and jumper wires
● Potentiometer middle pin to GPIO34, other pins to 3.3V and GND
MicroPython Program Code:
from machine import ADC, Pin
import time
pot = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
while True:
adc_value = [Link]()
voltage = (adc_value / 4095) * 3.3
print("ADC Value:", adc_value, "| Voltage:", round(voltage, 2), "V")
[Link](0.5)
3. Analog Voltage Measurement (ADC)
Prompt: Create a MicroPython program for ESP32 that measures analog voltage on GPIO 34
using ADC and displays both raw ADC value and calculated voltage on the serial monitor every
second.
Hardware Requirements:
● ESP32 development board
● Voltage divider circuit or sensor
● Breadboard and jumper wires
● Analog input to GPIO34 (max 3.3V)
MicroPython Program Code:
from machine import ADC, Pin
import time
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
[Link](ADC.WIDTH_12BIT)
while True:
raw_value = [Link]()
voltage = (raw_value / 4095) * 3.3
print("Raw ADC:", raw_value)
print("Voltage:", round(voltage, 3), "V")
print("---")
[Link](1)
4. Battery Percentage Estimation
Prompt: Create a MicroPython program for ESP32 that reads battery voltage from GPIO 34 (via
voltage divider) and estimates battery percentage assuming 4.2V is 100% and 3.0V is 0%,
displaying results on serial monitor.
Hardware Requirements:
● ESP32 development board
● Battery (3.7V Li-ion)
● Voltage divider (2x 10kΩ resistors)
● Breadboard and jumper wires
● Voltage divider output to GPIO34
MicroPython Program Code:
from machine import ADC, Pin
import time
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
V_MAX = 4.2
V_MIN = 3.0
while True:
adc_value = [Link]()
voltage = (adc_value / 4095) * 3.3 * 2
if voltage > V_MAX:
percentage = 100
elif voltage < V_MIN:
percentage = 0
else:
percentage = ((voltage - V_MIN) / (V_MAX - V_MIN)) * 100
print("Battery Voltage:", round(voltage, 2), "V")
print("Battery Percentage:", round(percentage, 1), "%")
[Link](2)
5. Temperature & Humidity Monitor
(DHT22)
Prompt: Create a MicroPython program for ESP32 that reads temperature and humidity from
DHT22 sensor on GPIO 4 and displays values with higher precision on the serial monitor every
3 seconds.
Hardware Requirements:
● ESP32 development board
● DHT22 temperature and humidity sensor
● 10kΩ pull-up resistor
● Breadboard and jumper wires
● DHT22 data pin to GPIO4
MicroPython Program Code:
from machine import Pin
import dht
import time
sensor = dht.DHT22(Pin(4))
while True:
try:
[Link]()
temp = [Link]()
humidity = [Link]()
print("Temperature:", temp, "°C")
print("Humidity:", humidity, "%")
print("---")
except OSError as e:
print("Failed to read sensor")
[Link](3)
6. Soil Moisture Based Irrigation Alert
Prompt: Create a MicroPython program for ESP32 that reads soil moisture from an analog
sensor on GPIO 34 and turns ON an LED on GPIO 2 with alert message when moisture falls
below threshold 1500.
Hardware Requirements:
● ESP32 development board
● Soil moisture sensor (analog)
● LED
● 220Ω resistor
● Breadboard and jumper wires
● Sensor analog output to GPIO34, LED to GPIO2
MicroPython Program Code:
from machine import ADC, Pin
import time
moisture_sensor = ADC(Pin(34))
moisture_sensor.atten(ADC.ATTN_11DB)
led = Pin(2, [Link])
THRESHOLD = 1500
while True:
moisture_value = moisture_sensor.read()
print("Soil Moisture:", moisture_value)
if moisture_value < THRESHOLD:
[Link]()
print("ALERT: Irrigation Required!")
else:
[Link]()
print("Soil Moisture: OK")
print("---")
[Link](2)
7. Water Level Monitoring System
Prompt: Create a MicroPython program for ESP32 that monitors water level using an analog
sensor on GPIO 34 and displays level status (Empty/Low/Medium/Full) with LED indication on
GPIO 2 for low level alert.
Hardware Requirements:
● ESP32 development board
● Water level sensor (analog)
● LED
● 220Ω resistor
● Breadboard and jumper wires
● Sensor to GPIO34, LED to GPIO2
MicroPython Program Code:
from machine import ADC, Pin
import time
water_sensor = ADC(Pin(34))
water_sensor.atten(ADC.ATTN_11DB)
led = Pin(2, [Link])
while True:
level = water_sensor.read()
print("Water Level Value:", level)
if level < 500:
status = "Empty"
[Link]()
elif level < 1500:
status = "Low"
[Link]()
elif level < 2500:
status = "Medium"
[Link]()
else:
status = "Full"
[Link]()
print("Status:", status)
print("---")
[Link](2)
8. Ultrasonic Distance Measurement
Prompt: Create a MicroPython program for ESP32 that measures distance using HC-SR04
ultrasonic sensor with trigger on GPIO 5 and echo on GPIO 18, displaying distance in cm on
serial monitor every second.
Hardware Requirements:
● ESP32 development board
● HC-SR04 ultrasonic sensor
● Breadboard and jumper wires
● Trigger to GPIO5, Echo to GPIO18, VCC to 5V, GND to GND
MicroPython Program Code:
from machine import Pin
import time
trigger = Pin(5, [Link])
echo = Pin(18, [Link])
def get_distance():
[Link]()
time.sleep_us(2)
[Link]()
time.sleep_us(10)
[Link]()
timeout = time.ticks_ms()
while [Link]() == 0:
pulse_start = time.ticks_us()
if time.ticks_diff(time.ticks_ms(), timeout) > 1000:
return -1
timeout = time.ticks_ms()
while [Link]() == 1:
pulse_end = time.ticks_us()
if time.ticks_diff(time.ticks_ms(), timeout) > 1000:
return -1
pulse_duration = time.ticks_diff(pulse_end, pulse_start)
distance = (pulse_duration * 0.0343) / 2
return distance
while True:
dist = get_distance()
print("Distance:", round(dist, 2), "cm")
[Link](1)
9. Speed of Sound Experiment
Prompt: Create a MicroPython program for ESP32 that calculates speed of sound using
ultrasonic sensor on GPIO 5 (trigger) and GPIO 18 (echo), measuring time for echo to return
from a known distance.
Hardware Requirements:
● ESP32 development board
● HC-SR04 ultrasonic sensor
● Breadboard and jumper wires
● Trigger to GPIO5, Echo to GPIO18
MicroPython Program Code:
from machine import Pin
import time
trigger = Pin(5, [Link])
echo = Pin(18, [Link])
def measure_speed_of_sound():
[Link]()
time.sleep_us(2)
[Link]()
time.sleep_us(10)
[Link]()
while [Link]() == 0:
pulse_start = time.ticks_us()
while [Link]() == 1:
pulse_end = time.ticks_us()
pulse_duration = time.ticks_diff(pulse_end, pulse_start)
distance = 100
time_seconds = pulse_duration / 1000000
speed = (2 * distance) / time_seconds
return speed, pulse_duration
while True:
speed, duration = measure_speed_of_sound()
print("Pulse Duration:", duration, "µs")
print("Calculated Speed of Sound:", round(speed, 2), "cm/s")
print("Expected: ~34300 cm/s")
print("---")
[Link](3)
10. IR Obstacle Detection (Reflection)
Prompt: Create a MicroPython program for ESP32 that detects obstacles using an IR sensor on
GPIO 13 and turns ON an LED on GPIO 2 with alert message when obstacle is detected.
Hardware Requirements:
● ESP32 development board
● IR obstacle detection sensor
● LED
● 220Ω resistor
● Breadboard and jumper wires
● IR sensor OUT to GPIO13, LED to GPIO2
MicroPython Program Code:
from machine import Pin
import time
ir_sensor = Pin(13, [Link])
led = Pin(2, [Link])
while True:
if ir_sensor.value() == 0:
[Link]()
print("OBSTACLE DETECTED!")
else:
[Link]()
print("No obstacle")
[Link](0.5)
11. Motion Detection (PIR sensor)
Prompt: Create a MicroPython program for ESP32 that detects motion using PIR sensor on
GPIO 13 and displays motion status on serial monitor with LED indication on GPIO 2.
Hardware Requirements:
● ESP32 development board
● PIR motion sensor
● LED
● 220Ω resistor
● Breadboard and jumper wires
● PIR OUT to GPIO13, LED to GPIO2
MicroPython Program Code:
from machine import Pin
import time
pir = Pin(13, [Link])
led = Pin(2, [Link])
print("PIR Motion Detector Ready")
[Link](2)
while True:
if [Link]() == 1:
[Link]()
print("MOTION DETECTED!")
[Link](1)
else:
[Link]()
print("No motion")
[Link](0.5)
12. Sound Level Meter (Decibel scale)
Prompt: Create a MicroPython program for ESP32 that reads sound level from an analog
sound sensor on GPIO 34 and estimates decibel level, displaying values on serial monitor every
0.5 seconds.
Hardware Requirements:
● ESP32 development board
● Sound sensor module (analog output)
● Breadboard and jumper wires
● Sound sensor analog out to GPIO34
MicroPython Program Code:
from machine import ADC, Pin
import time
import math
sound_sensor = ADC(Pin(34))
sound_sensor.atten(ADC.ATTN_11DB)
while True:
sound_value = sound_sensor.read()
voltage = (sound_value / 4095) * 3.3
if voltage > 0.01:
decibel = 20 * math.log10(voltage / 0.00631) + 94
else:
decibel = 0
print("Sound Value:", sound_value)
print("Estimated dB:", round(decibel, 1))
print("---")
[Link](0.5)
13. RTC Digital Clock System
Prompt: Create a MicroPython program for ESP32 that displays current time in HH:MM:SS
format on serial monitor using internal RTC, updating every second.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
from machine import RTC
import time
rtc = RTC()
[Link]((2025, 1, 1, 0, 10, 30, 0, 0))
while True:
current_time = [Link]()
hour = current_time[4]
minute = current_time[5]
second = current_time[6]
print("Time: {:02d}:{:02d}:{:02d}".format(hour, minute, second))
[Link](1)
14. Time vs Temperature Data Logging
Prompt: Create a MicroPython program for ESP32 that logs temperature from DHT11 on GPIO
4 along with timestamp every 5 seconds and displays on serial monitor.
Hardware Requirements:
● ESP32 development board
● DHT11 temperature sensor
● 10kΩ pull-up resistor
● Breadboard and jumper wires
● DHT11 data pin to GPIO4
MicroPython Program Code:
from machine import Pin, RTC
import dht
import time
sensor = dht.DHT11(Pin(4))
rtc = RTC()
[Link]((2025, 1, 1, 0, 12, 0, 0, 0))
print("Time | Temperature")
print("-------------------")
while True:
try:
[Link]()
temp = [Link]()
current_time = [Link]()
time_str = "{:02d}:{:02d}:{:02d}".format(
current_time[4], current_time[5], current_time[6]
)
print(time_str, "|", temp, "°C")
except:
print("Sensor read error")
[Link](5)
15. Linear Equation Solver (ax + b = 0)
Prompt: Create a MicroPython program for ESP32 that solves linear equation ax + b = 0 for
given values of a=5 and b=15, displaying the solution on serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
a=5
b = 15
print("Linear Equation: ax + b = 0")
print("Given: a =", a, ", b =", b)
if a == 0:
if b == 0:
print("Infinite solutions")
else:
print("No solution")
else:
x = -b / a
print("Solution: x =", x)
16. Quadratic Equation Solver
Prompt: Create a MicroPython program for ESP32 that solves quadratic equation ax² + bx + c =
0 for a=1, b=-5, c=6 and displays roots on serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import math
a=1
b = -5
c=6
print("Quadratic Equation: ax² + bx + c = 0")
print("a =", a, ", b =", b, ", c =", c)
discriminant = b**2 - 4*a*c
if discriminant > 0:
root1 = (-b + [Link](discriminant)) / (2*a)
root2 = (-b - [Link](discriminant)) / (2*a)
print("Two real roots:")
print("Root 1 =", root1)
print("Root 2 =", root2)
elif discriminant == 0:
root = -b / (2*a)
print("One real root:")
print("Root =", root)
else:
real_part = -b / (2*a)
imag_part = [Link](-discriminant) / (2*a)
print("Two complex roots:")
print("Root 1 =", real_part, "+", imag_part, "i")
print("Root 2 =", real_part, "-", imag_part, "i")
17. Discriminant & Nature of Roots
Prompt: Create a MicroPython program for ESP32 that calculates discriminant of quadratic
equation with a=2, b=4, c=2 and determines nature of roots, displaying results on serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import math
a=2
b=4
c=2
print("Quadratic Equation: ax² + bx + c = 0")
print("a =", a, ", b =", b, ", c =", c)
discriminant = b**2 - 4*a*c
print("Discriminant (Δ) =", discriminant)
if discriminant > 0:
print("Nature: Two distinct real roots")
elif discriminant == 0:
print("Nature: Two equal real roots")
else:
print("Nature: Two complex roots")
18. Trigonometric Calculator
Prompt: Create a MicroPython program for ESP32 that calculates sine, cosine, and tangent for
angle 45 degrees and displays results on serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import math
angle_deg = 45
angle_rad = [Link](angle_deg)
sin_value = [Link](angle_rad)
cos_value = [Link](angle_rad)
tan_value = [Link](angle_rad)
print("Angle:", angle_deg, "degrees")
print("Sine:", round(sin_value, 4))
print("Cosine:", round(cos_value, 4))
print("Tangent:", round(tan_value, 4))
19. Projectile Motion Calculator
Prompt: Create a MicroPython program for ESP32 that calculates maximum height and range
of projectile with initial velocity 20 m/s at 45 degrees angle, displaying results on serial monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
import math
velocity = 20
angle_deg = 45
g = 9.8
angle_rad = [Link](angle_deg)
max_height = (velocity**2 * [Link](angle_rad)**2) / (2 * g)
range_distance = (velocity**2 * [Link](2 * angle_rad)) / g
time_of_flight = (2 * velocity * [Link](angle_rad)) / g
print("Initial Velocity:", velocity, "m/s")
print("Angle:", angle_deg, "degrees")
print("Max Height:", round(max_height, 2), "m")
print("Range:", round(range_distance, 2), "m")
print("Time of Flight:", round(time_of_flight, 2), "s")
20. Statistical Calculator (mean, max, min)
Prompt: Create a MicroPython program for ESP32 that calculates mean, maximum, and
minimum of a list of temperature readings [22, 25, 23, 27, 24, 26] and displays results on serial
monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
data = [22, 25, 23, 27, 24, 26]
mean = sum(data) / len(data)
maximum = max(data)
minimum = min(data)
data_range = maximum - minimum
print("Data:", data)
print("Mean:", round(mean, 2))
print("Maximum:", maximum)
print("Minimum:", minimum)
print("Range:", data_range)
21. Sensor Graph Plotting (value vs time)
Prompt: Create a MicroPython program for ESP32 that reads temperature from DHT11 on
GPIO 4 every 2 seconds and displays values in time-series format for plotting on serial monitor.
Hardware Requirements:
● ESP32 development board
● DHT11 temperature sensor
● 10kΩ pull-up resistor
● Breadboard and jumper wires
● DHT11 data pin to GPIO4
MicroPython Program Code:
from machine import Pin
import dht
import time
sensor = dht.DHT11(Pin(4))
reading_count = 0
print("Time(s), Temperature(°C)")
while True:
try:
[Link]()
temp = [Link]()
print(reading_count * 2, ",", temp)
reading_count += 1
except:
print("Error reading sensor")
[Link](2)
22. Energy Consumption Calculator
Prompt: Create a MicroPython program for ESP32 that calculates energy consumption in kWh
for a device with power 100W running for 5 hours and displays cost at rate 10 per kWh on serial
monitor.
Hardware Requirements:
● ESP32 development board
● USB cable for serial communication
MicroPython Program Code:
power_watts = 100
time_hours = 5
cost_per_kwh = 10
energy_kwh = (power_watts * time_hours) / 1000
total_cost = energy_kwh * cost_per_kwh
print("Power:", power_watts, "W")
print("Time:", time_hours, "hours")
print("Energy Consumed:", energy_kwh, "kWh")
print("Cost per kWh:", cost_per_kwh)
print("Total Cost:", total_cost)
23. Gas Detection & Safety Indicator
Prompt: Create a MicroPython program for ESP32 that monitors gas level using MQ-2 sensor
on GPIO 34 and triggers buzzer on GPIO 15 and LED on GPIO 2 when gas level exceeds
threshold 2000, displaying status on serial monitor.
Hardware Requirements:
● ESP32 development board
● MQ-2 gas sensor (analog output)
● Buzzer
● LED
● 220Ω resistor
● Breadboard and jumper wires
● MQ-2 analog to GPIO34, Buzzer to GPIO15, LED to GPIO2
MicroPython Program Code:
from machine import ADC, Pin
import time
gas_sensor = ADC(Pin(34))
gas_sensor.atten(ADC.ATTN_11DB)
buzzer = Pin(15, [Link])
led = Pin(2, [Link])
THRESHOLD = 2000
print("Gas Detection System Active")
while True:
gas_level = gas_sensor.read()
print("Gas Level:", gas_level)
if gas_level > THRESHOLD:
[Link]()
[Link]()
print("DANGER! Gas Detected!")
else:
[Link]()
[Link]()
print("Safe")
print("---")
[Link](1)
24. Smart Street Light System
Prompt: Create a MicroPython program for ESP32 that automatically controls street light LED
on GPIO 2 based on LDR on GPIO 34 (turns ON when dark) and PIR sensor on GPIO 13 (turns
ON when motion detected at night), displaying status on serial monitor.
Hardware Requirements:
● ESP32 development board
● LDR with 10kΩ resistor
● PIR motion sensor
● LED (street light)
● 220Ω resistor
● Breadboard and jumper wires
● LDR to GPIO34, PIR to GPIO13, LED to GPIO2
MicroPython Program Code:
from machine import ADC, Pin
import time
ldr = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
pir = Pin(13, [Link])
led = Pin(2, [Link])
DARK_THRESHOLD = 1500
print("Smart Street Light System")
while True:
light_level = [Link]()
motion = [Link]()
print("Light Level:", light_level, "| Motion:", motion)
if light_level < DARK_THRESHOLD:
if motion == 1:
[Link]()
print("Night + Motion: Light ON")
else:
[Link]()
print("Night + No Motion: Light OFF")
else:
[Link]()
print("Day: Light OFF")
print("---")
[Link](1)
25. Automatic Water Tank Controller
Prompt: Create a MicroPython program for ESP32 that monitors water level using sensor on
GPIO 34 and controls a pump relay on GPIO 5, turning pump ON when level is low (below
1000) and OFF when full (above 3000), displaying status on serial monitor.
Hardware Requirements:
● ESP32 development board
● Water level sensor (analog)
● Relay module
● LED (pump indicator)
● Breadboard and jumper wires
● Water sensor to GPIO34, Relay to GPIO5
MicroPython Program Code:
from machine import ADC, Pin
import time
water_sensor = ADC(Pin(34))
water_sensor.atten(ADC.ATTN_11DB)
pump_relay = Pin(5, [Link])
LOW_LEVEL = 1000
HIGH_LEVEL = 3000
pump_state = False
print("Automatic Water Tank Controller")
while True:
water_level = water_sensor.read()
if water_level < LOW_LEVEL and not pump_state:
pump_relay.on()
pump_state = True
print("Water Level LOW - Pump ON")
elif water_level > HIGH_LEVEL and pump_state:
pump_relay.off()
pump_state = False
print("Water Level FULL - Pump OFF")
print("Water Level:", water_level, "| Pump:", "ON" if pump_state else "OFF")
[Link](2)
SEGMENT 3: DIPLOMA / FY
ENGINEERING (EMBEDDED & IOT) – 46 to
70
1. OLED Display Data Visualization
Prompt: Create an ESP32 MicroPython program to display text and sensor data on an OLED
display using I2C interface with SSD1306 driver.
Hardware Requirements:
● ESP32 Development Board
● SSD1306 OLED Display (128x64, I2C)
● Jumper wires
● Connections: SDA to GPIO21, SCL to GPIO22, VCC to 3.3V, GND to GND
⚠️ IMPORTANT - Library Installation:
# Upload [Link] to ESP32
# Download from:
[Link]
# Using ampy:
ampy --port /dev/ttyUSB0 put [Link]
# Or use Thonny IDE to save it to the device
MicroPython Code:
from machine import Pin, I2C
import ssd1306
import time
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
while True:
[Link](0)
[Link]('ESP32 OLED', 0, 0)
[Link]('Temp: 25C', 0, 20)
[Link]('Humidity: 60%', 0, 30)
[Link]('Pressure:1013', 0, 40)
[Link]()
[Link](2)
2. LCD 16×2 Interface System
Prompt: Create an ESP32 MicroPython program to interface with a 16x2 LCD display and show
scrolling text messages.
Hardware Requirements:
● ESP32 Development Board
● 16x2 LCD with I2C module (PCF8574)
● Jumper wires
● Connections: SDA to GPIO21, SCL to GPIO22, VCC to 5V, GND to GND
Important Instructions:
# On your computer, install the library:
pip install esp8266-i2c-lcd --break-system-packages
# Then upload the library files to your ESP32:
# Option 1: Using ampy
ampy --port /dev/ttyUSB0 put esp8266_i2c_lcd.py
# Option 2: Using Thonny IDE
# File > Save As > MicroPython device > save as "esp8266_i2c_lcd.py"
MicroPython Code:
from machine import Pin, I2C
from esp8266_i2c_lcd import I2cLcd
import time
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
lcd = I2cLcd(i2c, 0x27, 2, 16)
while True:
[Link]()
[Link]("ESP32 System")
[Link](2)
[Link]()
[Link]("Temp: 28C\nHumid: 55%")
[Link](2)
3. UART Communication Protocol
Prompt: Create an ESP32 MicroPython program to demonstrate UART serial communication
by sending and receiving data between two UART ports.
Hardware Requirements:
● ESP32 Development Board
● USB-to-Serial adapter (optional for external device)
● Jumper wires
● Connections: TX2 (GPIO17) to RX of external device, RX2 (GPIO16) to TX of external
device
MicroPython Code:
from machine import UART, Pin
import time
uart1 = UART(1, baudrate=9600, tx=Pin(17), rx=Pin(16))
uart2 = UART(2, baudrate=9600, tx=Pin(25), rx=Pin(26))
print("UART Communication Started")
while True:
[Link]("Hello from UART1\n")
print("UART1 Sent: Hello from UART1")
[Link](1)
if [Link]():
data = [Link]()
print("UART2 Received:", [Link]())
[Link](2)
4. Bluetooth Serial Communication
Prompt: Create an ESP32 MicroPython program to establish Bluetooth serial communication
and exchange data with a smartphone app.
Hardware Requirements:
● ESP32 Development Board
● Smartphone with Bluetooth Serial Terminal app
MicroPython Code:
from machine import UART
import time
uart = UART(0, baudrate=115200)
print("Bluetooth Serial Ready")
counter = 0
while True:
if [Link]():
data = [Link]()
print("Received:", [Link]())
[Link]("Echo: " + [Link]() + "\n")
counter += 1
message = "Counter: " + str(counter) + "\n"
[Link](message)
print("Sent:", [Link]())
[Link](3)
5. Bluetooth Home Automation System
Prompt: Create an ESP32 MicroPython program to control home appliances (LEDs
representing devices) via Bluetooth commands from a smartphone.
Hardware Requirements:
● ESP32 Development Board
● 4x LEDs
● 4x 220Ω Resistors
● Smartphone with Bluetooth Serial Terminal app
● Connections: LEDs to GPIO23, GPIO22, GPIO21, GPIO19
⚠️ IMPORTANT - Bluetooth Setup Required:
Using Bluetooth Classic (Serial Port Profile - SPP)
This method requires pairing your phone with ESP32 first:
1. Enable Bluetooth on your phone
2. Search for "ESP32" device
3. Pair with it (PIN: 1234 usually)
4. Use Serial Bluetooth Terminal app to connect
Note: Standard MicroPython uses UART(0) which is the USB serial, not Bluetooth. For true
Bluetooth functionality, you need to use Bluetooth library or custom firmware.
MicroPython Code:
from machine import Pin, UART
import time
uart = UART(0, baudrate=115200)
led1 = Pin(23, [Link])
led2 = Pin(22, [Link])
led3 = Pin(21, [Link])
led4 = Pin(19, [Link])
print("Bluetooth Home Automation Ready")
print("Commands: 1ON, 1OFF, 2ON, 2OFF, 3ON, 3OFF, 4ON, 4OFF")
while True:
if [Link]():
cmd = [Link]().decode().strip()
print("Command:", cmd)
if cmd == "1ON":
[Link]()
[Link]("Device 1 ON\n")
elif cmd == "1OFF":
[Link]()
[Link]("Device 1 OFF\n")
elif cmd == "2ON":
[Link]()
[Link]("Device 2 ON\n")
elif cmd == "2OFF":
[Link]()
[Link]("Device 2 OFF\n")
elif cmd == "3ON":
[Link]()
[Link]("Device 3 ON\n")
elif cmd == "3OFF":
[Link]()
[Link]("Device 3 OFF\n")
elif cmd == "4ON":
[Link]()
[Link]("Device 4 ON\n")
elif cmd == "4OFF":
[Link]()
[Link]("Device 4 OFF\n")
[Link](0.1)
6. WiFi Network Scanner
Prompt: Create an ESP32 MicroPython program to scan for available WiFi networks and
display their SSID, signal strength, and security type.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import network
import time
wlan = [Link](network.STA_IF)
[Link](True)
print("WiFi Network Scanner")
print("-" * 50)
while True:
networks = [Link]()
print("\nAvailable Networks:")
print("-" * 50)
for net in networks:
ssid = net[0].decode()
bssid = ':'.join('%02x' % b for b in net[1])
channel = net[2]
rssi = net[3]
security = net[4]
print("SSID:", ssid)
print("RSSI:", rssi, "dBm")
print("Channel:", channel)
print("Security:", security)
print("-" * 50)
[Link](10)
7. WiFi Signal Strength Analyzer
Prompt: Create an ESP32 MicroPython program to connect to a WiFi network and continuously
monitor the signal strength (RSSI) with quality indicators.
Hardware Requirements:
● ESP32 Development Board
● WiFi Router
MicroPython Code:
import network
import time
SSID = "YourWiFiSSID"
PASSWORD = "YourWiFiPassword"
wlan = [Link](network.STA_IF)
[Link](True)
print("Connecting to WiFi...")
[Link](SSID, PASSWORD)
while not [Link]():
[Link](1)
print("Connected to:", SSID)
print("IP Address:", [Link]()[0])
print("-" * 50)
while True:
rssi = [Link]('rssi')
if rssi >= -50:
quality = "Excellent"
elif rssi >= -60:
quality = "Good"
elif rssi >= -70:
quality = "Fair"
else:
quality = "Poor"
print("Signal Strength:", rssi, "dBm -", quality)
[Link](2)
8. Web Server – Device Control
Prompt: Create an ESP32 MicroPython program to run a web server that allows controlling
LEDs through a web interface with ON/OFF buttons.
Hardware Requirements:
● ESP32 Development Board
● 2x LEDs
● 2x 220Ω Resistors
● WiFi Router
● Connections: LEDs to GPIO23 and GPIO22
MicroPython Code:
import network
import socket
from machine import Pin
import time
SSID = "YourWiFiSSID"
PASSWORD = "YourWiFiPassword"
led1 = Pin(23, [Link])
led2 = Pin(22, [Link])
wlan = [Link](network.STA_IF)
[Link](True)
[Link](SSID, PASSWORD)
while not [Link]():
[Link](1)
print("Connected! IP:", [Link]()[0])
html = """HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head><title>ESP32 Control</title></head>
<body>
<h1>Device Control</h1>
<p>LED 1: <a href="?led1=on"><button>ON</button></a> <a
href="?led1=off"><button>OFF</button></a></p>
<p>LED 2: <a href="?led2=on"><button>ON</button></a> <a
href="?led2=off"><button>OFF</button></a></p>
</body>
</html>
"""
addr = [Link]('[Link]', 80)[0][-1]
s = [Link]()
[Link](addr)
[Link](1)
print("Server running on port 80")
while True:
cl, addr = [Link]()
request = [Link](1024).decode()
if "?led1=on" in request:
[Link]()
elif "?led1=off" in request:
[Link]()
elif "?led2=on" in request:
[Link]()
elif "?led2=off" in request:
[Link]()
[Link](html)
[Link]()
9. Web Dashboard – Live Sensor Data
Prompt: Create an ESP32 MicroPython program to display live sensor data on a web
dashboard with auto-refresh functionality.
Hardware Requirements:
● ESP32 Development Board
● WiFi Router
MicroPython Code:
import network
import socket
from machine import Pin
import time
import random
SSID = "YourWiFiSSID"
PASSWORD = "YourWiFiPassword"
wlan = [Link](network.STA_IF)
[Link](True)
[Link](SSID, PASSWORD)
while not [Link]():
[Link](1)
print("Connected! IP:", [Link]()[0])
def get_sensor_data():
temp = 20 + [Link](0, 15)
humidity = 40 + [Link](0, 40)
pressure = 1000 + [Link](0, 30)
return temp, humidity, pressure
addr = [Link]('[Link]', 80)[0][-1]
s = [Link]()
[Link](addr)
[Link](1)
print("Server running on port 80")
while True:
cl, addr = [Link]()
request = [Link](1024)
temp, humidity, pressure = get_sensor_data()
html = """HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head>
<title>Sensor Dashboard</title>
<meta http-equiv="refresh" content="5">
</head>
<body>
<h1>Live Sensor Data</h1>
<h2>Temperature: {}C</h2>
<h2>Humidity: {}%</h2>
<h2>Pressure: {} hPa</h2>
<p>Auto-refresh every 5 seconds</p>
</body>
</html>
""".format(temp, humidity, pressure)
[Link](html)
[Link]()
10. JSON Data Encoding & Parsing
Prompt: Create an ESP32 MicroPython program to encode sensor data into JSON format and
parse received JSON data for processing.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import json
import time
import random
def create_sensor_json():
data = {
"device_id": "ESP32_001",
"timestamp": [Link](),
"sensors": {
"temperature": 22 + [Link](0, 10),
"humidity": 50 + [Link](0, 30),
"pressure": 1013 + [Link](-10, 10)
},
"status": "active"
}
return data
def parse_json(json_string):
try:
data = [Link](json_string)
print("Parsed Data:")
print("Device ID:", data["device_id"])
print("Temperature:", data["sensors"]["temperature"])
print("Humidity:", data["sensors"]["humidity"])
print("Pressure:", data["sensors"]["pressure"])
print("Status:", data["status"])
except Exception as e:
print("Parse Error:", e)
print("JSON Encoding & Parsing Demo")
print("-" * 50)
while True:
sensor_data = create_sensor_json()
json_string = [Link](sensor_data)
print("\nEncoded JSON:")
print(json_string)
print("-" * 50)
parse_json(json_string)
print("-" * 50)
[Link](5)
11. SPI Communication Demo
Prompt: Create an ESP32 MicroPython program to demonstrate SPI communication by
interfacing with an SPI device and transferring data.
Hardware Requirements:
● ESP32 Development Board
● SPI device (e.g., MCP3008 ADC or any SPI sensor)
● Jumper wires
● Connections: MOSI to GPIO23, MISO to GPIO19, SCK to GPIO18, CS to GPIO5
MicroPython Code:
from machine import Pin, SPI
import time
spi = SPI(1, baudrate=1000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
cs = Pin(5, [Link])
[Link](1)
print("SPI Communication Demo")
def spi_transfer(data):
[Link](0)
time.sleep_us(1)
result = [Link](len(data), data[0])
[Link](1)
return result
while True:
tx_data = bytearray([0x01, 0x80, 0x00])
print("Transmitting:", [hex(b) for b in tx_data])
rx_data = spi_transfer(tx_data)
print("Received:", [hex(b) for b in rx_data])
value = ((rx_data[1] & 0x03) << 8) | rx_data[2]
print("Converted Value:", value)
print("-" * 50)
[Link](2)
12. I2C Master–Slave Communication
Prompt: Create an ESP32 MicroPython program to demonstrate I2C master-slave
communication by reading data from an I2C slave device.
Hardware Requirements:
● ESP32 Development Board
● I2C Slave device (e.g., MPU6050, BMP280)
● Jumper wires
● Connections: SDA to GPIO21, SCL to GPIO22
MicroPython Code:
from machine import Pin, I2C
import time
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
print("I2C Master-Slave Communication")
print("Scanning I2C bus...")
devices = [Link]()
if devices:
print("Found I2C devices at addresses:", [hex(addr) for addr in devices])
else:
print("No I2C devices found")
SLAVE_ADDR = 0x68
while True:
try:
data = [Link](SLAVE_ADDR, 6)
print("Read from slave:", [hex(b) for b in data])
write_data = bytearray([0x3B, 0x00])
[Link](SLAVE_ADDR, write_data)
print("Written to slave:", [hex(b) for b in write_data])
except Exception as e:
print("Communication Error:", e)
print("-" * 50)
[Link](2)
13. SD Card File Read/Write
Prompt: Create an ESP32 MicroPython program to read and write data files on an SD card
using SPI interface.
Hardware Requirements:
● ESP32 Development Board
● SD Card Module
● SD Card
● Jumper wires
● Connections: MISO to GPIO19, MOSI to GPIO23, SCK to GPIO18, CS to GPIO5
⚠️ IMPORTANT - SD Card Driver Required: The [Link] driver is not included in
MicroPython by default. You need to upload it to your ESP32.
Step 1: Download [Link]
# Download the official driver:
wget
[Link]
# Or get it from MicroPython libraries
Step 2: Upload to ESP32
# Using ampy:
ampy --port /dev/ttyUSB0 put [Link]
# Or use Thonny IDE: File > Save As > MicroPython device > save as "[Link]"
MicroPython Code:
from machine import Pin, SPI
import sdcard
import os
import time
spi = SPI(1, baudrate=1000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
cs = Pin(5, [Link])
try:
sd = [Link](spi, cs)
[Link](sd, '/sd')
print("SD Card mounted successfully")
file_path = '/sd/[Link]'
with open(file_path, 'w') as f:
[Link]("ESP32 SD Card Test\n")
[Link]("Temperature: 25C\n")
[Link]("Humidity: 60%\n")
print("Data written to", file_path)
with open(file_path, 'r') as f:
content = [Link]()
print("File Contents:")
print(content)
print("File operations completed")
except Exception as e:
print("SD Card Error:", e)
14. CSV Sensor Data Logger
Prompt: Create an ESP32 MicroPython program to log sensor data to a CSV file on an SD card
with timestamp and multiple sensor readings.
Hardware Requirements:
● ESP32 Development Board
● SD Card Module
● SD Card
● Jumper wires
● Connections: MISO to GPIO19, MOSI to GPIO23, SCK to GPIO18, CS to GPIO5
MicroPython Code:
from machine import Pin, SPI
import sdcard
import os
import time
import random
spi = SPI(1, baudrate=1000000, sck=Pin(18), mosi=Pin(23), miso=Pin(19))
cs = Pin(5, [Link])
try:
sd = [Link](spi, cs)
[Link](sd, '/sd')
print("SD Card mounted")
csv_file = '/sd/sensor_log.csv'
with open(csv_file, 'w') as f:
[Link]("Timestamp,Temperature,Humidity,Pressure\n")
print("CSV file created")
counter = 0
while counter < 10:
timestamp = [Link]()
temp = 20 + [Link](0, 15)
humidity = 40 + [Link](0, 40)
pressure = 1000 + [Link](0, 30)
with open(csv_file, 'a') as f:
[Link]("{},{},{},{}\n".format(timestamp, temp, humidity, pressure))
print("Logged: {},{},{},{}".format(timestamp, temp, humidity, pressure))
counter += 1
[Link](2)
print("Data logging completed")
except Exception as e:
print("Error:", e)
15. OTA Firmware Update System
Prompt: Create an ESP32 MicroPython program to implement Over-The-Air (OTA) firmware
update capability via WiFi with version checking.
Hardware Requirements:
● ESP32 Development Board
● WiFi Router
MicroPython Code:
import network
import socket
import time
import os
SSID = "YourWiFiSSID"
PASSWORD = "YourWiFiPassword"
FIRMWARE_VERSION = "1.0.0"
UPDATE_SERVER = "[Link]"
UPDATE_PORT = 8080
wlan = [Link](network.STA_IF)
[Link](True)
[Link](SSID, PASSWORD)
while not [Link]():
[Link](1)
print("Connected! IP:", [Link]()[0])
print("Current Firmware Version:", FIRMWARE_VERSION)
def check_for_update():
try:
s = [Link]()
addr = [Link](UPDATE_SERVER, UPDATE_PORT)[0][-1]
[Link](addr)
[Link](b'GET /version HTTP/1.1\r\nHost: update-server\r\n\r\n')
response = [Link](1024).decode()
[Link]()
version_line = [Link]('\n')[-1]
server_version = version_line.strip()
print("Server Version:", server_version)
if server_version > FIRMWARE_VERSION:
print("New firmware available!")
return True
else:
print("Firmware is up to date")
return False
except Exception as e:
print("Update check failed:", e)
return False
def download_firmware():
print("Downloading firmware...")
print("OTA update simulated (actual implementation requires file write)")
while True:
print("\nChecking for updates...")
if check_for_update():
download_firmware()
[Link](60)
16. DC Motor Speed Control (RPM relation)
Prompt: Create an ESP32 MicroPython program to control DC motor speed using PWM and
calculate RPM based on duty cycle relationship.
Hardware Requirements:
● ESP32 Development Board
● L298N Motor Driver
● DC Motor
● 12V Power Supply
● Jumper wires
● Connections: ENA to GPIO25, IN1 to GPIO26, IN2 to GPIO27
MicroPython Code:
from machine import Pin, PWM
import time
in1 = Pin(26, [Link])
in2 = Pin(27, [Link])
ena = PWM(Pin(25), freq=1000)
def set_motor_speed(duty):
[Link]()
[Link]()
[Link](duty)
rpm = int((duty / 1023) * 200)
return rpm
print("DC Motor Speed Control")
print("-" * 50)
while True:
for duty in range(0, 1024, 100):
rpm = set_motor_speed(duty)
print("Duty Cycle: {}% | Estimated RPM: {}".format(int(duty/10.23), rpm))
[Link](2)
for duty in range(1023, -1, -100):
rpm = set_motor_speed(duty)
print("Duty Cycle: {}% | Estimated RPM: {}".format(int(duty/10.23), rpm))
[Link](2)
17. Servo Motor Angle Control
Prompt: Create an ESP32 MicroPython program to control servo motor position by setting
precise angles from 0 to 180 degrees.
Hardware Requirements:
● ESP32 Development Board
● SG90 Servo Motor
● Jumper wires
● Connections: Signal to GPIO13, VCC to 5V, GND to GND
MicroPython Code:
from machine import Pin, PWM
import time
servo = PWM(Pin(13), freq=50)
def set_angle(angle):
if angle < 0:
angle = 0
elif angle > 180:
angle = 180
duty = int(40 + (angle / 180) * 75)
[Link](duty)
print("Servo Motor Angle Control")
print("-" * 50)
angles = [0, 45, 90, 135, 180, 135, 90, 45, 0]
while True:
for angle in angles:
print("Setting angle to:", angle, "degrees")
set_angle(angle)
[Link](1)
print("-" * 50)
18. Stepper Motor Positioning System
Prompt: Create an ESP32 MicroPython program to control a stepper motor for precise
positioning with step count and direction control.
Hardware Requirements:
● ESP32 Development Board
● ULN2003 Driver Board
● 28BYJ-48 Stepper Motor
● Jumper wires
● Connections: IN1 to GPIO19, IN2 to GPIO18, IN3 to GPIO5, IN4 to GPIO17
MicroPython Code:
from machine import Pin
import time
IN1 = Pin(19, [Link])
IN2 = Pin(18, [Link])
IN3 = Pin(5, [Link])
IN4 = Pin(17, [Link])
step_sequence = [
[1, 0, 0, 0],
[1, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 1],
[1, 0, 0, 1]
]
def step_motor(steps, direction=1, delay=0.002):
for _ in range(steps):
for step in step_sequence[::direction]:
[Link](step[0])
[Link](step[1])
[Link](step[2])
[Link](step[3])
[Link](delay)
print("Stepper Motor Positioning System")
print("-" * 50)
position = 0
while True:
print("Moving forward 512 steps (90 degrees)")
step_motor(512, 1)
position += 512
print("Current Position:", position, "steps")
[Link](1)
print("Moving backward 512 steps (-90 degrees)")
step_motor(512, -1)
position -= 512
print("Current Position:", position, "steps")
[Link](1)
print("-" * 50)
19. Deep Sleep Power Management
Prompt: Create an ESP32 MicroPython program to implement deep sleep mode with timer
wakeup for power-efficient operation.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
from machine import Pin, deepsleep
import esp32
import time
led = Pin(2, [Link])
wake_reason = esp32.wake_reason()
if wake_reason == esp32.WAKEUP_TIMER:
print("Woke up from deep sleep (timer)")
elif wake_reason == esp32.WAKEUP_EXT0:
print("Woke up from external signal")
else:
print("Power on or reset")
print("Active mode - performing tasks...")
for i in range(5):
[Link]()
[Link](0.5)
[Link]()
[Link](0.5)
print("Task iteration:", i+1)
print("Entering deep sleep for 10 seconds...")
[Link](1)
deepsleep(10000)
20. Interrupt-Based Input Handling
Prompt: Create an ESP32 MicroPython program to handle button inputs using hardware
interrupts with debouncing and event counting.
Hardware Requirements:
● ESP32 Development Board
● 2x Push Buttons
● 2x 10kΩ Pull-down Resistors
● LED
● 220Ω Resistor
● Connections: Button1 to GPIO12, Button2 to GPIO14, LED to GPIO2
MicroPython Code:
from machine import Pin
import time
led = Pin(2, [Link])
button1 = Pin(12, [Link], Pin.PULL_DOWN)
button2 = Pin(14, [Link], Pin.PULL_DOWN)
button1_count = 0
button2_count = 0
last_time1 = 0
last_time2 = 0
def button1_handler(pin):
global button1_count, last_time1
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_time1) > 200:
button1_count += 1
print("Button 1 pressed | Count:", button1_count)
[Link]()
[Link](0.1)
[Link]()
last_time1 = current_time
def button2_handler(pin):
global button2_count, last_time2
current_time = time.ticks_ms()
if time.ticks_diff(current_time, last_time2) > 200:
button2_count += 1
print("Button 2 pressed | Count:", button2_count)
last_time2 = current_time
[Link](trigger=Pin.IRQ_RISING, handler=button1_handler)
[Link](trigger=Pin.IRQ_RISING, handler=button2_handler)
print("Interrupt-Based Input Handling Ready")
print("Press buttons to trigger interrupts")
while True:
[Link](1)
21. Watchdog Timer Fault Recovery
Prompt: Create an ESP32 MicroPython program to implement watchdog timer for automatic
system recovery from hangs or crashes.
Hardware Requirements:
● ESP32 Development Board
● LED
● 220Ω Resistor
● Connections: LED to GPIO2
MicroPython Code:
from machine import Pin, WDT
import time
led = Pin(2, [Link])
wdt = WDT(timeout=5000)
print("Watchdog Timer Fault Recovery System")
print("Watchdog timeout set to 5 seconds")
print("-" * 50)
iteration = 0
while True:
iteration += 1
print("Iteration:", iteration)
[Link]()
[Link](0.5)
[Link]()
[Link](0.5)
[Link]()
print("Watchdog fed")
if iteration == 10
print("Simulating system hang...")
print("Watchdog will reset the system in 5 seconds")
while True:
[Link](1)
[Link](2)
22. Event-Driven Programming Model
Prompt:
Create an ESP32 MicroPython program to demonstrate event-driven programming with multiple
event sources and handlers.
Hardware Requirements:
- ESP32 Development Board
- 2x Push Buttons
- 2x LEDs
- 2x 10kΩ Resistors
- 2x 220Ω Resistors
- Connections: Button1 to GPIO12, Button2 to GPIO14, LED1 to GPIO2, LED2 to GPIO4
MicroPython Code:
from machine import Pin, Timer
import time
led1 = Pin(2, [Link])
led2 = Pin(4, [Link])
button1 = Pin(12, [Link], Pin.PULL_DOWN)
button2 = Pin(14, [Link], Pin.PULL_DOWN)
event_queue = []
def button1_event(pin):
event_queue.append(("BUTTON1", time.ticks_ms()))
print("Event: Button 1 pressed")
def button2_event(pin):
event_queue.append(("BUTTON2", time.ticks_ms()))
print("Event: Button 2 pressed")
def timer_event(timer):
event_queue.append(("TIMER", time.ticks_ms()))
print("Event: Timer tick")
def process_events():
while event_queue:
event_type, timestamp = event_queue.pop(0)
print("Processing event:", event_type, "at", timestamp)
if event_type == "BUTTON1":
[Link]()
[Link](0.5)
[Link]()
elif event_type == "BUTTON2":
[Link]()
[Link](0.5)
[Link]()
elif event_type == "TIMER":
[Link]()
[Link]()
[Link](0.2)
[Link]()
[Link]()
[Link](trigger=Pin.IRQ_RISING, handler=button1_event)
[Link](trigger=Pin.IRQ_RISING, handler=button2_event)
timer = Timer(0)
[Link](period=5000, mode=[Link], callback=timer_event)
print("Event-Driven System Ready")
while True:
process_events()
[Link](0.1)
23. Error Detection & Logging System
Prompt: Create an ESP32 MicroPython program to implement error detection, logging, and
reporting with severity levels and timestamps.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
import random
class ErrorLogger:
def __init__(self):
self.error_count = 0
self.warning_count = 0
self.info_count = 0
self.log_file = "error_log.txt"
def log(self, level, message):
timestamp = [Link]()
log_entry = "[{}] {} - {}".format(timestamp, level, message)
print(log_entry)
if level == "ERROR":
self.error_count += 1
elif level == "WARNING":
self.warning_count += 1
elif level == "INFO":
self.info_count += 1
try:
with open(self.log_file, 'a') as f:
[Link](log_entry + "\n")
except:
print("Failed to write to log file")
def error(self, message):
[Link]("ERROR", message)
def warning(self, message):
[Link]("WARNING", message)
def info(self, message):
[Link]("INFO", message)
def report(self):
print("\n" + "-" * 50)
print("Error Report:")
print("Total Errors:", self.error_count)
print("Total Warnings:", self.warning_count)
print("Total Info:", self.info_count)
print("-" * 50)
logger = ErrorLogger()
print("Error Detection & Logging System")
[Link]("System started")
for i in range(10):
sensor_value = [Link](0, 100)
if sensor_value > 80:
[Link]("Sensor value critically high: {}".format(sensor_value))
elif sensor_value > 60:
[Link]("Sensor value elevated: {}".format(sensor_value))
else:
[Link]("Sensor value normal: {}".format(sensor_value))
[Link](2)
[Link]()
24. Circular / Ring Buffer for Data
Prompt: Create an ESP32 MicroPython program to implement a circular buffer for efficient data
storage and retrieval with overflow handling.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
import random
class CircularBuffer:
def __init__(self, size):
[Link] = size
[Link] = [None] * size
[Link] = 0
[Link] = 0
[Link] = 0
def is_full(self):
return [Link] == [Link]
def is_empty(self):
return [Link] == 0
def write(self, data):
[Link][[Link]] = data
[Link] = ([Link] + 1) % [Link]
if self.is_full():
[Link] = ([Link] + 1) % [Link]
print("Buffer full - overwriting oldest data")
else:
[Link] += 1
def read(self):
if self.is_empty():
print("Buffer empty")
return None
data = [Link][[Link]]
[Link] = ([Link] + 1) % [Link]
[Link] -= 1
return data
def display(self):
print("Buffer contents:", [Link])
print("Head:", [Link], "| Tail:", [Link], "| Count:", [Link])
buffer = CircularBuffer(5)
print("Circular Buffer Demo (Size: 5)")
print("-" * 50)
for i in range(8):
value = [Link](10, 99)
print("\nWriting:", value)
[Link](value)
[Link]()
[Link](1)
print("\n" + "-" * 50)
print("Reading data from buffer:")
for i in range(5):
data = [Link]()
print("Read:", data)
[Link]()
[Link](1)
25. Internet Time Sync (NTP)
Prompt: Create an ESP32 MicroPython program to synchronize system time with internet NTP
servers and display local time.
Hardware Requirements:
● ESP32 Development Board
● WiFi Router
MicroPython Code:
import network
import ntptime
import time
from machine import RTC
SSID = "YourWiFiSSID"
PASSWORD = "YourWiFiPassword"
wlan = [Link](network.STA_IF)
[Link](True)
[Link](SSID, PASSWORD)
print("Connecting to WiFi...")
while not [Link]():
[Link](1)
print("Connected! IP:", [Link]()[0])
rtc = RTC()
def sync_time():
try:
print("Syncing time with NTP server...")
[Link]()
print("Time synchronized successfully")
return True
except Exception as e:
print("Time sync failed:", e)
return False
def get_local_time():
current_time = [Link]()
return "{:04d}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(
current_time[0], current_time[1], current_time[2],
current_time[3], current_time[4], current_time[5]
)
sync_time()
print("-" * 50)
print("Internet Time Sync (NTP) System")
print("-" * 50)
while True:
print("Current Time:", get_local_time())
print("Unix Timestamp:", [Link]())
[Link](5)
SEGMENT 4: CORE ENGINEERING (DSA,
CONTROL, SIGNALS) – 71 to 105
DATA STRUCTURES & ALGORITHMS
1. Array Operations
Prompt: Create an ESP32 MicroPython program to demonstrate basic array operations
including insertion, deletion, searching, and traversal.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class ArrayOps:
def __init__(self, size):
[Link] = []
[Link] = size
def insert(self, element):
if len([Link]) < [Link]:
[Link](element)
print("Inserted:", element)
else:
print("Array is full")
def delete(self, element):
if element in [Link]:
[Link](element)
print("Deleted:", element)
else:
print("Element not found")
def search(self, element):
if element in [Link]:
index = [Link](element)
print("Found", element, "at index", index)
return index
else:
print("Element not found")
return -1
def display(self):
print("Array:", [Link])
print("Array Operations Demo")
print("-" * 50)
arr = ArrayOps(10)
[Link](10)
[Link](20)
[Link](30)
[Link](40)
[Link](50)
[Link]()
[Link](30)
[Link](20)
[Link]()
[Link](60)
[Link](70)
[Link]()
print("Array length:", len([Link]))
2. String Processing Algorithms
Prompt: Create an ESP32 MicroPython program to demonstrate string processing algorithms
including reverse, palindrome check, substring search, and character frequency.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def reverse_string(s):
return s[::-1]
def is_palindrome(s):
s = [Link]().replace(" ", "")
return s == s[::-1]
def substring_search(text, pattern):
index = [Link](pattern)
return index
def char_frequency(s):
freq = {}
for char in s:
if char in freq:
freq[char] += 1
else:
freq[char] = 1
return freq
def count_vowels(s):
vowels = "aeiouAEIOU"
count = 0
for char in s:
if char in vowels:
count += 1
return count
print("String Processing Algorithms")
print("-" * 50)
text = "ESP32 MicroPython"
print("Original:", text)
print("Reversed:", reverse_string(text))
print("-" * 50)
test_str = "madam"
print("String:", test_str)
print("Is Palindrome:", is_palindrome(test_str))
print("-" * 50)
pattern = "Micro"
index = substring_search(text, pattern)
print("Pattern '{}' found at index: {}".format(pattern, index))
print("-" * 50)
freq = char_frequency(text)
print("Character Frequency:", freq)
print("-" * 50)
print("Vowel count:", count_vowels(text))
3. Frequency Counter (Hashing)
Prompt: Create an ESP32 MicroPython program to implement frequency counter using hashing
to count occurrences of elements in a collection.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class FrequencyCounter:
def __init__(self):
self.freq_map = {}
def add(self, element):
if element in self.freq_map:
self.freq_map[element] += 1
else:
self.freq_map[element] = 1
def get_frequency(self, element):
return self.freq_map.get(element, 0)
def most_frequent(self):
if not self.freq_map:
return None
max_freq = max(self.freq_map.values())
for key, value in self.freq_map.items():
if value == max_freq:
return key, max_freq
def display(self):
print("Frequency Map:")
for key, value in self.freq_map.items():
print("{}: {}".format(key, value))
print("Frequency Counter (Hashing)")
print("-" * 50)
counter = FrequencyCounter()
data = [1, 2, 3, 2, 1, 4, 5, 3, 2, 1, 6, 3, 2]
print("Input data:", data)
for item in data:
[Link](item)
[Link]()
print("-" * 50)
print("Frequency of 2:", counter.get_frequency(2))
print("Frequency of 5:", counter.get_frequency(5))
print("-" * 50)
most_freq = counter.most_frequent()
print("Most frequent element: {} (appears {} times)".format(most_freq[0], most_freq[1]))
4. Linear Search Algorithm
Prompt: Create an ESP32 MicroPython program to implement linear search algorithm with
step-by-step visualization and comparison count.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def linear_search(arr, target):
comparisons = 0
print("Searching for:", target)
print("-" * 50)
for i in range(len(arr)):
comparisons += 1
print("Step {}: Checking arr[{}] = {}".format(comparisons, i, arr[i]))
if arr[i] == target:
print("Found at index:", i)
print("Total comparisons:", comparisons)
return i
[Link](0.5)
print("Element not found")
print("Total comparisons:", comparisons)
return -1
print("Linear Search Algorithm")
print("-" * 50)
arr = [15, 23, 8, 42, 17, 31, 9, 56, 12]
print("Array:", arr)
print("-" * 50)
target = 31
result = linear_search(arr, target)
print("=" * 50)
target = 100
result = linear_search(arr, target)
5. Binary Search Algorithm
Prompt: Create an ESP32 MicroPython program to implement binary search algorithm on
sorted arrays with step-by-step visualization.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def binary_search(arr, target):
left = 0
right = len(arr) - 1
comparisons = 0
print("Searching for:", target)
print("-" * 50)
while left <= right:
comparisons += 1
mid = (left + right) // 2
print("Step {}: left={}, mid={}, right={}".format(comparisons, left, mid, right))
print("Checking arr[{}] = {}".format(mid, arr[mid]))
if arr[mid] == target:
print("Found at index:", mid)
print("Total comparisons:", comparisons)
return mid
elif arr[mid] < target:
print("Target is in right half")
left = mid + 1
else:
print("Target is in left half")
right = mid - 1
print("-" * 50)
[Link](1)
print("Element not found")
print("Total comparisons:", comparisons)
return -1
print("Binary Search Algorithm")
print("-" * 50)
arr = [5, 12, 18, 23, 31, 42, 56, 67, 89]
print("Sorted Array:", arr)
print("-" * 50)
target = 42
result = binary_search(arr, target)
print("=" * 50)
target = 25
result = binary_search(arr, target)
6. Stack Implementation
Prompt: Create an ESP32 MicroPython program to implement stack data structure with push,
pop, peek operations and overflow/underflow handling.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Stack:
def __init__(self, size):
[Link] = []
[Link] = size
[Link] = -1
def is_empty(self):
return [Link] == -1
def is_full(self):
return [Link] == [Link] - 1
def push(self, data):
if self.is_full():
print("Stack Overflow! Cannot push", data)
return False
else:
[Link](data)
[Link] += 1
print("Pushed:", data)
return True
def pop(self):
if self.is_empty():
print("Stack Underflow! Cannot pop")
return None
else:
data = [Link]()
[Link] -= 1
print("Popped:", data)
return data
def peek(self):
if self.is_empty():
print("Stack is empty")
return None
else:
return [Link][[Link]]
def display(self):
print("Stack:", [Link])
print("Top index:", [Link])
print("Stack Implementation")
print("-" * 50)
stack = Stack(5)
[Link](10)
[Link](20)
[Link](30)
[Link]()
print("-" * 50)
print("Top element:", [Link]())
print("-" * 50)
[Link]()
[Link]()
[Link]()
print("-" * 50)
[Link](40)
[Link](50)
[Link](60)
[Link](70)
[Link]()
7. Circular Queue
Prompt: Create an ESP32 MicroPython program to implement circular queue with enqueue,
dequeue operations and efficient space utilization.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class CircularQueue:
def __init__(self, size):
[Link] = size
[Link] = [None] * size
[Link] = -1
[Link] = -1
def is_empty(self):
return [Link] == -1
def is_full(self):
return ([Link] + 1) % [Link] == [Link]
def enqueue(self, data):
if self.is_full():
print("Queue Full! Cannot enqueue", data)
return False
if self.is_empty():
[Link] = 0
[Link] = 0
else:
[Link] = ([Link] + 1) % [Link]
[Link][[Link]] = data
print("Enqueued:", data)
return True
def dequeue(self):
if self.is_empty():
print("Queue Empty! Cannot dequeue")
return None
data = [Link][[Link]]
if [Link] == [Link]:
[Link] = -1
[Link] = -1
else:
[Link] = ([Link] + 1) % [Link]
print("Dequeued:", data)
return data
def display(self):
if self.is_empty():
print("Queue is empty")
return
print("Queue:", end=" ")
i = [Link]
while True:
print([Link][i], end=" ")
if i == [Link]:
break
i = (i + 1) % [Link]
print()
print("Front:", [Link], "| Rear:", [Link])
print("Circular Queue Implementation")
print("-" * 50)
cq = CircularQueue(5)
[Link](10)
[Link](20)
[Link](30)
[Link]()
print("-" * 50)
[Link]()
[Link]()
[Link]()
print("-" * 50)
[Link](40)
[Link](50)
[Link](60)
[Link](70)
[Link]()
8. Singly Linked List
Prompt: Create an ESP32 MicroPython program to implement singly linked list with insertion,
deletion, and traversal operations.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Node:
def __init__(self, data):
[Link] = data
[Link] = None
class SinglyLinkedList:
def __init__(self):
[Link] = None
def insert_at_beginning(self, data):
new_node = Node(data)
new_node.next = [Link]
[Link] = new_node
print("Inserted", data, "at beginning")
def insert_at_end(self, data):
new_node = Node(data)
if not [Link]:
[Link] = new_node
return
temp = [Link]
while [Link]:
temp = [Link]
[Link] = new_node
print("Inserted", data, "at end")
def delete(self, key):
temp = [Link]
if temp and [Link] == key:
[Link] = [Link]
print("Deleted:", key)
return
prev = None
while temp and [Link] != key:
prev = temp
temp = [Link]
if temp is None:
print("Key not found")
return
[Link] = [Link]
print("Deleted:", key)
def display(self):
if not [Link]:
print("List is empty")
return
print("Linked List:", end=" ")
temp = [Link]
while temp:
print([Link], end=" -> ")
temp = [Link]
print("None")
print("Singly Linked List")
print("-" * 50)
sll = SinglyLinkedList()
sll.insert_at_end(10)
sll.insert_at_end(20)
sll.insert_at_end(30)
[Link]()
print("-" * 50)
sll.insert_at_beginning(5)
[Link]()
print("-" * 50)
[Link](20)
[Link]()
9. Doubly Linked List
Prompt: Create an ESP32 MicroPython program to implement doubly linked list with
bidirectional traversal and insertion/deletion operations.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Node:
def __init__(self, data):
[Link] = data
[Link] = None
[Link] = None
class DoublyLinkedList:
def __init__(self):
[Link] = None
def insert_at_end(self, data):
new_node = Node(data)
if not [Link]:
[Link] = new_node
print("Inserted", data)
return
temp = [Link]
while [Link]:
temp = [Link]
[Link] = new_node
new_node.prev = temp
print("Inserted", data)
def delete(self, key):
temp = [Link]
while temp and [Link] != key:
temp = [Link]
if temp is None:
print("Key not found")
return
if [Link]:
[Link] = [Link]
else:
[Link] = [Link]
if [Link]:
[Link] = [Link]
print("Deleted:", key)
def display_forward(self):
if not [Link]:
print("List is empty")
return
print("Forward:", end=" ")
temp = [Link]
while temp:
print([Link], end=" <-> ")
temp = [Link]
print("None")
def display_backward(self):
if not [Link]:
print("List is empty")
return
temp = [Link]
while [Link]:
temp = [Link]
print("Backward:", end=" ")
while temp:
print([Link], end=" <-> ")
temp = [Link]
print("None")
print("Doubly Linked List")
print("-" * 50)
dll = DoublyLinkedList()
dll.insert_at_end(10)
dll.insert_at_end(20)
dll.insert_at_end(30)
dll.insert_at_end(40)
dll.display_forward()
dll.display_backward()
print("-" * 50)
[Link](20)
dll.display_forward()
10. Recursion (Factorial, Fibonacci)
Prompt: Create an ESP32 MicroPython program to demonstrate recursion with factorial and
Fibonacci sequence calculations.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def factorial(n):
print("factorial({})".format(n))
if n == 0 or n == 1:
return 1
return n * factorial(n - 1)
def fibonacci(n):
print("fibonacci({})".format(n))
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
def fibonacci_iterative(n):
if n <= 1:
return n
a, b = 0, 1
for i in range(2, n + 1):
a, b = b, a + b
return b
print("Recursion - Factorial & Fibonacci")
print("=" * 50)
n=5
print("Factorial of", n)
print("-" * 50)
result = factorial(n)
print("Result:", result)
print("=" * 50)
n=6
print("Fibonacci of", n, "(Recursive)")
print("-" * 50)
result = fibonacci(n)
print("Result:", result)
print("=" * 50)
print("Fibonacci Sequence (Iterative):")
for i in range(10):
print("F({}) = {}".format(i, fibonacci_iterative(i)))
11. Sorting Algorithms (Basic)
Prompt: Create an ESP32 MicroPython program to implement basic sorting algorithms: Bubble
Sort, Selection Sort, and Insertion Sort with visualization.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def bubble_sort(arr):
n = len(arr)
print("Bubble Sort")
for i in range(n):
for j in range(0, n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
print("Swapped: {} <-> {}".format(arr[j + 1], arr[j]))
print("Pass {}: {}".format(i + 1, arr))
return arr
def selection_sort(arr):
n = len(arr)
print("Selection Sort")
for i in range(n):
min_idx = i
for j in range(i + 1, n):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
print("Pass {}: {}".format(i + 1, arr))
return arr
def insertion_sort(arr):
print("Insertion Sort")
for i in range(1, len(arr)):
key = arr[i]
j=i-1
while j >= 0 and arr[j] > key:
arr[j + 1] = arr[j]
j -= 1
arr[j + 1] = key
print("Pass {}: {}".format(i, arr))
return arr
print("Basic Sorting Algorithms")
print("=" * 50)
arr1 = [64, 34, 25, 12, 22]
print("Original:", arr1)
print("-" * 50)
sorted_arr = bubble_sort([Link]())
print("Sorted:", sorted_arr)
print("=" * 50)
arr2 = [64, 25, 12, 22, 11]
print("Original:", arr2)
print("-" * 50)
sorted_arr = selection_sort([Link]())
print("Sorted:", sorted_arr)
print("=" * 50)
arr3 = [12, 11, 13, 5, 6]
print("Original:", arr3)
print("-" * 50)
sorted_arr = insertion_sort([Link]())
print("Sorted:", sorted_arr)
12. Sorting Algorithms (Merge, Quick)
Prompt: Create an ESP32 MicroPython program to implement advanced sorting algorithms:
Merge Sort and Quick Sort with divide-and-conquer approach.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
result = []
i=j=0
while i < len(left) and j < len(right):
if left[i] <= right[j]:
[Link](left[i])
i += 1
else:
[Link](right[j])
j += 1
[Link](left[i:])
[Link](right[j:])
print("Merged:", result)
return result
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
print("Pivot: {} | Left: {} | Right: {}".format(pivot, left, right))
return quick_sort(left) + middle + quick_sort(right)
print("Advanced Sorting Algorithms")
print("=" * 50)
arr1 = [38, 27, 43, 3, 9, 82, 10]
print("Merge Sort")
print("Original:", arr1)
print("-" * 50)
sorted_arr = merge_sort([Link]())
print("Sorted:", sorted_arr)
print("=" * 50)
arr2 = [10, 7, 8, 9, 1, 5]
print("Quick Sort")
print("Original:", arr2)
print("-" * 50)
sorted_arr = quick_sort([Link]())
print("Sorted:", sorted_arr)
13. Prefix Sum Technique
Prompt: Create an ESP32 MicroPython program to implement prefix sum technique for efficient
range sum queries.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class PrefixSum:
def __init__(self, arr):
[Link] = arr
[Link] = [0] * (len(arr) + 1)
self.build_prefix()
def build_prefix(self):
print("Building prefix sum array...")
for i in range(len([Link])):
[Link][i + 1] = [Link][i] + [Link][i]
print("prefix[{}] = {}".format(i + 1, [Link][i + 1]))
def range_sum(self, left, right):
result = [Link][right + 1] - [Link][left]
print("Sum from index {} to {}: {}".format(left, right, result))
return result
def display(self):
print("Original array:", [Link])
print("Prefix sum:", [Link])
print("Prefix Sum Technique")
print("-" * 50)
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ps = PrefixSum(arr)
[Link]()
print("-" * 50)
ps.range_sum(2, 5)
ps.range_sum(0, 9)
ps.range_sum(4, 7)
print("-" * 50)
print("Comparing with brute force:")
left, right = 2, 5
brute_sum = sum(arr[left:right + 1])
print("Brute force sum:", brute_sum)
14. Sliding Window Algorithm
Prompt: Create an ESP32 MicroPython program to implement sliding window algorithm for
maximum sum subarray and other window-based problems.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def max_sum_subarray(arr, k):
if len(arr) < k:
print("Array size less than window size")
return -1
window_sum = sum(arr[:k])
max_sum = window_sum
print("Initial window sum:", window_sum)
print("Window:", arr[:k])
print("-" * 50)
for i in range(len(arr) - k):
window_sum = window_sum - arr[i] + arr[i + k]
print("Window:", arr[i + 1:i + k + 1])
print("Window sum:", window_sum)
if window_sum > max_sum:
max_sum = window_sum
print("New max found!")
print("-" * 50)
return max_sum
def first_negative_in_window(arr, k):
result = []
for i in range(len(arr) - k + 1):
window = arr[i:i + k]
first_neg = None
for num in window:
if num < 0:
first_neg = num
break
[Link](first_neg if first_neg else 0)
print("Window: {} | First negative: {}".format(window, first_neg))
return result
print("Sliding Window Algorithm")
print("=" * 50)
arr = [1, 4, 2, 10, 23, 3, 1, 0, 20]
k=4
print("Array:", arr)
print("Window size:", k)
print("-" * 50)
max_sum = max_sum_subarray(arr, k)
print("Maximum sum of subarray:", max_sum)
print("=" * 50)
arr2 = [12, -1, -7, 8, -15, 30, 16, 28]
k2 = 3
print("Array:", arr2)
print("Window size:", k2)
print("-" * 50)
result = first_negative_in_window(arr2, k2)
print("First negatives:", result)
15. Hash Table Implementation
Prompt: Create an ESP32 MicroPython program to implement hash table with collision handling
using chaining method.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class HashTable:
def __init__(self, size):
[Link] = size
[Link] = [[] for _ in range(size)]
def hash_function(self, key):
return hash(key) % [Link]
def insert(self, key, value):
hash_index = self.hash_function(key)
for i, (k, v) in enumerate([Link][hash_index]):
if k == key:
[Link][hash_index][i] = (key, value)
print("Updated: {} -> {} at index {}".format(key, value, hash_index))
return
[Link][hash_index].append((key, value))
print("Inserted: {} -> {} at index {}".format(key, value, hash_index))
def search(self, key):
hash_index = self.hash_function(key)
for k, v in [Link][hash_index]:
if k == key:
print("Found: {} -> {}".format(key, v))
return v
print("Key not found:", key)
return None
def delete(self, key):
hash_index = self.hash_function(key)
for i, (k, v) in enumerate([Link][hash_index]):
if k == key:
del [Link][hash_index][i]
print("Deleted:", key)
return True
print("Key not found:", key)
return False
def display(self):
print("Hash Table:")
for i, bucket in enumerate([Link]):
if bucket:
print("Index {}: {}".format(i, bucket))
print("Hash Table Implementation")
print("-" * 50)
ht = HashTable(10)
[Link]("name", "ESP32")
[Link]("temp", 25)
[Link]("humidity", 60)
[Link]("pressure", 1013)
[Link]()
print("-" * 50)
[Link]("temp")
[Link]("voltage")
print("-" * 50)
[Link]("humidity")
[Link]()
16. Binary Tree Traversals
Prompt: Create an ESP32 MicroPython program to implement binary tree with inorder,
preorder, and postorder traversals.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Node:
def __init__(self, data):
[Link] = data
[Link] = None
[Link] = None
class BinaryTree:
def __init__(self):
[Link] = None
def inorder(self, node):
if node:
[Link]([Link])
print([Link], end=" ")
[Link]([Link])
def preorder(self, node):
if node:
print([Link], end=" ")
[Link]([Link])
[Link]([Link])
def postorder(self, node):
if node:
[Link]([Link])
[Link]([Link])
print([Link], end=" ")
print("Binary Tree Traversals")
print("-" * 50)
tree = BinaryTree()
[Link] = Node(1)
[Link] = Node(2)
[Link] = Node(3)
[Link] = Node(4)
[Link] = Node(5)
[Link] = Node(6)
[Link] = Node(7)
print("Tree Structure:")
print(" 1")
print(" / \\")
print(" 2 3")
print(" / \\ / \\")
print(" 4 5 6 7")
print("-" * 50)
print("Inorder (Left-Root-Right):", end=" ")
[Link]([Link])
print()
print("Preorder (Root-Left-Right):", end=" ")
[Link]([Link])
print()
print("Postorder (Left-Right-Root):", end=" ")
[Link]([Link])
print()
---
## 17. Binary Search Tree Operations
**Prompt:**
Create an ESP32 MicroPython program to implement Binary Search Tree with insertion,
searching, and deletion operations.
**Hardware Requirements:**
- ESP32 Development Board
**MicroPython Code:**
```python
import time
class Node:
def __init__(self, data):
[Link] = data
[Link] = None
[Link] = None
class BST:
def __init__(self):
[Link] = None
def insert(self, data):
if not [Link]:
[Link] = Node(data)
print("Inserted root:", data)
else:
self._insert_recursive([Link], data)
def _insert_recursive(self, node, data):
if data < [Link]:
if [Link] is None:
[Link] = Node(data)
print("Inserted {} to left of {}".format(data, [Link]))
else:
self._insert_recursive([Link], data)
else:
if [Link] is None:
[Link] = Node(data)
print("Inserted {} to right of {}".format(data, [Link]))
else:
self._insert_recursive([Link], data)
def search(self, data):
return self._search_recursive([Link], data)
def _search_recursive(self, node, data):
if node is None:
return False
if [Link] == data:
return True
elif data < [Link]:
return self._search_recursive([Link], data)
else:
return self._search_recursive([Link], data)
def inorder(self, node):
if node:
[Link]([Link])
print([Link], end=" ")
[Link]([Link])
print("Binary Search Tree Operations")
print("-" * 50)
bst = BST()
values = [50, 30, 70, 20, 40, 60, 80]
print("Inserting:", values)
print("-" * 50)
for val in values:
[Link](val)
print("-" * 50)
print("Inorder traversal:", end=" ")
[Link]([Link])
print()
print("-" * 50)
search_values = [40, 25, 80]
for val in search_values:
found = [Link](val)
print("Search {}: {}".format(val, "Found" if found else "Not Found"))
18. Heap (Min & Max)
Prompt: Create an ESP32 MicroPython program to implement Min Heap and Max Heap with
insertion, deletion, and heapify operations.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class MinHeap:
def __init__(self):
[Link] = []
def parent(self, i):
return (i - 1) // 2
def left_child(self, i):
return 2 * i + 1
def right_child(self, i):
return 2 * i + 2
def insert(self, key):
[Link](key)
self._heapify_up(len([Link]) - 1)
print("Inserted:", key)
def _heapify_up(self, i):
while i > 0 and [Link][[Link](i)] > [Link][i]:
[Link][i], [Link][[Link](i)] = [Link][[Link](i)], [Link][i]
i = [Link](i)
def extract_min(self):
if not [Link]:
return None
min_val = [Link][0]
[Link][0] = [Link][-1]
[Link]()
if [Link]:
self._heapify_down(0)
print("Extracted min:", min_val)
return min_val
def _heapify_down(self, i):
min_index = i
left = self.left_child(i)
right = self.right_child(i)
if left < len([Link]) and [Link][left] < [Link][min_index]:
min_index = left
if right < len([Link]) and [Link][right] < [Link][min_index]:
min_index = right
if min_index != i:
[Link][i], [Link][min_index] = [Link][min_index], [Link][i]
self._heapify_down(min_index)
def display(self):
print("Heap:", [Link])
print("Min Heap Implementation")
print("-" * 50)
min_heap = MinHeap()
values = [5, 3, 8, 1, 9, 2]
print("Inserting:", values)
for val in values:
min_heap.insert(val)
min_heap.display()
print("-" * 50)
print("Extracting minimum values:")
for _ in range(3):
min_heap.extract_min()
min_heap.display()
19. Priority Queue Scheduler
Prompt: Create an ESP32 MicroPython program to implement priority queue-based task
scheduler with priority levels.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Task:
def __init__(self, name, priority):
[Link] = name
[Link] = priority
def __lt__(self, other):
return [Link] < [Link]
class PriorityQueue:
def __init__(self):
[Link] = []
def enqueue(self, task):
[Link](task)
[Link]()
print("Added task: {} (Priority: {})".format([Link], [Link]))
def dequeue(self):
if self.is_empty():
print("Queue is empty")
return None
task = [Link](0)
print("Executing task: {} (Priority: {})".format([Link], [Link]))
return task
def is_empty(self):
return len([Link]) == 0
def display(self):
print("Priority Queue:")
for task in [Link]:
print(" {} - Priority: {}".format([Link], [Link]))
print("Priority Queue Scheduler")
print("-" * 50)
scheduler = PriorityQueue()
[Link](Task("Read Sensor", 2))
[Link](Task("Emergency Stop", 1))
[Link](Task("Log Data", 5))
[Link](Task("Send Alert", 1))
[Link](Task("Update Display", 3))
print("-" * 50)
[Link]()
print("-" * 50)
print("Executing tasks in priority order:")
while not scheduler.is_empty():
[Link]()
[Link](1)
20. Graph Representation
Prompt: Create an ESP32 MicroPython program to implement graph representation using
adjacency list and adjacency matrix.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Graph:
def __init__(self, vertices):
[Link] = vertices
self.adj_list = {i: [] for i in range(vertices)}
self.adj_matrix = [[0] * vertices for _ in range(vertices)]
def add_edge(self, u, v):
self.adj_list[u].append(v)
self.adj_list[v].append(u)
self.adj_matrix[u][v] = 1
self.adj_matrix[v][u] = 1
print("Added edge: {} - {}".format(u, v))
def display_adj_list(self):
print("Adjacency List:")
for vertex in range([Link]):
print("{}: {}".format(vertex, self.adj_list[vertex]))
def display_adj_matrix(self):
print("Adjacency Matrix:")
for row in self.adj_matrix:
print(row)
print("Graph Representation")
print("-" * 50)
g = Graph(5)
edges = [(0, 1), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (3, 4)]
print("Adding edges:")
for u, v in edges:
g.add_edge(u, v)
print("-" * 50)
g.display_adj_list()
print("-" * 50)
g.display_adj_matrix()
21. BFS & DFS Traversals
Prompt: Create an ESP32 MicroPython program to implement Breadth-First Search (BFS) and
Depth-First Search (DFS) graph traversal algorithms.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Graph:
def __init__(self, vertices):
[Link] = vertices
self.adj_list = {i: [] for i in range(vertices)}
def add_edge(self, u, v):
self.adj_list[u].append(v)
self.adj_list[v].append(u)
def bfs(self, start):
visited = [False] * [Link]
queue = [start]
visited[start] = True
print("BFS Traversal from node {}:".format(start))
while queue:
vertex = [Link](0)
print("Visited:", vertex)
for neighbor in self.adj_list[vertex]:
if not visited[neighbor]:
[Link](neighbor)
visited[neighbor] = True
print(" Enqueued:", neighbor)
def dfs(self, start):
visited = [False] * [Link]
print("DFS Traversal from node {}:".format(start))
self._dfs_recursive(start, visited)
def _dfs_recursive(self, vertex, visited):
visited[vertex] = True
print("Visited:", vertex)
for neighbor in self.adj_list[vertex]:
if not visited[neighbor]:
print(" Moving to:", neighbor)
self._dfs_recursive(neighbor, visited)
print("BFS & DFS Traversals")
print("-" * 50)
g = Graph(6)
edges = [(0, 1), (0, 2), (1, 3), (1, 4), (2, 4), (3, 5), (4, 5)]
for u, v in edges:
g.add_edge(u, v)
print("Graph edges:", edges)
print("=" * 50)
[Link](0)
print("=" * 50)
[Link](0)
22. Dijkstra's Shortest Path
Prompt: Create an ESP32 MicroPython program to implement Dijkstra's algorithm for finding
shortest path in weighted graphs.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
class Graph:
def __init__(self, vertices):
[Link] = vertices
[Link] = [[0 for _ in range(vertices)] for _ in range(vertices)]
def add_edge(self, u, v, weight):
[Link][u][v] = weight
[Link][v][u] = weight
print("Added edge: {} - {} (weight: {})".format(u, v, weight))
def min_distance(self, dist, visited):
min_dist = float('inf')
min_index = -1
for v in range([Link]):
if dist[v] < min_dist and not visited[v]:
min_dist = dist[v]
min_index = v
return min_index
def dijkstra(self, src):
dist = [float('inf')] * [Link]
dist[src] = 0
visited = [False] * [Link]
print("Starting Dijkstra from node", src)
print("-" * 50)
for _ in range([Link]):
u = self.min_distance(dist, visited)
visited[u] = True
print("Visiting node:", u, "| Distance:", dist[u])
for v in range([Link]):
if ([Link][u][v] > 0 and not visited[v] and
dist[v] > dist[u] + [Link][u][v]):
dist[v] = dist[u] + [Link][u][v]
print(" Updated distance to {}: {}".format(v, dist[v]))
print("-" * 50)
print("Shortest distances from node {}:".format(src))
for i in range([Link]):
print("Node {}: {}".format(i, dist[i]))
print("Dijkstra's Shortest Path Algorithm")
print("-" * 50)
g = Graph(6)
g.add_edge(0, 1, 4)
g.add_edge(0, 2, 2)
g.add_edge(1, 2, 1)
g.add_edge(1, 3, 5)
g.add_edge(2, 3, 8)
g.add_edge(2, 4, 10)
g.add_edge(3, 4, 2)
g.add_edge(3, 5, 6)
g.add_edge(4, 5, 3)
print("-" * 50)
[Link](0)
23. Dynamic Programming (Knapsack)
Prompt: Create an ESP32 MicroPython program to implement 0/1 Knapsack problem using
dynamic programming approach.
Hardware Requirements:
● ESP32 Development Board
MicroPython Code:
import time
def knapsack(weights, values, capacity):
n = len(weights)
dp = [[0 for _ in range(capacity + 1)] for _ in range(n + 1)]
print("0/1 Knapsack Problem")
print("Capacity:", capacity)
print("Items:", n)
print("-" * 50)
for i in range(1, n + 1):
for w in range(1, capacity + 1):
if weights[i - 1] <= w:
dp[i][w] = max(values[i - 1] + dp[i - 1][w - weights[i - 1]],
dp[i - 1][w])
else:
dp[i][w] = dp[i - 1][w]
print("DP Table (last row):")
print(dp[n])
print("-" * 50)
selected = []
w = capacity
for i in range(n, 0, -1):
if dp[i][w] != dp[i - 1][w]:
[Link](i - 1)
w -= weights[i - 1]
[Link]()
print("Maximum value:", dp[n][capacity])
print("Selected items (0-indexed):", selected)
print("Total weight:", sum(weights[i] for i in selected))
print("-" * 50)
for i in selected:
print("Item {}: Weight={}, Value={}".format(i, weights[i], values[i]))
return dp[n][capacity]
print("Dynamic Programming - Knapsack")
print("=" * 50)
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
capacity = 8
print("Weights:", weights)
print("Values:", values)
print("-" * 50)
max_value = knapsack(weights, values, capacity)
Math, Control & Signal Processing -
MicroPython Projects
1. Numerical Integration
Prompt: Create a MicroPython program that performs numerical integration using Trapezoidal
and Simpson's rules to calculate definite integrals of mathematical functions and sensor data.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico / ESP8266
● No external components needed (computational only)
● USB cable for programming and power
Additional Details:
● Implements Trapezoidal rule for general integration
● Implements Simpson's 1/3 rule for higher accuracy
● Can integrate discrete sensor data points
● Useful for calculating areas, signal energy, and accumulated values
● Works with any mathematical function
MicroPython Code:
import math
import time
class NumericalIntegrator:
"""Numerical integration using Trapezoidal and Simpson's rules"""
@staticmethod
def trapezoidal(func, a, b, n=1000):
"""
Trapezoidal rule: Integral = h * [f(a)/2 + sum(f(x_i)) + f(b)/2]
func: function to integrate
a, b: integration limits
n: number of subdivisions
"""
h = (b - a) / n
result = 0.5 * (func(a) + func(b))
for i in range(1, n):
x=a+i*h
result += func(x)
return result * h
@staticmethod
def simpson(func, a, b, n=1000):
"""
Simpson's 1/3 rule (n must be even)
More accurate than trapezoidal for smooth functions
"""
if n % 2 == 1:
n += 1
h = (b - a) / n
result = func(a) + func(b)
for i in range(1, n, 2):
x=a+i*h
result += 4 * func(x)
for i in range(2, n-1, 2):
x=a+i*h
result += 2 * func(x)
return result * h / 3
@staticmethod
def integrate_data(data, dx=1.0):
"""
Integrate discrete data points using trapezoidal rule
data: list of y values
dx: spacing between points
"""
result = 0.0
for i in range(len(data) - 1):
result += (data[i] + data[i+1]) / 2.0 * dx
return result
# Test functions
def test_integration():
integrator = NumericalIntegrator()
print("=== Numerical Integration Test ===\n")
# Test 1: sin(x) from 0 to pi (exact = 2.0)
def sin_func(x):
return [Link](x)
result_trap = [Link](sin_func, 0, [Link], 1000)
result_simp = [Link](sin_func, 0, [Link], 1000)
print("Test 1: Integral of sin(x) from 0 to pi")
print(f" Trapezoidal: {result_trap:.6f}")
print(f" Simpson: {result_simp:.6f}")
print(f" Exact: 2.000000")
print(f" Error (Trap): {abs(result_trap - 2.0):.6f}")
print(f" Error (Simp): {abs(result_simp - 2.0):.6f}\n")
# Test 2: x^2 from 0 to 3 (exact = 9.0)
def square(x):
return x * x
result_trap2 = [Link](square, 0, 3, 1000)
result_simp2 = [Link](square, 0, 3, 1000)
print("Test 2: Integral of x^2 from 0 to 3")
print(f" Trapezoidal: {result_trap2:.6f}")
print(f" Simpson: {result_simp2:.6f}")
print(f" Exact: 9.000000\n")
# Test 3: Integrate sensor data
sensor_data = [0, 1, 4, 9, 16, 25, 36] # y = x^2
area = integrator.integrate_data(sensor_data, dx=1.0)
print("Test 3: Sensor data integration")
print(f" Data: {sensor_data}")
print(f" Area under curve: {area:.2f}\n")
print("Integration tests complete!")
# Run test
test_integration()
2. Numerical Differentiation
Prompt: Create a MicroPython program to calculate derivatives of functions and discrete sensor
data using finite difference methods for velocity calculation and rate of change analysis.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico / ESP8266
● Optional: Accelerometer/Temperature sensor for real-time differentiation
● USB cable for programming
Additional Details:
● Forward, backward, and central difference methods
● Smoothing filter for noisy data
● Essential for calculating velocity from position data
● Used in control systems and signal processing
● Handles discrete sensor measurements
MicroPython Code:
import math
import time
class NumericalDifferentiator:
"""Numerical differentiation using finite differences"""
@staticmethod
def forward_difference(func, x, h=1e-5):
"""Forward difference: f'(x) ≈ (f(x+h) - f(x)) / h"""
return (func(x + h) - func(x)) / h
@staticmethod
def backward_difference(func, x, h=1e-5):
"""Backward difference: f'(x) ≈ (f(x) - f(x-h)) / h"""
return (func(x) - func(x - h)) / h
@staticmethod
def central_difference(func, x, h=1e-5):
"""Central difference: f'(x) ≈ (f(x+h) - f(x-h)) / (2h)"""
return (func(x + h) - func(x - h)) / (2 * h)
@staticmethod
def differentiate_data(data, dt=1.0, method='central'):
"""
Differentiate discrete data points
data: list of y values
dt: time step between samples
method: 'forward', 'backward', or 'central'
"""
n = len(data)
result = [0.0] * n
if method == 'forward':
for i in range(n - 1):
result[i] = (data[i+1] - data[i]) / dt
result[-1] = result[-2]
elif method == 'backward':
result[0] = result[1] if n > 1 else 0
for i in range(1, n):
result[i] = (data[i] - data[i-1]) / dt
else: # central
result[0] = (data[1] - data[0]) / dt if n > 1 else 0
for i in range(1, n - 1):
result[i] = (data[i+1] - data[i-1]) / (2 * dt)
result[-1] = (data[-1] - data[-2]) / dt if n > 1 else 0
return result
@staticmethod
def smooth_differentiate(data, dt=1.0, window=3):
"""
Differentiate with moving average smoothing
Reduces noise in derivative calculation
"""
smoothed = [0.0] * len(data)
half_window = window // 2
for i in range(len(data)):
start = max(0, i - half_window)
end = min(len(data), i + half_window + 1)
smoothed[i] = sum(data[start:end]) / (end - start)
return NumericalDifferentiator.differentiate_data(smoothed, dt, 'central')
# Test differentiation
def test_differentiation():
diff = NumericalDifferentiator()
print("=== Numerical Differentiation Test ===\n")
# Test 1: Derivative of x^2 at x=5 (exact = 2x = 10)
def square(x):
return x * x
x_test = 5.0
deriv_forward = diff.forward_difference(square, x_test)
deriv_backward = diff.backward_difference(square, x_test)
deriv_central = diff.central_difference(square, x_test)
exact = 2 * x_test
print(f"Test 1: Derivative of x^2 at x={x_test}")
print(f" Forward: {deriv_forward:.6f}")
print(f" Backward: {deriv_backward:.6f}")
print(f" Central: {deriv_central:.6f}")
print(f" Exact: {exact:.6f}")
print(f" Error (Central): {abs(deriv_central - exact):.9f}\n")
# Test 2: Position to velocity (x = t^2)
position = [0, 1, 4, 9, 16, 25, 36, 49] # t = 0,1,2,3,4,5,6,7
velocity = diff.differentiate_data(position, dt=1.0, method='central')
print("Test 2: Velocity from position (x = t^2)")
print(f" Position: {position}")
print(f" Velocity: {[f'{v:.1f}' for v in velocity]}")
print(f" Expected: [0, 2, 4, 6, 8, 10, 12, 14] (approx)\n")
# Test 3: Noisy data with smoothing
noisy_position = [0, 1.2, 3.8, 9.3, 15.7, 25.2, 35.8, 49.1]
velocity_noisy = diff.differentiate_data(noisy_position, dt=1.0, method='central')
velocity_smooth = diff.smooth_differentiate(noisy_position, dt=1.0, window=3)
print("Test 3: Noisy data differentiation")
print(f" Noisy data: {noisy_position}")
print(f" Direct diff: {[f'{v:.1f}' for v in velocity_noisy]}")
print(f" Smoothed diff: {[f'{v:.1f}' for v in velocity_smooth]}\n")
print("Differentiation tests complete!")
# Run test
test_differentiation()
3. FFT Spectrum Analyzer
Prompt: Create an ESP32 MicroPython program to perform Fast Fourier Transform (FFT) on
audio signals to analyze frequency content and detect dominant frequencies in real-time.
Hardware Requirements:
● ESP32 Development Board (needs sufficient RAM)
● MAX9814 or INMP441 Microphone Module
● Optional: 0.96" OLED Display (SSD1306) for spectrum visualization
● Connections:
○ Microphone OUT → GPIO34 (ADC)
○ OLED SDA → GPIO21, SCL → GPIO22
Additional Details:
● Implements Cooley-Tukey FFT algorithm
● Works best with power-of-2 sample sizes (64, 128, 256, 512)
● Calculates magnitude and power spectrum
● Identifies dominant frequency peaks
● Useful for audio processing, vibration analysis, signal detection
MicroPython Code:
import math
import time
from machine import Pin, ADC
class FFT:
"""Fast Fourier Transform implementation"""
@staticmethod
def fft(x):
"""
Cooley-Tukey FFT algorithm
x: complex input array (list of [real, imag] pairs)
Returns: complex output array
"""
N = len(x)
if N <= 1:
return x
# Divide
even = [Link]([x[i] for i in range(0, N, 2)])
odd = [Link]([x[i] for i in range(1, N, 2)])
# Conquer
T = []
for k in range(N // 2):
angle = -2 * [Link] * k / N
w_real = [Link](angle)
w_imag = [Link](angle)
# Complex multiplication: w * odd[k]
t_real = w_real * odd[k][0] - w_imag * odd[k][1]
t_imag = w_real * odd[k][1] + w_imag * odd[k][0]
[Link]([t_real, t_imag])
result = [[0, 0] for _ in range(N)]
for k in range(N // 2):
result[k][0] = even[k][0] + T[k][0]
result[k][1] = even[k][1] + T[k][1]
result[k + N//2][0] = even[k][0] - T[k][0]
result[k + N//2][1] = even[k][1] - T[k][1]
return result
@staticmethod
def magnitude_spectrum(fft_result):
"""Calculate magnitude spectrum from FFT result"""
return [[Link](r[0]**2 + r[1]**2) for r in fft_result]
@staticmethod
def power_spectrum(fft_result):
"""Calculate power spectrum from FFT result"""
return [r[0]**2 + r[1]**2 for r in fft_result]
@staticmethod
def find_dominant_frequency(signal, sample_rate):
"""
Find dominant frequency in signal
signal: real-valued input signal
sample_rate: sampling rate in Hz
Returns: (dominant_frequency, magnitude_spectrum)
"""
N = len(signal)
# Pad to power of 2
n_pow2 = 1
while n_pow2 < N:
n_pow2 *= 2
# Convert to complex
complex_signal = [[signal[i] if i < N else 0, 0] for i in range(n_pow2)]
# Perform FFT
fft_result = [Link](complex_signal)
# Calculate magnitude spectrum (only first half)
magnitudes = FFT.magnitude_spectrum(fft_result[:n_pow2//2])
# Find peak (skip DC component at index 0)
max_mag = 0
max_idx = 0
for i in range(1, len(magnitudes)):
if magnitudes[i] > max_mag:
max_mag = magnitudes[i]
max_idx = i
# Convert index to frequency
dominant_freq = max_idx * sample_rate / n_pow2
return dominant_freq, magnitudes
class SpectrumAnalyzer:
"""Real-time spectrum analyzer"""
def __init__(self, adc_pin, sample_rate=8000, fft_size=128):
"""
Initialize spectrum analyzer
adc_pin: GPIO pin number for ADC
sample_rate: sampling rate in Hz
fft_size: number of samples for FFT (power of 2)
"""
[Link] = ADC(Pin(adc_pin))
[Link](ADC.ATTN_11DB) # 0-3.3V range
[Link](ADC.WIDTH_12BIT) # 12-bit resolution
self.sample_rate = sample_rate
self.fft_size = fft_size
self.sample_period_us = int(1000000 / sample_rate)
def capture_samples(self):
"""Capture audio samples"""
samples = []
for _ in range(self.fft_size):
start = time.ticks_us()
sample = [Link]() - 2048 # Center around zero
[Link](sample)
# Wait for next sample
elapsed = time.ticks_diff(time.ticks_us(), start)
if elapsed < self.sample_period_us:
time.sleep_us(self.sample_period_us - elapsed)
return samples
def analyze(self):
"""
Capture and analyze spectrum
Returns: (dominant_freq, magnitudes, frequencies)
"""
# Capture samples
samples = self.capture_samples()
# Perform FFT
dominant_freq, magnitudes = FFT.find_dominant_frequency(samples, self.sample_rate)
# Calculate frequency bins
frequencies = [i * self.sample_rate / self.fft_size for i in range(len(magnitudes))]
return dominant_freq, magnitudes, frequencies
# Test with simulated data
def test_fft():
print("=== FFT Spectrum Analyzer Test ===\n")
# Generate test signal: 440 Hz (A4 note) + 880 Hz (A5 note)
sample_rate = 8000 # Hz
duration = 0.125 # seconds
N = int(sample_rate * duration)
print(f"Generating test signal:")
print(f" Sample rate: {sample_rate} Hz")
print(f" Duration: {duration} s")
print(f" Samples: {N}")
print(f" Frequencies: 440 Hz + 880 Hz\n")
signal = []
for i in range(N):
t = i / sample_rate
value = [Link](2 * [Link] * 440 * t) + 0.5 * [Link](2 * [Link] * 880 * t)
[Link](value)
# Perform FFT analysis
dominant_freq, spectrum = FFT.find_dominant_frequency(signal, sample_rate)
print(f"Dominant frequency detected: {dominant_freq:.2f} Hz")
print(f"Expected: 440 Hz\n")
# Find top frequency components
n = len(spectrum)
freqs = [i * sample_rate / (2 * n) for i in range(n)]
# Sort by magnitude
indexed_spectrum = [(i, spectrum[i]) for i in range(len(spectrum))]
indexed_spectrum.sort(key=lambda x: x[1], reverse=True)
print("Top 5 frequency components:")
for i in range(min(5, len(indexed_spectrum))):
idx, mag = indexed_spectrum[i]
if idx > 0: # Skip DC
print(f" {freqs[idx]:.2f} Hz: magnitude {mag:.2f}")
print("\nFFT test complete!")
# Run test
test_fft()
# Real-time analyzer example (uncomment to use with microphone)
"""
# Initialize spectrum analyzer
analyzer = SpectrumAnalyzer(adc_pin=34, sample_rate=8000, fft_size=128)
print("Real-time Spectrum Analyzer Started")
print("Press Ctrl+C to stop\n")
try:
while True:
# Analyze spectrum
dominant_freq, magnitudes, frequencies = [Link]()
# Display results
print(f"Dominant: {dominant_freq:.1f} Hz", end=" | ")
# Show spectrum bars (simple text visualization)
max_mag = max(magnitudes[1:20]) if max(magnitudes[1:20]) > 0 else 1
for i in range(1, 20, 2):
bar_height = int(10 * magnitudes[i] / max_mag)
print("#" * bar_height, end=" ")
print()
[Link](0.1)
except KeyboardInterrupt:
print("\nAnalyzer stopped")
"""
4. FIR Digital Filter
Prompt: Create a MicroPython program implementing Finite Impulse Response (FIR) digital
filters for signal processing, noise removal, and frequency band extraction from sensor data.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● Analog sensor (accelerometer, microphone, temperature sensor, etc.)
● Optional: Signal generator for testing
● Connections: Sensor analog output → GPIO34/35 (ADC pins)
Additional Details:
● Implements lowpass, highpass, and bandpass filters
● Uses windowed sinc method for filter design
● Linear phase response (no signal distortion)
● Circular buffer for efficient real-time filtering
● Configurable filter order and cutoff frequencies
MicroPython Code:
import math
import time
from machine import Pin, ADC
class FIRFilter:
"""Finite Impulse Response (FIR) Digital Filter"""
def __init__(self, coefficients):
"""
Initialize FIR filter with coefficients
coefficients: filter tap weights (list)
"""
[Link] = coefficients
[Link] = [0.0] * len(coefficients)
[Link] = 0
def filter(self, sample):
"""
Process one sample through the filter
sample: input sample value
Returns: filtered output
"""
# Add new sample to circular buffer
[Link][[Link]] = sample
[Link] = ([Link] + 1) % len([Link])
# Calculate output (convolution)
output = 0.0
buf_idx = [Link]
for coef in [Link]:
buf_idx = (buf_idx - 1) % len([Link])
output += coef * [Link][buf_idx]
return output
def filter_signal(self, signal):
"""Filter entire signal array"""
return [[Link](s) for s in signal]
def reset(self):
"""Clear filter state"""
[Link] = [0.0] * len([Link])
[Link] = 0
@staticmethod
def design_lowpass(cutoff_freq, sample_rate, num_taps=51):
"""
Design lowpass FIR filter using windowed sinc method
cutoff_freq: -3dB frequency in Hz
sample_rate: sampling rate in Hz
num_taps: number of filter coefficients (odd number recommended)
Returns: list of filter coefficients
"""
if num_taps % 2 == 0:
num_taps += 1
# Normalize cutoff frequency
fc = cutoff_freq / sample_rate
# Generate sinc function
coefficients = []
M = (num_taps - 1) // 2
for n in range(num_taps):
m=n-M
if m == 0:
h = 2 * fc
else:
h = [Link](2 * [Link] * fc * m) / ([Link] * m)
# Apply Hamming window
window = 0.54 - 0.46 * [Link](2 * [Link] * n / (num_taps - 1))
[Link](h * window)
# Normalize to unity gain at DC
total = sum(coefficients)
coefficients = [c / total for c in coefficients]
return coefficients
@staticmethod
def design_highpass(cutoff_freq, sample_rate, num_taps=51):
"""
Design highpass FIR filter using spectral inversion
cutoff_freq: -3dB frequency in Hz
sample_rate: sampling rate in Hz
num_taps: number of filter coefficients
Returns: list of filter coefficients
"""
# Design lowpass filter
lp_coef = FIRFilter.design_lowpass(cutoff_freq, sample_rate, num_taps)
# Spectral inversion
hp_coef = [-c for c in lp_coef]
hp_coef[len(hp_coef)//2] += 1
return hp_coef
@staticmethod
def design_bandpass(low_freq, high_freq, sample_rate, num_taps=51):
"""
Design bandpass FIR filter
low_freq: lower cutoff frequency in Hz
high_freq: upper cutoff frequency in Hz
sample_rate: sampling rate in Hz
num_taps: number of filter coefficients
Returns: list of filter coefficients
"""
# Design two lowpass filters and subtract
lp1 = FIRFilter.design_lowpass(high_freq, sample_rate, num_taps)
lp2 = FIRFilter.design_lowpass(low_freq, sample_rate, num_taps)
bp_coef = [lp1[i] - lp2[i] for i in range(num_taps)]
return bp_coef
# Test FIR filter
def test_fir_filter():
print("=== FIR Digital Filter Test ===\n")
# Filter parameters
sample_rate = 1000 # Hz
cutoff = 50 # Hz
num_taps = 31
print(f"Filter Design:")
print(f" Type: Lowpass")
print(f" Cutoff: {cutoff} Hz")
print(f" Sample rate: {sample_rate} Hz")
print(f" Number of taps: {num_taps}\n")
# Design lowpass filter
coefficients = FIRFilter.design_lowpass(cutoff, sample_rate, num_taps)
fir = FIRFilter(coefficients)
print(f"First 5 coefficients: {[f'{c:.6f}' for c in coefficients[:5]]}")
print(f"Last 5 coefficients: {[f'{c:.6f}' for c in coefficients[-5:]]}\n")
# Generate test signal: 25 Hz (pass) + 150 Hz (reject) + noise
print("Generating test signal:")
print(" 25 Hz sine wave (should pass)")
print(" 150 Hz sine wave (should be rejected)")
N = 500
signal = []
for i in range(N):
t = i / sample_rate
s = ([Link](2 * [Link] * 25 * t) +
0.5 * [Link](2 * [Link] * 150 * t))
[Link](s)
# Filter signal
filtered = fir.filter_signal(signal)
# Calculate energy (simple measure of amplitude)
original_energy = sum(s**2 for s in signal) / N
filtered_energy = sum(s**2 for s in filtered) / N
print(f"\nResults:")
print(f" Original signal energy: {original_energy:.4f}")
print(f" Filtered signal energy: {filtered_energy:.4f}")
print(f" Energy reduction: {(1 - filtered_energy/original_energy)*100:.1f}%")
print(" (High frequency component should be attenuated)\n")
# Test highpass filter
print("Highpass Filter Design:")
hp_coef = FIRFilter.design_highpass(cutoff, sample_rate, num_taps)
print(f" Cutoff: {cutoff} Hz")
print(f" Coefficients designed: {len(hp_coef)}\n")
# Test bandpass filter
print("Bandpass Filter Design:")
bp_coef = FIRFilter.design_bandpass(40, 60, sample_rate, num_taps)
print(f" Passband: 40-60 Hz")
print(f" Coefficients designed: {len(bp_coef)}\n")
print("FIR filter test complete!")
# Run test
test_fir_filter()
# Real-time filtering example (uncomment to use with sensor)
"""
# Initialize ADC for sensor
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
[Link](ADC.WIDTH_12BIT)
# Design filter
sample_rate = 100 # Hz
cutoff = 10 # Hz
coefficients = FIRFilter.design_lowpass(cutoff, sample_rate, num_taps=31)
fir_filter = FIRFilter(coefficients)
print("Real-time FIR Filtering Started")
print("Reading from ADC and filtering...")
try:
while True:
# Read sensor
raw_value = [Link]()
# Filter value
filtered_value = fir_filter.filter(raw_value)
print(f"Raw: {raw_value:4d} | Filtered: {filtered_value:7.2f}")
[Link](1.0 / sample_rate)
except KeyboardInterrupt:
print("\nFiltering stopped")
"""
5. IIR Digital Filter
Prompt: Create a MicroPython program implementing Infinite Impulse Response (IIR) digital
filters including Butterworth filters for efficient real-time signal processing with fewer coefficients
than FIR.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico / ESP8266
● Analog sensor (accelerometer, temperature, microphone, etc.)
● Optional: Potentiometer for cutoff frequency adjustment
● Connections: Sensor → GPIO34 (ADC)
Additional Details:
● More computationally efficient than FIR filters
● Implements Butterworth lowpass and highpass filters
● Uses bilinear transform for digital filter design
● Direct Form II structure for stability
● Exponential moving average for simple smoothing
MicroPython Code:
import math
import time
from machine import Pin, ADC
class IIRFilter:
"""Infinite Impulse Response (IIR) Digital Filter - Direct Form II"""
def __init__(self, b_coeffs, a_coeffs):
"""
Initialize IIR filter
b_coeffs: numerator coefficients [b0, b1, b2, ...]
a_coeffs: denominator coefficients [a0, a1, a2, ...]
H(z) = (b0 + b1*z^-1 + b2*z^-2 + ...) / (a0 + a1*z^-1 + a2*z^-2 + ...)
"""
# Normalize by a0
a0 = a_coeffs[0]
self.b = [b / a0 for b in b_coeffs]
self.a = [a / a0 for a in a_coeffs[1:]] # Skip a0 (now 1)
# State variables for Direct Form II
self.w = [0.0] * max(len(self.b), len(self.a) + 1)
def filter(self, sample):
"""
Process one sample through the filter
sample: input sample
Returns: filtered output
"""
# Calculate current state (feedback)
w0 = sample
for i in range(len(self.a)):
w0 -= self.a[i] * self.w[i]
# Calculate output (feedforward)
output = self.b[0] * w0
for i in range(1, len(self.b)):
if i <= len(self.w):
output += self.b[i] * self.w[i-1]
# Shift state variables
for i in range(len(self.w) - 1, 0, -1):
self.w[i] = self.w[i-1]
self.w[0] = w0
return output
def filter_signal(self, signal):
"""Filter entire signal array"""
return [[Link](s) for s in signal]
def reset(self):
"""Clear filter state"""
self.w = [0.0] * len(self.w)
@staticmethod
def butterworth_lowpass(cutoff_freq, sample_rate, order=2):
"""
Design Butterworth lowpass filter using bilinear transform
cutoff_freq: -3dB frequency in Hz
sample_rate: sampling rate in Hz
order: filter order (1 or 2)
Returns: (b_coeffs, a_coeffs)
"""
# Pre-warp frequency
omega = 2 * [Link] * cutoff_freq
T = 1.0 / sample_rate
omega_d = 2 / T * [Link](omega * T / 2)
if order == 1:
# First order: H(s) = 1 / (1 + s/ωc)
K = omega_d * T / 2
b = [K, K]
a = [1 + K, K - 1]
else: # order == 2
# Second order: H(s) = 1 / (1 + √2*s/ωc + (s/ωc)^2)
K = omega_d * T / 2
sqrt2 = [Link](2)
K2 = K * K
b = [K2, 2*K2, K2]
a = [1 + sqrt2*K + K2, 2*K2 - 2, 1 - sqrt2*K + K2]
return b, a
@staticmethod
def butterworth_highpass(cutoff_freq, sample_rate, order=2):
"""
Design Butterworth highpass filter
cutoff_freq: -3dB frequency in Hz
sample_rate: sampling rate in Hz
order: filter order (1 or 2)
Returns: (b_coeffs, a_coeffs)
"""
omega = 2 * [Link] * cutoff_freq
T = 1.0 / sample_rate
omega_d = 2 / T * [Link](omega * T / 2)
if order == 1:
K = omega_d * T / 2
b = [1, -1]
a = [1 + K, K - 1]
else: # order == 2
K = omega_d * T / 2
sqrt2 = [Link](2)
K2 = K * K
b = [1, -2, 1]
a = [1 + sqrt2*K + K2, 2*K2 - 2, 1 - sqrt2*K + K2]
return b, a
@staticmethod
def exponential_moving_average(alpha):
"""
Design exponential moving average (EMA) filter
alpha: smoothing factor (0 < alpha < 1)
Higher alpha = more responsive, lower alpha = smoother
H(z) = alpha / (1 - (1-alpha)*z^-1)
Returns: (b_coeffs, a_coeffs)
"""
b = [alpha]
a = [1, -(1 - alpha)]
return b, a
# Test IIR filter
def test_iir_filter():
print("=== IIR Digital Filter Test ===\n")
# Filter parameters
sample_rate = 1000 # Hz
cutoff = 50 # Hz
order = 2
print(f"Butterworth Lowpass Filter Design:")
print(f" Cutoff: {cutoff} Hz")
print(f" Sample rate: {sample_rate} Hz")
print(f" Order: {order}\n")
# Design 2nd order Butterworth lowpass
b, a = IIRFilter.butterworth_lowpass(cutoff, sample_rate, order=2)
iir = IIRFilter(b, a)
print(f"Filter Coefficients:")
print(f" B (numerator): {[f'{c:.6f}' for c in b]}")
print(f" A (denominator): {[f'{c:.6f}' for c in a]}\n")
# Generate test signal: 25 Hz (pass) + 150 Hz (reject)
print("Generating test signal:")
print(" 25 Hz sine wave (should pass)")
print(" 150 Hz sine wave (should be rejected)\n")
N = 500
signal = []
for i in range(N):
t = i / sample_rate
s = ([Link](2 * [Link] * 25 * t) +
0.5 * [Link](2 * [Link] * 150 * t))
[Link](s)
# Filter signal
filtered = iir.filter_signal(signal)
# Calculate energy
original_energy = sum(s**2 for s in signal) / N
filtered_energy = sum(s**2 for s in filtered) / N
print(f"Results:")
print(f" Original signal energy: {original_energy:.4f}")
print(f" Filtered signal energy: {filtered_energy:.4f}")
print(f" Energy reduction: {(1 - filtered_energy/original_energy)*100:.1f}%\n")
# Test highpass filter
print("Butterworth Highpass Filter Design:")
b_hp, a_hp = IIRFilter.butterworth_highpass(cutoff, sample_rate, order=2)
print(f" Cutoff: {cutoff} Hz")
print(f" B coefficients: {len(b_hp)}, A coefficients: {len(a_hp)}\n")
# Test EMA filter
print("Exponential Moving Average Filter Design:")
alpha = 0.1
b_ema, a_ema = IIRFilter.exponential_moving_average(alpha)
ema = IIRFilter(b_ema, a_ema)
print(f" Alpha (smoothing factor): {alpha}")
print(f" Lower alpha = smoother, Higher alpha = more responsive\n")
# Test EMA on noisy data
noisy_signal = [10 + (i % 3 - 1) * 2 for i in range(20)]
smoothed = ema.filter_signal(noisy_signal)
print("EMA Smoothing Example:")
print(f" Noisy: {noisy_signal[:10]}")
print(f" Smoothed: {['{:.2f}'.format(s) for s in smoothed[:10]]}")
print("\nIIR filter test complete!")
# Run test
test_iir_filter()
# Real-time filtering example (uncomment to use with sensor)
"""
# Initialize ADC
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
[Link](ADC.WIDTH_12BIT)
# Design filter (Butterworth 2nd order lowpass)
sample_rate = 100 # Hz
cutoff = 10 # Hz
b, a = IIRFilter.butterworth_lowpass(cutoff, sample_rate, order=2)
iir_filter = IIRFilter(b, a)
print("Real-time IIR Filtering Started")
print(f"Butterworth Lowpass: {cutoff} Hz cutoff\n")
try:
while True:
# Read sensor
raw_value = [Link]()
# Filter value
filtered_value = iir_filter.filter(raw_value)
print(f"Raw: {raw_value:4d} | Filtered: {filtered_value:7.2f}")
[Link](1.0 / sample_rate)
except KeyboardInterrupt:
print("\nFiltering stopped")
"""
6. PID Motor Speed Controller
Prompt: Create an ESP32 MicroPython program for precise DC motor speed control using PID
algorithm with rotary encoder feedback for robotics and automation applications.
Hardware Requirements:
● ESP32 Development Board
● DC Motor with Rotary Encoder (e.g., JGA25-370 with encoder)
● L298N Motor Driver Module (or TB6612FNG)
● 12V Power Supply for motor
● Connections:
○ Encoder A → GPIO18
○ Encoder B → GPIO19
○ Motor PWM → GPIO25
○ Motor DIR1 → GPIO26
○ Motor DIR2 → GPIO27
Additional Details:
● Uses quadrature encoder for speed measurement
● PID control for precise RPM control
● Bidirectional motor control
● Handles encoder interrupts for accurate counting
● Anti-windup and derivative filtering included
MicroPython Code:
import time
from machine import Pin, PWM
class Encoder:
"""Quadrature encoder reader for speed measurement"""
def __init__(self, pin_a, pin_b, ppr=20):
"""
Initialize encoder
pin_a, pin_b: encoder channel A and B pins
ppr: pulses per revolution (encoder resolution)
"""
self.pin_a = Pin(pin_a, [Link], Pin.PULL_UP)
self.pin_b = Pin(pin_b, [Link], Pin.PULL_UP)
[Link] = ppr
[Link] = 0
self.last_time = time.ticks_ms()
[Link] = 0
# Setup interrupt on channel A
self.pin_a.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING,
handler=self._encoder_callback)
def _encoder_callback(self, pin):
"""Encoder interrupt handler"""
# Determine direction based on channel B state
if self.pin_a.value() == self.pin_b.value():
[Link] += 1 # Forward
else:
[Link] -= 1 # Reverse
def get_rpm(self):
"""
Calculate RPM based on encoder counts
Call this periodically (e.g., every 100ms)
Returns: current RPM
"""
current_time = time.ticks_ms()
dt = time.ticks_diff(current_time, self.last_time) / 1000.0 # seconds
if dt > 0:
# RPM = (counts / ppr) * (60 / dt)
[Link] = ([Link] / [Link]) * (60.0 / dt)
[Link] = 0
self.last_time = current_time
return [Link]
def reset(self):
"""Reset encoder count"""
[Link] = 0
self.last_time = time.ticks_ms()
class MotorDriver:
"""DC Motor driver with PWM and direction control"""
def __init__(self, pwm_pin, dir_pin1, dir_pin2):
"""
Initialize motor driver
pwm_pin: PWM pin for speed control
dir_pin1, dir_pin2: direction control pins
"""
[Link] = PWM(Pin(pwm_pin))
[Link](1000) # 1 kHz PWM
self.dir1 = Pin(dir_pin1, [Link])
self.dir2 = Pin(dir_pin2, [Link])
[Link]()
def set_speed(self, speed):
"""
Set motor speed
speed: -100 to +100 (negative = reverse, positive = forward)
"""
# Determine direction
if speed > 0:
[Link](1)
[Link](0)
elif speed < 0:
[Link](0)
[Link](1)
speed = -speed
else:
[Link]()
return
# Set PWM duty cycle (0-1023)
duty = int(abs(speed) * 10.23)
duty = max(0, min(1023, duty))
[Link](duty)
def stop(self):
"""Stop motor (brake)"""
[Link](0)
[Link](0)
[Link](0)
def coast(self):
"""Coast motor (no brake)"""
[Link](0)
class PIDController:
"""PID Controller for motor speed control"""
def __init__(self, kp, ki, kd, setpoint=0, output_limits=(-100, 100)):
"""
Initialize PID controller
kp, ki, kd: PID gains
setpoint: target speed (RPM)
output_limits: (min, max) motor power percentage
"""
[Link] = kp
[Link] = ki
[Link] = kd
[Link] = setpoint
self.output_min, self.output_max = output_limits
[Link] = 0.0
self.prev_error = 0.0
self.prev_time = time.ticks_ms()
self.derivative_filtered = 0.0
self.derivative_filter_alpha = 0.1
def compute(self, measurement):
"""
Compute PID output
measurement: current speed (RPM)
Returns: motor power (-100 to +100)
"""
current_time = time.ticks_ms()
dt = time.ticks_diff(current_time, self.prev_time) / 1000.0
if dt <= 0:
return 0
# Calculate error
error = [Link] - measurement
# Proportional term
p_term = [Link] * error
# Integral term with anti-windup
[Link] += error * dt
i_term = [Link] * [Link]
# Derivative term with filtering
derivative = (error - self.prev_error) / dt
self.derivative_filtered = (self.derivative_filter_alpha * derivative +
(1 - self.derivative_filter_alpha) * self.derivative_filtered)
d_term = [Link] * self.derivative_filtered
# Calculate output
output = p_term + i_term + d_term
# Apply limits with anti-windup
if output > self.output_max:
output = self.output_max
[Link] -= error * dt
elif output < self.output_min:
output = self.output_min
[Link] -= error * dt
self.prev_error = error
self.prev_time = current_time
return output
def set_setpoint(self, setpoint):
"""Update target setpoint"""
[Link] = setpoint
def reset(self):
"""Reset controller state"""
[Link] = 0.0
self.prev_error = 0.0
self.derivative_filtered = 0.0
self.prev_time = time.ticks_ms()
class MotorSpeedController:
"""Motor speed control system using PID"""
def __init__(self, encoder_a, encoder_b, pwm_pin, dir_pin1, dir_pin2,
ppr=20, kp=0.5, ki=0.1, kd=0.05):
"""
Initialize motor speed controller
encoder_a, encoder_b: encoder pins
pwm_pin, dir_pin1, dir_pin2: motor driver pins
ppr: encoder pulses per revolution
kp, ki, kd: PID gains
"""
[Link] = Encoder(encoder_a, encoder_b, ppr)
[Link] = MotorDriver(pwm_pin, dir_pin1, dir_pin2)
[Link] = PIDController(kp, ki, kd, setpoint=0, output_limits=(-100, 100))
self.current_rpm = 0
[Link] = False
def set_speed(self, target_rpm):
"""Set target speed in RPM"""
[Link].set_setpoint(target_rpm)
print(f"Target speed set to: {target_rpm} RPM")
def update(self):
"""
Update controller (call periodically at ~10-20Hz)
Returns: (current_rpm, motor_power)
"""
# Measure current speed
self.current_rpm = [Link].get_rpm()
if not [Link]:
[Link]()
return self.current_rpm, 0
# Compute PID output
motor_power = [Link](self.current_rpm)
# Apply to motor
[Link].set_speed(motor_power)
return self.current_rpm, motor_power
def start(self):
"""Start speed control"""
[Link] = True
[Link]()
[Link]()
print("Motor speed control started")
def stop(self):
"""Stop speed control"""
[Link] = False
[Link]()
print("Motor speed control stopped")
def tune_pid(self, kp, ki, kd):
"""Update PID parameters"""
[Link] = kp
[Link] = ki
[Link] = kd
print(f"PID tuned: Kp={kp}, Ki={ki}, Kd={kd}")
# Main program
print("=== PID Motor Speed Controller ===\n")
# Initialize controller
# Encoder: A=GPIO18, B=GPIO19
# Motor: PWM=GPIO25, DIR1=GPIO26, DIR2=GPIO27
controller = MotorSpeedController(
encoder_a=18,
encoder_b=19,
pwm_pin=25,
dir_pin1=26,
dir_pin2=27,
ppr=20, # Pulses per revolution
kp=0.5, # Proportional gain
ki=0.1, # Integral gain
kd=0.05 # Derivative gain
)
# Set target speed
target_rpm = 100 # RPM
controller.set_speed(target_rpm)
# Start control
[Link]()
print(f"Target: {target_rpm} RPM")
print(f"PID Gains: Kp={[Link]}, Ki={[Link]}, Kd={[Link]}")
print("\nTime(s) | RPM | Power(%) | Error(RPM)")
print("-" * 50)
try:
start_time = [Link]()
while True:
# Update controller
rpm, power = [Link]()
# Calculate error
error = target_rpm - rpm
# Display status
elapsed = [Link]() - start_time
print(f"{elapsed:7.1f} | {rpm:4.0f} | {power:8.1f} | {error:10.1f}")
# Wait for next update (100ms = 10Hz)
[Link](0.1)
except KeyboardInterrupt:
print("\n\nStopping motor controller...")
[Link]()
print("Controller stopped.")
7. Kalman Filter (Sensor Fusion)
Prompt: Create a MicroPython program implementing Kalman Filter for optimal sensor fusion,
combining noisy measurements from multiple sensors (accelerometer, gyroscope, GPS) to
estimate true system state.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● MPU6050 (Accelerometer + Gyroscope) / IMU sensor
● Optional: GPS module, Temperature sensor
● Optional: OLED display for visualization
Connections:
● MPU6050 → I2C (SCL: GPIO22, SDA: GPIO21)
● GPS → UART (TX: GPIO16, RX: GPIO17)
Additional Details:
● Optimal state estimation with uncertainty quantification
● Recursive filter for real-time processing
● Prediction and update steps (measurement correction)
● Sensor fusion for position, velocity, or orientation
● Handles measurement noise and process uncertainty
MicroPython Code:
import math
import time
from machine import Pin, I2C
class KalmanFilter:
"""1D Kalman Filter for optimal state estimation"""
def __init__(self, process_variance, measurement_variance,
initial_value=0.0, initial_estimate_error=1.0):
"""
Initialize Kalman Filter
process_variance (Q): uncertainty in the process/model
measurement_variance (R): uncertainty in measurements
initial_value: initial state estimate
initial_estimate_error (P): initial estimation error
"""
self.q = process_variance # Process noise covariance
self.r = measurement_variance # Measurement noise covariance
self.x = initial_value # State estimate
self.p = initial_estimate_error # Estimation error covariance
def update(self, measurement):
"""
Update filter with new measurement
Prediction step:
x_pred = x (assuming constant model)
p_pred = p + q
Update step:
K = p_pred / (p_pred + r) # Kalman gain
x = x_pred + K * (z - x_pred)
p = (1 - K) * p_pred
"""
# Prediction
x_pred = self.x
p_pred = self.p + self.q
# Update with measurement
kalman_gain = p_pred / (p_pred + self.r)
self.x = x_pred + kalman_gain * (measurement - x_pred)
self.p = (1 - kalman_gain) * p_pred
return self.x
def update_with_control(self, measurement, control_input, control_matrix=1.0):
"""Update with control input (e.g., known acceleration)"""
# Prediction with control
x_pred = self.x + control_matrix * control_input
p_pred = self.p + self.q
# Update
kalman_gain = p_pred / (p_pred + self.r)
self.x = x_pred + kalman_gain * (measurement - x_pred)
self.p = (1 - kalman_gain) * p_pred
return self.x
def get_state(self):
"""Return current state estimate"""
return self.x
def get_uncertainty(self):
"""Return current estimation uncertainty"""
return self.p
class KalmanFilter2D:
"""2D Kalman Filter for position and velocity tracking"""
def __init__(self, dt, process_variance, measurement_variance):
"""
Initialize 2D Kalman Filter for constant velocity model
dt: time step
State: [position, velocity]
"""
[Link] = dt
# State transition matrix (constant velocity model)
self.F = [[1, dt],
[0, 1]]
# Measurement matrix (we measure position only)
self.H = [[1, 0]]
# Process noise covariance
self.Q = [[process_variance * dt**4 / 4, process_variance * dt**3 / 2],
[process_variance * dt**3 / 2, process_variance * dt**2]]
# Measurement noise covariance
self.R = [[measurement_variance]]
# State estimate [position, velocity]
self.x = [[0.0], [0.0]]
# Estimation error covariance
self.P = [[1.0, 0.0],
[0.0, 1.0]]
def predict(self):
"""Prediction step"""
# x_pred = F * x
x_new = [[0.0], [0.0]]
for i in range(2):
for j in range(2):
x_new[i][0] += self.F[i][j] * self.x[j][0]
self.x = x_new
# P_pred = F * P * F^T + Q
FP = [[0.0, 0.0], [0.0, 0.0]]
for i in range(2):
for j in range(2):
for k in range(2):
FP[i][j] += self.F[i][k] * self.P[k][j]
P_new = [[0.0, 0.0], [0.0, 0.0]]
for i in range(2):
for j in range(2):
for k in range(2):
P_new[i][j] += FP[i][k] * self.F[j][k]
P_new[i][j] += self.Q[i][j]
self.P = P_new
def update(self, measurement):
"""Update step with measurement"""
# Innovation: y = z - H * x
Hx = self.H[0][0] * self.x[0][0] + self.H[0][1] * self.x[1][0]
y = measurement - Hx
# Innovation covariance: S = H * P * H^T + R
HP = [0.0, 0.0]
for j in range(2):
HP[j] = self.H[0][0] * self.P[0][j] + self.H[0][1] * self.P[1][j]
S = HP[0] * self.H[0][0] + HP[1] * self.H[0][1] + self.R[0][0]
# Kalman gain: K = P * H^T * S^-1
K = [[0.0], [0.0]]
for i in range(2):
K[i][0] = (self.P[i][0] * self.H[0][0] + self.P[i][1] * self.H[0][1]) / S
# Update state: x = x + K * y
for i in range(2):
self.x[i][0] += K[i][0] * y
# Update covariance: P = (I - K * H) * P
KH = [[K[0][0] * self.H[0][0], K[0][0] * self.H[0][1]],
[K[1][0] * self.H[0][0], K[1][0] * self.H[0][1]]]
P_new = [[0.0, 0.0], [0.0, 0.0]]
for i in range(2):
for j in range(2):
I_KH = (1.0 if i == j else 0.0) - KH[i][j]
for k in range(2):
P_new[i][j] += I_KH * self.P[k][j] if k == i else KH[i][k] * self.P[k][j]
self.P = P_new
def get_position(self):
"""Return estimated position"""
return self.x[0][0]
def get_velocity(self):
"""Return estimated velocity"""
return self.x[1][0]
# Test Kalman Filter
def test_kalman_filter():
print("=== Kalman Filter Test ===\n")
# Simulate noisy sensor measuring constant value
print("Test 1: Constant Value Estimation")
print("True value: 100.0")
print("Measurement noise: ±10.0\n")
true_value = 100.0
kf = KalmanFilter(
process_variance=0.01, # Low process noise (nearly constant)
measurement_variance=100.0, # High measurement noise
initial_value=0.0
)
print("Sample | Measurement | Kalman Est | Error")
print("-------|-------------|------------|-------")
for i in range(15):
# Simulate noisy measurement
import random
noise = ([Link]() - 0.5) * 20 # ±10 noise
measurement = true_value + noise
# Update Kalman filter
estimate = [Link](measurement)
error = abs(estimate - true_value)
print(f" {i+1:2d} | {measurement:6.2f} | {estimate:6.2f} | {error:5.2f}")
print(f"\nFinal estimate: {kf.get_state():.2f}")
print(f"Uncertainty: {kf.get_uncertainty():.4f}\n")
# Test 2D Kalman Filter
print("\nTest 2: 2D Position/Velocity Tracking")
print("Simulating object moving at constant velocity\n")
dt = 0.1 # 100ms time step
true_velocity = 5.0 # 5 units/sec
kf2d = KalmanFilter2D(
dt=dt,
process_variance=0.1,
measurement_variance=4.0
)
print("Time | True Pos | Meas Pos | Est Pos | Est Vel")
print("------|----------|----------|---------|--------")
for i in range(20):
t = i * dt
true_position = true_velocity * t
# Noisy measurement
noise = ([Link]() - 0.5) * 4
measurement = true_position + noise
# Kalman predict and update
[Link]()
[Link](measurement)
est_pos = kf2d.get_position()
est_vel = kf2d.get_velocity()
print(f"{t:5.2f} | {true_position:8.2f} | {measurement:8.2f} | {est_pos:7.2f} | {est_vel:7.2f}")
print("\nKalman filter converged to true velocity!")
print("Notice how estimates are smoother than measurements\n")
# Run test
test_kalman_filter()
# Real-time sensor fusion example (uncomment to use with MPU6050)
"""
# Initialize I2C for MPU6050
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
# Simple MPU6050 reading function
def read_accel_z():
# Read Z-axis acceleration (example)
data = i2c.readfrom_mem(0x68, 0x3F, 2)
return (data[0] << 8 | data[1]) / 16384.0 # Convert to g's
# Initialize Kalman filter for Z-axis acceleration
kf_accel = KalmanFilter(
process_variance=0.001,
measurement_variance=0.1,
initial_value=0.0
)
print("Real-time Kalman Filtering Started")
print("Filtering accelerometer Z-axis\n")
try:
while True:
# Read noisy sensor
raw_accel = read_accel_z()
# Apply Kalman filter
filtered_accel = kf_accel.update(raw_accel)
print(f"Raw: {raw_accel:6.3f} g | Filtered: {filtered_accel:6.3f} g | Uncertainty:
{kf_accel.get_uncertainty():.6f}")
[Link](0.1)
except KeyboardInterrupt:
print("\nFiltering stopped")
"""
8. State Space Control System
Prompt: Create a MicroPython program implementing State Space control system for
multivariable system control using state feedback, observer design, and optimal control (LQR).
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● DC motors with encoders (2x)
● Motor driver (L298N / TB6612FNG)
● Power supply (7-12V for motors)
Connections:
● Motor 1: IN1→GPIO25, IN2→GPIO26, ENA→GPIO27 (PWM)
● Motor 2: IN3→GPIO32, IN4→GPIO33, ENB→GPIO14 (PWM)
● Encoder 1: GPIO18, GPIO19
● Encoder 2: GPIO21, GPIO22
Additional Details:
● Modern control theory implementation
● State space representation: ẋ = Ax + Bu, y = Cx
● State feedback controller: u = -Kx
● Full-state observer for unmeasured states
● Discrete-time implementation for microcontrollers
MicroPython Code:
import math
import time
from machine import Pin, PWM
class StateSpaceSystem:
"""Discrete-time State Space System"""
def __init__(self, A, B, C, D=None, dt=0.01):
"""
Initialize state space system
ẋ = Ax + Bu (continuous)
x[k+1] = Ad*x[k] + Bd*u[k] (discrete)
y = Cx + Du
A: state matrix (n×n)
B: input matrix (n×m)
C: output matrix (p×n)
D: feedthrough matrix (p×m)
dt: sampling time
"""
self.A = A
self.B = B
self.C = C
self.D = D if D else [[0.0] * len(B[0]) for _ in range(len(C))]
[Link] = dt
# Number of states, inputs, outputs
self.n = len(A)
self.m = len(B[0])
self.p = len(C)
# State vector
self.x = [[0.0] for _ in range(self.n)]
def matrix_mult(self, A, B):
"""Multiply two matrices"""
rows_A, cols_A = len(A), len(A[0])
rows_B, cols_B = len(B), len(B[0])
result = [[0.0] * cols_B for _ in range(rows_A)]
for i in range(rows_A):
for j in range(cols_B):
for k in range(cols_A):
result[i][j] += A[i][k] * B[k][j]
return result
def matrix_add(self, A, B):
"""Add two matrices"""
return [[A[i][j] + B[i][j] for j in range(len(A[0]))] for i in range(len(A))]
def update(self, u):
"""
Update system state (discrete time step)
x[k+1] = Ad*x[k] + Bd*u[k]
Using forward Euler: Ad ≈ I + A*dt, Bd ≈ B*dt
"""
# Compute A*x
Ax = self.matrix_mult(self.A, self.x)
# Compute B*u (u should be column vector)
u_vec = [[ui] for ui in u] if isinstance(u[0], (int, float)) else u
Bu = self.matrix_mult(self.B, u_vec)
# x_new = x + (Ax + Bu)*dt
for i in range(self.n):
self.x[i][0] += (Ax[i][0] + Bu[i][0]) * [Link]
def output(self):
"""Compute system output: y = C*x"""
y = self.matrix_mult(self.C, self.x)
return [y[i][0] for i in range(self.p)]
def set_state(self, x):
"""Set system state"""
self.x = [[xi] for xi in x]
def get_state(self):
"""Get system state"""
return [self.x[i][0] for i in range(self.n)]
class StateFeedbackController:
"""State feedback controller: u = -K*x + r"""
def __init__(self, K, reference=None):
"""
Initialize state feedback controller
K: feedback gain matrix (m×n)
reference: reference input (optional)
"""
self.K = K
self.m = len(K)
self.n = len(K[0])
[Link] = reference if reference else [0.0] * self.m
def compute_control(self, x):
"""
Compute control input: u = -K*x + r
x: state vector
"""
u = []
for i in range(self.m):
ui = [Link][i]
for j in range(self.n):
ui -= self.K[i][j] * x[j]
[Link](ui)
return u
def set_reference(self, reference):
"""Set reference input"""
[Link] = reference
class StateObserver:
"""Luenberger observer for state estimation"""
def __init__(self, A, B, C, L, dt=0.01):
"""
Initialize state observer
ẋ_hat = A*x_hat + B*u + L*(y - C*x_hat)
A, B, C: system matrices
L: observer gain matrix (n×p)
dt: sampling time
"""
self.A = A
self.B = B
self.C = C
self.L = L
[Link] = dt
self.n = len(A)
self.m = len(B[0])
self.p = len(C)
# Estimated state
self.x_hat = [[0.0] for _ in range(self.n)]
[Link] = StateSpaceSystem(A, B, C, dt=dt)
def update(self, u, y):
"""
Update observer with measurement
u: control input
y: measured output
"""
# Compute C*x_hat (predicted output)
y_hat = [Link].matrix_mult(self.C, self.x_hat)
# Output error: e = y - y_hat
e = [[y[i] - y_hat[i][0]] for i in range(self.p)]
# Correction term: L*e
Le = [Link].matrix_mult(self.L, e)
# Compute A*x_hat
Ax = [Link].matrix_mult(self.A, self.x_hat)
# Compute B*u
u_vec = [[ui] for ui in u]
Bu = [Link].matrix_mult(self.B, u_vec)
# Update: x_hat = x_hat + (A*x_hat + B*u + L*e)*dt
for i in range(self.n):
self.x_hat[i][0] += (Ax[i][0] + Bu[i][0] + Le[i][0]) * [Link]
def get_state_estimate(self):
"""Return estimated state"""
return [self.x_hat[i][0] for i in range(self.n)]
# Test State Space Control
def test_state_space_control():
print("=== State Space Control System Test ===\n")
# Simple 2nd order system (mass-spring-damper)
# ẍ + 2*ζ*ω*ẋ + ω²*x = u
# State: [position, velocity]
print("System: Mass-Spring-Damper")
print("States: [position, velocity]")
print("Control: force input\n")
omega = 2.0 # Natural frequency
zeta = 0.1 # Damping ratio (underdamped)
dt = 0.01 # 10ms sample time
# State space matrices
A = [[0.0, 1.0],
[-omega**2, -2*zeta*omega]]
B = [[0.0],
[1.0]]
C = [[1.0, 0.0]] # Measure position only
print("System Matrices:")
print(f"A = {A}")
print(f"B = {B}")
print(f"C = {C}\n")
# Create system
system = StateSpaceSystem(A, B, C, dt=dt)
system.set_state([1.0, 0.0]) # Initial position = 1.0
# State feedback controller (pole placement)
# Desired closed-loop poles: faster and more damped
K = [[4.0, 1.5]] # Tuned gains
controller = StateFeedbackController(K, reference=[0.0])
print("Controller: u = -K*x")
print(f"K = {K}\n")
# Create observer (faster than system)
L = [[4.0],
[6.0]]
observer = StateObserver(A, B, C, L, dt=dt)
print("Observer gains:")
print(f"L = {L}\n")
# Simulation
print("Time | Position | Velocity | Control | Est Pos | Est Vel")
print("------|----------|----------|---------|---------|--------")
for i in range(100):
t = i * dt
# Get measurement (position only)
y = [Link]()
# Observer estimates full state
x_est = observer.get_state_estimate()
# Controller uses estimated state
u = controller.compute_control(x_est)
# Update observer
[Link](u, y)
# Update system
[Link](u)
# Get true state
x = system.get_state()
if i % 10 == 0:
print(f"{t:5.2f} | {x[0]:8.4f} | {x[1]:8.4f} | {u[0]:7.4f} | {x_est[0]:7.4f} | {x_est[1]:7.4f}")
print("\nSystem stabilized at origin!")
print("Observer successfully estimated velocity from position measurements\n")
# Run test
test_state_space_control()
# Real-time motor control example (uncomment to use with motors)
"""
# Motor control class
class DCMotor:
def __init__(self, in1_pin, in2_pin, en_pin, enc_a_pin, enc_b_pin):
self.in1 = Pin(in1_pin, [Link])
self.in2 = Pin(in2_pin, [Link])
[Link] = PWM(Pin(en_pin), freq=1000)
# Encoder
self.enc_a = Pin(enc_a_pin, [Link])
self.enc_b = Pin(enc_b_pin, [Link])
[Link] = 0
[Link] = 0
# Setup encoder interrupt
self.enc_a.irq(trigger=Pin.IRQ_RISING, handler=self._encoder_callback)
def _encoder_callback(self, pin):
if self.enc_b.value():
[Link] += 1
else:
[Link] -= 1
def set_speed(self, speed):
# speed: -1.0 to 1.0
if speed >= 0:
[Link]()
[Link]()
[Link](int(abs(speed) * 1023))
else:
[Link]()
[Link]()
[Link](int(abs(speed) * 1023))
def get_state(self):
return [[Link], [Link]]
# Initialize motor
motor = DCMotor(25, 26, 27, 18, 19)
# State space model for DC motor
# States: [angle, angular_velocity]
A_motor = [[0.0, 1.0],
[0.0, -10.0]] # Motor damping
B_motor = [[0.0],
[50.0]] # Motor constant
C_motor = [[1.0, 0.0]]
# Create controller
system = StateSpaceSystem(A_motor, B_motor, C_motor, dt=0.01)
K_motor = [[2.0, 0.5]]
controller = StateFeedbackController(K_motor, reference=[100.0]) # Target angle
print("State space motor control started")
try:
while True:
# Get motor state
x = motor.get_state()
# Compute control
u = controller.compute_control(x)
# Apply control (saturate to ±1.0)
u_sat = max(-1.0, min(1.0, u[0]))
motor.set_speed(u_sat)
print(f"Angle: {x[0]:6.1f} | Vel: {x[1]:6.2f} | Control: {u_sat:5.2f}")
[Link](0.01)
except KeyboardInterrupt:
motor.set_speed(0)
print("\nControl stopped")
"""
9. Time Series Analysis
Prompt: Create a MicroPython program implementing Time Series Analysis for trend detection,
seasonality decomposition, forecasting (ARIMA-like), and real-time anomaly detection in sensor
data streams.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● Any analog sensor (temperature, humidity, light, etc.)
● Optional: SD card module for data logging
● Optional: RTC module for timestamps
Connections:
● Sensor → GPIO34 (ADC)
● SD Card → SPI (optional)
Additional Details:
● Moving averages and exponential smoothing
● Trend and seasonality decomposition
● Auto-regressive models for prediction
● Statistical analysis (mean, variance, autocorrelation)
● Real-time streaming analytics
MicroPython Code:
import math
import time
from machine import Pin, ADC
class TimeSeriesAnalyzer:
"""Time Series Analysis and Forecasting"""
def __init__(self, max_length=1000):
"""Initialize time series analyzer"""
[Link] = []
self.max_length = max_length
def add_point(self, value):
"""Add data point to series"""
[Link](value)
if len([Link]) > self.max_length:
[Link](0)
def get_series(self):
"""Return time series data"""
return [Link]()
def clear(self):
"""Clear all data"""
[Link] = []
# Statistical measures
def mean(self, data=None):
"""Calculate mean"""
d = data if data else [Link]
return sum(d) / len(d) if d else 0.0
def variance(self, data=None):
"""Calculate variance"""
d = data if data else [Link]
if not d:
return 0.0
m = [Link](d)
return sum((x - m) ** 2 for x in d) / len(d)
def std_dev(self, data=None):
"""Calculate standard deviation"""
return [Link]([Link](data))
def autocorrelation(self, lag):
"""
Calculate autocorrelation at given lag
r(k) = Σ[(x_t - μ)(x_{t-k} - μ)] / Σ[(x_t - μ)²]
"""
if len([Link]) <= lag:
return 0.0
m = [Link]()
numerator = 0.0
denominator = 0.0
for i in range(lag, len([Link])):
numerator += ([Link][i] - m) * ([Link][i - lag] - m)
for x in [Link]:
denominator += (x - m) ** 2
return numerator / denominator if denominator != 0 else 0.0
# Smoothing methods
def simple_moving_average(self, window):
"""Simple Moving Average (SMA)"""
if len([Link]) < window:
return [Link]()
sma = []
for i in range(len([Link])):
if i < window - 1:
[Link]([Link]([Link][:i+1]))
else:
[Link]([Link]([Link][i-window+1:i+1]))
return sma
def exponential_smoothing(self, alpha):
"""
Exponential Smoothing
S_t = α*x_t + (1-α)*S_{t-1}
alpha: smoothing factor (0 < alpha < 1)
"""
if not [Link]:
return []
smoothed = [[Link][0]]
for i in range(1, len([Link])):
s = alpha * [Link][i] + (1 - alpha) * smoothed[-1]
[Link](s)
return smoothed
def double_exponential_smoothing(self, alpha, beta):
"""
Double Exponential Smoothing (Holt's method)
Handles trend
alpha: level smoothing
beta: trend smoothing
"""
if len([Link]) < 2:
return [Link]()
# Initialize
level = [Link][0]
trend = [Link][1] - [Link][0]
smoothed = [[Link][0]]
for i in range(1, len([Link])):
last_level = level
level = alpha * [Link][i] + (1 - alpha) * (level + trend)
trend = beta * (level - last_level) + (1 - beta) * trend
[Link](level)
return smoothed
def forecast_next(self, method='sma', window=5, alpha=0.3):
"""
Forecast next value
method: 'sma' or 'ema'
"""
if not [Link]:
return 0.0
if method == 'sma':
w = min(window, len([Link]))
return [Link]([Link][-w:])
elif method == 'ema':
smoothed = self.exponential_smoothing(alpha)
return smoothed[-1]
else:
return [Link][-1]
# Trend detection
def detect_trend(self, window=10):
"""
Detect trend direction using linear regression
Returns: 'increasing', 'decreasing', or 'stable'
"""
if len([Link]) < window:
return 'insufficient_data'
# Use last 'window' points
recent = [Link][-window:]
n = len(recent)
# Linear regression: y = a + b*x
x_mean = (n - 1) / 2
y_mean = sum(recent) / n
numerator = sum((i - x_mean) * (recent[i] - y_mean) for i in range(n))
denominator = sum((i - x_mean) ** 2 for i in range(n))
if denominator == 0:
return 'stable'
slope = numerator / denominator
# Threshold for trend detection
threshold = self.std_dev(recent) * 0.1
if slope > threshold:
return 'increasing'
elif slope < -threshold:
return 'decreasing'
else:
return 'stable'
# Seasonality decomposition (simplified)
def decompose_additive(self, period):
"""
Additive decomposition: Y = T + S + R
T: trend, S: seasonal, R: residual
"""
if len([Link]) < period * 2:
return None, None, None
# 1. Calculate trend using centered moving average
trend = []
for i in range(len([Link])):
if i < period // 2 or i >= len([Link]) - period // 2:
[Link](None)
else:
start = i - period // 2
end = i + period // 2 + 1
[Link]([Link]([Link][start:end]))
# 2. Detrend to get seasonal + residual
detrended = []
for i in range(len([Link])):
if trend[i] is not None:
[Link]([Link][i] - trend[i])
else:
[Link](None)
# 3. Calculate seasonal component
seasonal = [0.0] * len([Link])
for i in range(period):
# Average all values at this phase
values = [detrended[j] for j in range(i, len(detrended), period)
if detrended[j] is not None]
if values:
avg = sum(values) / len(values)
for j in range(i, len(seasonal), period):
seasonal[j] = avg
# 4. Calculate residual
residual = []
for i in range(len([Link])):
if trend[i] is not None:
[Link]([Link][i] - trend[i] - seasonal[i])
else:
[Link](None)
return trend, seasonal, residual
class AnomalyDetector:
"""Real-time anomaly detection"""
def __init__(self, window=50, threshold=3.0):
"""
Initialize anomaly detector
window: lookback window for statistics
threshold: number of standard deviations for anomaly
"""
[Link] = window
[Link] = threshold
[Link] = []
def add_point(self, value):
"""Add point and return if it's anomalous"""
[Link](value)
if len([Link]) > [Link]:
[Link](0)
if len([Link]) < 10: # Need minimum data
return False, 0.0
# Calculate mean and std dev
mean = sum([Link]) / len([Link])
variance = sum((x - mean) ** 2 for x in [Link]) / len([Link])
std_dev = [Link](variance)
if std_dev == 0:
return False, 0.0
# Z-score
z_score = abs(value - mean) / std_dev
is_anomaly = z_score > [Link]
return is_anomaly, z_score
def reset(self):
"""Clear buffer"""
[Link] = []
# Test Time Series Analysis
def test_time_series():
print("=== Time Series Analysis Test ===\n")
# Generate synthetic data with trend, seasonality, and noise
print("Generating synthetic time series:")
print(" - Linear trend")
print(" - Seasonal pattern (period=10)")
print(" - Random noise\n")
ts = TimeSeriesAnalyzer(max_length=100)
for i in range(100):
# Trend: linear increase
trend = 0.5 * i
# Seasonality: sine wave
seasonal = 10 * [Link](2 * [Link] * i / 10)
# Noise
import random
noise = ([Link]() - 0.5) * 2
value = trend + seasonal + noise
ts.add_point(value)
data = ts.get_series()
# Statistics
print("Statistical Summary:")
print(f" Mean: {[Link]():.2f}")
print(f" Std Dev: {ts.std_dev():.2f}")
print(f" Variance: {[Link]():.2f}\n")
# Autocorrelation
print("Autocorrelation:")
for lag in [1, 5, 10]:
acf = [Link](lag)
print(f" Lag {lag}: {acf:.3f}")
print()
# Smoothing
print("Smoothing Methods:")
sma = ts.simple_moving_average(5)
ema = ts.exponential_smoothing(0.3)
print(f" Original (last 5): {[f'{x:.1f}' for x in data[-5:]]}")
print(f" SMA(5) (last 5): {[f'{x:.1f}' for x in sma[-5:]]}")
print(f" EMA(0.3) (last 5): {[f'{x:.1f}' for x in ema[-5:]]}\n")
# Trend detection
trend_direction = ts.detect_trend(window=20)
print(f"Trend Detection (last 20 points): {trend_direction}\n")
# Forecasting
forecast_sma = ts.forecast_next('sma', window=10)
forecast_ema = ts.forecast_next('ema', alpha=0.3)
print("Forecasting:")
print(f" Current value: {data[-1]:.2f}")
print(f" Forecast (SMA): {forecast_sma:.2f}")
print(f" Forecast (EMA): {forecast_ema:.2f}\n")
# Decomposition
print("Seasonal Decomposition (period=10):")
trend_comp, seasonal_comp, residual_comp = ts.decompose_additive(10)
# Show last 10 points
print("Index | Original | Trend | Seasonal | Residual")
print("------|----------|---------|----------|----------")
for i in range(-10, 0):
orig = data[i]
tr = trend_comp[i] if trend_comp[i] is not None else 0.0
seas = seasonal_comp[i]
res = residual_comp[i] if residual_comp[i] is not None else 0.0
print(f" {100+i:3d} | {orig:8.2f} | {tr:7.2f} | {seas:8.2f} | {res:8.2f}")
print("\n")
# Anomaly detection
print("Anomaly Detection Test:")
detector = AnomalyDetector(window=20, threshold=2.5)
# Add normal data
for i in range(30):
value = 50 + ([Link]() - 0.5) * 10
is_anom, z = detector.add_point(value)
# Add anomaly
print("\nInjecting anomalies...")
test_values = [52, 54, 120, 51, 53, -30, 50]
for val in test_values:
is_anom, z_score = detector.add_point(val)
status = "ANOMALY!" if is_anom else "Normal"
print(f" Value: {val:6.1f} | Z-score: {z_score:5.2f} | {status}")
print("\nTime series analysis complete!")
# Run test
test_time_series()
# Real-time sensor monitoring (uncomment to use)
"""
# Initialize ADC
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
[Link](ADC.WIDTH_12BIT)
# Create analyzer and anomaly detector
ts = TimeSeriesAnalyzer(max_length=500)
anomaly_detector = AnomalyDetector(window=30, threshold=3.0)
print("Real-time Time Series Monitoring Started")
print("Collecting sensor data...\n")
sample_count = 0
try:
while True:
# Read sensor
raw_value = [Link]()
# Add to time series
ts.add_point(raw_value)
sample_count += 1
# Check for anomaly
is_anomaly, z_score = anomaly_detector.add_point(raw_value)
# Every 10 samples, show analysis
if sample_count % 10 == 0:
trend = ts.detect_trend(window=20)
forecast = ts.forecast_next('ema', alpha=0.2)
print(f"Samples: {sample_count}")
print(f" Current: {raw_value:4d} | Mean: {[Link]():6.1f} | StdDev: {ts.std_dev():5.1f}")
print(f" Trend: {trend} | Forecast: {forecast:.1f}")
if is_anomaly:
print(f" *** ANOMALY DETECTED! Z-score: {z_score:.2f} ***")
print()
[Link](0.1)
except KeyboardInterrupt:
print("\nMonitoring stopped")
print(f"Total samples collected: {len(ts.get_series())}")
"""
10. Statistical Anomaly Detection
Prompt: Create a MicroPython program implementing Statistical Anomaly Detection using
multiple methods including Z-score, Modified Z-score, IQR, and Isolation Forest-like algorithms
for real-time outlier detection.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● Any sensors (temperature, pressure, current, vibration)
● Optional: LED indicators for anomaly alerts
● Optional: Buzzer for alarms
Connections:
● Sensor → GPIO34 (ADC)
● Alert LED → GPIO2
● Buzzer → GPIO4
Additional Details:
● Multiple detection algorithms for robust detection
● Online learning for adaptive thresholds
● Statistical methods and distance-based detection
● Configurable sensitivity and window sizes
● Real-time alert system
MicroPython Code:
import math
import time
from machine import Pin, ADC
class ZScoreDetector:
"""Standard Z-score anomaly detection"""
def __init__(self, threshold=3.0, window=100):
"""
threshold: number of standard deviations
window: rolling window size
"""
[Link] = threshold
[Link] = window
[Link] = []
def add_sample(self, value):
"""Add sample and detect anomaly"""
[Link](value)
if len([Link]) > [Link]:
[Link](0)
if len([Link]) < 5:
return False, 0.0, None
mean = sum([Link]) / len([Link])
variance = sum((x - mean) ** 2 for x in [Link]) / len([Link])
std_dev = [Link](variance)
if std_dev == 0:
return False, 0.0, {'mean': mean, 'std': std_dev}
z_score = (value - mean) / std_dev
is_anomaly = abs(z_score) > [Link]
stats = {'mean': mean, 'std': std_dev, 'z_score': z_score}
return is_anomaly, abs(z_score), stats
class ModifiedZScoreDetector:
"""Modified Z-score using Median Absolute Deviation (MAD)"""
def __init__(self, threshold=3.5, window=100):
"""
threshold: modified z-score threshold
window: rolling window size
"""
[Link] = threshold
[Link] = window
[Link] = []
def median(self, data):
"""Calculate median"""
sorted_data = sorted(data)
n = len(sorted_data)
if n % 2 == 0:
return (sorted_data[n//2 - 1] + sorted_data[n//2]) / 2
else:
return sorted_data[n//2]
def mad(self, data, median_val):
"""Median Absolute Deviation"""
deviations = [abs(x - median_val) for x in data]
return [Link](deviations)
def add_sample(self, value):
"""Add sample and detect anomaly"""
[Link](value)
if len([Link]) > [Link]:
[Link](0)
if len([Link]) < 5:
return False, 0.0, None
median_val = [Link]([Link])
mad_val = [Link]([Link], median_val)
if mad_val == 0:
return False, 0.0, {'median': median_val, 'mad': mad_val}
# Modified Z-score: 0.6745 * (x - median) / MAD
modified_z = 0.6745 * (value - median_val) / mad_val
is_anomaly = abs(modified_z) > [Link]
stats = {'median': median_val, 'mad': mad_val, 'modified_z': modified_z}
return is_anomaly, abs(modified_z), stats
class IQRDetector:
"""Interquartile Range (IQR) anomaly detection"""
def __init__(self, iqr_multiplier=1.5, window=100):
"""
iqr_multiplier: multiplier for IQR (typical: 1.5 for outliers, 3.0 for extreme)
window: rolling window size
"""
self.iqr_multiplier = iqr_multiplier
[Link] = window
[Link] = []
def percentile(self, data, p):
"""Calculate percentile"""
sorted_data = sorted(data)
n = len(sorted_data)
k = (n - 1) * p
f = [Link](k)
c = [Link](k)
if f == c:
return sorted_data[int(k)]
d0 = sorted_data[int(f)] * (c - k)
d1 = sorted_data[int(c)] * (k - f)
return d0 + d1
def add_sample(self, value):
"""Add sample and detect anomaly"""
[Link](value)
if len([Link]) > [Link]:
[Link](0)
if len([Link]) < 5:
return False, 0.0, None
q1 = [Link]([Link], 0.25)
q3 = [Link]([Link], 0.75)
iqr = q3 - q1
lower_bound = q1 - self.iqr_multiplier * iqr
upper_bound = q3 + self.iqr_multiplier * iqr
is_anomaly = value < lower_bound or value > upper_bound
# Distance from bounds
if value < lower_bound:
distance = abs(value - lower_bound) / iqr if iqr > 0 else 0
elif value > upper_bound:
distance = abs(value - upper_bound) / iqr if iqr > 0 else 0
else:
distance = 0.0
stats = {
'q1': q1, 'q3': q3, 'iqr': iqr,
'lower': lower_bound, 'upper': upper_bound
}
return is_anomaly, distance, stats
class EWMADetector:
"""Exponentially Weighted Moving Average anomaly detection"""
def __init__(self, alpha=0.2, threshold=3.0):
"""
alpha: smoothing factor (0 < alpha < 1)
threshold: number of standard deviations
"""
[Link] = alpha
[Link] = threshold
[Link] = None
self.ewma_std = None
[Link] = False
def add_sample(self, value):
"""Add sample and detect anomaly"""
if not [Link]:
[Link] = value
self.ewma_std = 0.0
[Link] = True
return False, 0.0, {'ewma': [Link], 'std': self.ewma_std}
# Update EWMA
prediction = [Link]
error = abs(value - prediction)
[Link] = [Link] * value + (1 - [Link]) * [Link]
# Update EWMA of standard deviation
self.ewma_std = [Link] * error + (1 - [Link]) * self.ewma_std
if self.ewma_std == 0:
return False, 0.0, {'ewma': [Link], 'std': self.ewma_std}
# Detect anomaly
z_score = error / self.ewma_std
is_anomaly = z_score > [Link]
stats = {'ewma': [Link], 'std': self.ewma_std, 'error': error}
return is_anomaly, z_score, stats
class CUSUMDetector:
"""Cumulative Sum (CUSUM) anomaly detection"""
def __init__(self, threshold=5.0, drift=0.5, window=50):
"""
threshold: detection threshold
drift: allowable drift from mean
window: window for calculating baseline
"""
[Link] = threshold
[Link] = drift
[Link] = window
[Link] = []
self.cusum_pos = 0.0
self.cusum_neg = 0.0
[Link] = 0.0
def add_sample(self, value):
"""Add sample and detect anomaly"""
[Link](value)
if len([Link]) > [Link]:
[Link](0)
if len([Link]) < 5:
return False, 0.0, None
# Update mean
[Link] = sum([Link]) / len([Link])
# Update CUSUM
deviation = value - [Link]
self.cusum_pos = max(0, self.cusum_pos + deviation - [Link])
self.cusum_neg = max(0, self.cusum_neg - deviation - [Link])
# Detect anomaly
is_anomaly = self.cusum_pos > [Link] or self.cusum_neg > [Link]
score = max(self.cusum_pos, self.cusum_neg)
stats = {
'mean': [Link],
'cusum_pos': self.cusum_pos,
'cusum_neg': self.cusum_neg
}
return is_anomaly, score, stats
class EnsembleDetector:
"""Ensemble of multiple anomaly detectors"""
def __init__(self, vote_threshold=0.5):
"""
vote_threshold: fraction of detectors that must agree (0-1)
"""
self.vote_threshold = vote_threshold
[Link] = {
'zscore': ZScoreDetector(threshold=3.0),
'modified_z': ModifiedZScoreDetector(threshold=3.5),
'iqr': IQRDetector(iqr_multiplier=1.5),
'ewma': EWMADetector(alpha=0.2, threshold=3.0),
'cusum': CUSUMDetector(threshold=5.0, drift=0.5)
}
def add_sample(self, value):
"""Add sample and detect with ensemble voting"""
results = {}
votes = 0
total_detectors = len([Link])
for name, detector in [Link]():
is_anomaly, score, stats = detector.add_sample(value)
results[name] = {
'anomaly': is_anomaly,
'score': score,
'stats': stats
}
if is_anomaly:
votes += 1
# Ensemble decision
vote_fraction = votes / total_detectors
ensemble_anomaly = vote_fraction >= self.vote_threshold
return ensemble_anomaly, vote_fraction, results
# Test Anomaly Detection
def test_anomaly_detection():
print("=== Statistical Anomaly Detection Test ===\n")
import random
# Generate normal data with anomalies
print("Generating test data:")
print(" - Normal data: mean=100, std=10")
print(" - Injected anomalies at indices 50, 100, 150\n")
data = []
anomaly_indices = [50, 100, 150]
for i in range(200):
if i in anomaly_indices:
# Inject anomaly
value = 100 + [Link]([-50, 50])
else:
# Normal data
value = 100 + ([Link]() - 0.5) * 20
[Link](value)
# Test each detector
print("Testing Individual Detectors:\n")
detectors = {
'Z-Score': ZScoreDetector(threshold=3.0),
'Modified Z-Score': ModifiedZScoreDetector(threshold=3.5),
'IQR': IQRDetector(iqr_multiplier=1.5),
'EWMA': EWMADetector(alpha=0.2, threshold=3.0),
'CUSUM': CUSUMDetector(threshold=5.0)
}
detections = {name: [] for name in [Link]()}
# Process data
for i, value in enumerate(data):
for name, detector in [Link]():
is_anomaly, score, stats = detector.add_sample(value)
if is_anomaly:
detections[name].append(i)
# Report results
print("Detection Results:")
print(f"True anomalies at indices: {anomaly_indices}\n")
for name, detected_indices in [Link]():
true_positives = sum(1 for idx in detected_indices if idx in anomaly_indices)
false_positives = len(detected_indices) - true_positives
missed = sum(1 for idx in anomaly_indices if idx not in detected_indices)
print(f"{name}:")
print(f" Detected: {len(detected_indices)} anomalies")
print(f" True Positives: {true_positives}")
print(f" False Positives: {false_positives}")
print(f" Missed: {missed}")
print()
# Test Ensemble Detector
print("\nTesting Ensemble Detector (voting):")
ensemble = EnsembleDetector(vote_threshold=0.6) # 60% must agree
ensemble_detections = []
for i, value in enumerate(data):
is_anomaly, vote_fraction, results = ensemble.add_sample(value)
if is_anomaly:
ensemble_detections.append((i, vote_fraction))
print(f"Ensemble detected {len(ensemble_detections)} anomalies")
print("\nDetailed results:")
print("Index | Value | Vote % | Status")
print("------|-------|--------|-------")
for idx, vote_pct in ensemble_detections:
is_true = "TRUE" if idx in anomaly_indices else "FALSE"
print(f" {idx:3d} | {data[idx]:5.1f} | {vote_pct*100:5.1f}% | {is_true}")
print("\nAnomaly detection test complete!")
# Run test
test_anomaly_detection()
# Real-time monitoring with alerts (uncomment to use)
"""
# Initialize hardware
adc = ADC(Pin(34))
[Link](ADC.ATTN_11DB)
[Link](ADC.WIDTH_12BIT)
alert_led = Pin(2, [Link])
buzzer = Pin(4, [Link])
# Create ensemble detector
detector = EnsembleDetector(vote_threshold=0.5)
print("Real-time Anomaly Detection Started")
print("Monitoring sensor for anomalies...\n")
sample_count = 0
anomaly_count = 0
try:
while True:
# Read sensor
raw_value = [Link]()
# Detect anomaly
is_anomaly, vote_fraction, results = detector.add_sample(raw_value)
sample_count += 1
if is_anomaly:
anomaly_count += 1
alert_led.on()
[Link]()
print(f"\n*** ANOMALY DETECTED! (#{anomaly_count}) ***")
print(f"Sample: {sample_count} | Value: {raw_value}")
print(f"Ensemble vote: {vote_fraction*100:.1f}%")
# Show which detectors flagged it
for name, result in [Link]():
if result['anomaly']:
print(f" - {name}: ANOMALY (score: {result['score']:.2f})")
print()
[Link](0.5) # Alert duration
alert_led.off()
[Link]()
else:
# Normal operation
if sample_count % 50 == 0:
print(f"Samples: {sample_count} | Anomalies: {anomaly_count} | Current:
{raw_value}")
[Link](0.1)
except KeyboardInterrupt:
alert_led.off()
[Link]()
print(f"\nMonitoring stopped")
print(f"Total samples: {sample_count}")
print(f"Total anomalies: {anomaly_count} ({anomaly_count/sample_count*100:.2f}%)")
"""
11. Mathematical Expression Parser
Prompt: Create a MicroPython program implementing Mathematical Expression Parser with
tokenization, recursive descent parsing, expression evaluation, and support for variables,
functions, and operators for embedded calculator applications.
Hardware Requirements:
● ESP32 Development Board / Raspberry Pi Pico
● Optional: Keypad (4x4) for input
● Optional: OLED/LCD display for output
● Optional: Rotary encoder for variable adjustment
Connections:
● Keypad → GPIO pins (rows: 25,26,27,14, cols: 12,13,15,32)
● Display → I2C (SCL: GPIO22, SDA: GPIO21)
Additional Details:
● Recursive descent parser for mathematical expressions
● Support for: +, -, *, /, ^, %, parentheses
● Built-in functions: sin, cos, tan, sqrt, log, exp, abs
● Variable support and assignment
● Operator precedence and associativity
● Error handling for invalid expressions
MicroPython Code:
"""
Mathematical Expression Parser for ESP32/Raspberry Pi Pico
Supports tokenization, recursive descent parsing, variables, and functions
"""
import math
import time
from machine import Pin, I2C, ADC
try:
from ssd1306 import SSD1306_I2C
DISPLAY_AVAILABLE = True
except:
DISPLAY_AVAILABLE = False
class Token:
"""Token class for lexer"""
# Token types
NUMBER = 'NUMBER'
OPERATOR = 'OPERATOR'
FUNCTION = 'FUNCTION'
LPAREN = 'LPAREN'
RPAREN = 'RPAREN'
VARIABLE = 'VARIABLE'
COMMA = 'COMMA'
ASSIGN = 'ASSIGN'
EOF = 'EOF'
def __init__(self, type, value):
[Link] = type
[Link] = value
def __repr__(self):
return f'Token({[Link]}, {[Link]})'
class Lexer:
"""Tokenizer for mathematical expressions"""
OPERATORS = {'+', '-', '*', '/', '^', '%'}
FUNCTIONS = {
'sin', 'cos', 'tan', 'asin', 'acos', 'atan',
'sqrt', 'log', 'ln', 'exp', 'abs', 'ceil', 'floor',
'min', 'max', 'pow', 'round'
def __init__(self, text):
[Link] = [Link](' ', '') # Remove whitespace
[Link] = 0
self.current_char = [Link][0] if [Link] else None
def advance(self):
"""Move to next character"""
[Link] += 1
self.current_char = [Link][[Link]] if [Link] < len([Link]) else None
def peek(self):
"""Look at next character without advancing"""
peek_pos = [Link] + 1
return [Link][peek_pos] if peek_pos < len([Link]) else None
def skip_whitespace(self):
"""Skip whitespace characters"""
while self.current_char and self.current_char.isspace():
[Link]()
def read_number(self):
"""Read a number (integer or float)"""
num_str = ''
has_dot = False
while self.current_char and (self.current_char.isdigit() or self.current_char == '.'):
if self.current_char == '.':
if has_dot:
raise ValueError("Invalid number format")
has_dot = True
num_str += self.current_char
[Link]()
return float(num_str)
def read_identifier(self):
"""Read identifier (function or variable name)"""
identifier = ''
while self.current_char and (self.current_char.isalnum() or self.current_char == '_'):
identifier += self.current_char
[Link]()
return identifier
def get_next_token(self):
"""Get next token from input"""
while self.current_char:
if self.current_char.isspace():
self.skip_whitespace()
continue
# Numbers
if self.current_char.isdigit() or self.current_char == '.':
return Token([Link], self.read_number())
# Identifiers (functions or variables)
if self.current_char.isalpha() or self.current_char == '_':
identifier = self.read_identifier()
if identifier in [Link]:
return Token([Link], identifier)
else:
return Token([Link], identifier)
# Operators
if self.current_char in [Link]:
op = self.current_char
[Link]()
return Token([Link], op)
# Assignment
if self.current_char == '=':
[Link]()
return Token([Link], '=')
# Parentheses
if self.current_char == '(':
[Link]()
return Token([Link], '(')
if self.current_char == ')':
[Link]()
return Token([Link], ')')
# Comma
if self.current_char == ',':
[Link]()
return Token([Link], ',')
raise ValueError(f"Invalid character: {self.current_char}")
return Token([Link], None)
class Parser:
"""Recursive descent parser for mathematical expressions"""
def __init__(self, lexer):
[Link] = lexer
self.current_token = [Link].get_next_token()
[Link] = {}
def eat(self, token_type):
"""Consume current token if it matches expected type"""
if self.current_token.type == token_type:
self.current_token = [Link].get_next_token()
else:
raise ValueError(f"Expected {token_type}, got {self.current_token.type}")
def parse(self):
"""Parse expression (handles assignments)"""
# Check for assignment
if self.current_token.type == [Link]:
var_name = self.current_token.value
next_pos = [Link]
next_char = [Link].current_char
# Look ahead for assignment
[Link]([Link])
if self.current_token.type == [Link]:
[Link]([Link])
value = [Link]()
[Link][var_name] = value
return value
else:
# Not an assignment, reset and parse as expression
[Link] = next_pos - len(var_name)
[Link].current_char = [Link][[Link]] if [Link] <
len([Link]) else None
self.current_token = [Link].get_next_token()
return [Link]()
def expression(self):
"""Parse addition and subtraction (lowest precedence)"""
result = [Link]()
while self.current_token.type == [Link] and self.current_token.value in ['+', '-']:
op = self.current_token.value
[Link]([Link])
if op == '+':
result += [Link]()
else:
result -= [Link]()
return result
def term(self):
"""Parse multiplication, division, and modulo"""
result = [Link]()
while self.current_token.type == [Link] and self.current_token.value in ['*', '/',
'%']:
op = self.current_token.value
[Link]([Link])
if op == '*':
result *= [Link]()
elif op == '/':
divisor = [Link]()
if divisor == 0:
raise ValueError("Division by zero")
result /= divisor
else: # %
result %= [Link]()
return result
def power(self):
"""Parse exponentiation (right-associative)"""
result = [Link]()
if self.current_token.type == [Link] and self.current_token.value == '^':
[Link]([Link])
result = result ** [Link]() # Right-associative
return result
def unary(self):
"""Parse unary operators"""
if self.current_token.type == [Link] and self.current_token.value in ['+', '-']:
op = self.current_token.value
[Link]([Link])
if op == '-':
return -[Link]()
else:
return [Link]()
return [Link]()
def factor(self):
"""Parse numbers, variables, functions, and parentheses"""
token = self.current_token
# Numbers
if [Link] == [Link]:
[Link]([Link])
return [Link]
# Variables
if [Link] == [Link]:
var_name = [Link]
[Link]([Link])
if var_name not in [Link]:
raise ValueError(f"Undefined variable: {var_name}")
return [Link][var_name]
# Functions
if [Link] == [Link]:
func_name = [Link]
[Link]([Link])
[Link]([Link])
args = []
[Link]([Link]())
while self.current_token.type == [Link]:
[Link]([Link])
[Link]([Link]())
[Link]([Link])
return self.evaluate_function(func_name, args)
# Parentheses
if [Link] == [Link]:
[Link]([Link])
result = [Link]()
[Link]([Link])
return result
raise ValueError(f"Unexpected token: {token}")
def evaluate_function(self, func_name, args):
"""Evaluate built-in functions"""
if func_name == 'sin':
if len(args) != 1:
raise ValueError("sin() takes 1 argument")
return [Link](args[0])
elif func_name == 'cos':
if len(args) != 1:
raise ValueError("cos() takes 1 argument")
return [Link](args[0])
elif func_name == 'tan':
if len(args) != 1:
raise ValueError("tan() takes 1 argument")
return [Link](args[0])
elif func_name == 'asin':
if len(args) != 1:
raise ValueError("asin() takes 1 argument")
return [Link](args[0])
elif func_name == 'acos':
if len(args) != 1:
raise ValueError("acos() takes 1 argument")
return [Link](args[0])
elif func_name == 'atan':
if len(args) != 1:
raise ValueError("atan() takes 1 argument")
return [Link](args[0])
elif func_name == 'sqrt':
if len(args) != 1:
raise ValueError("sqrt() takes 1 argument")
if args[0] < 0:
raise ValueError("sqrt() of negative number")
return [Link](args[0])
elif func_name == 'log':
if len(args) != 1:
raise ValueError("log() takes 1 argument")
return math.log10(args[0])
elif func_name == 'ln':
if len(args) != 1:
raise ValueError("ln() takes 1 argument")
return [Link](args[0])
elif func_name == 'exp':
if len(args) != 1:
raise ValueError("exp() takes 1 argument")
return [Link](args[0])
elif func_name == 'abs':
if len(args) != 1:
raise ValueError("abs() takes 1 argument")
return abs(args[0])
elif func_name == 'ceil':
if len(args) != 1:
raise ValueError("ceil() takes 1 argument")
return [Link](args[0])
elif func_name == 'floor':
if len(args) != 1:
raise ValueError("floor() takes 1 argument")
return [Link](args[0])
elif func_name == 'round':
if len(args) != 1:
raise ValueError("round() takes 1 argument")
return round(args[0])
elif func_name == 'min':
if len(args) < 2:
raise ValueError("min() takes at least 2 arguments")
return min(args)
elif func_name == 'max':
if len(args) < 2:
raise ValueError("max() takes at least 2 arguments")
return max(args)
elif func_name == 'pow':
if len(args) != 2:
raise ValueError("pow() takes 2 arguments")
return args[0] ** args[1]
else:
raise ValueError(f"Unknown function: {func_name}")
class MathCalculator:
"""Calculator with display and keypad support"""
def __init__(self):
# Keypad configuration (4x4)
[Link] = [25, 26, 27, 14]
[Link] = [12, 13, 15, 32]
self.keypad_layout = [
['7', '8', '9', '/'],
['4', '5', '6', '*'],
['1', '2', '3', '-'],
['C', '0', '=', '+']
]
# Initialize keypad pins
self.row_pins = [Pin(pin, [Link]) for pin in [Link]]
self.col_pins = [Pin(pin, [Link], Pin.PULL_DOWN) for pin in [Link]]
# Display setup
if DISPLAY_AVAILABLE:
try:
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
[Link] = SSD1306_I2C(128, 64, i2c)
self.has_display = True
except:
self.has_display = False
print("Display not found")
else:
self.has_display = False
[Link] = ""
[Link] = None
[Link] = {}
def scan_keypad(self):
"""Scan keypad for pressed key"""
for row_idx, row_pin in enumerate(self.row_pins):
row_pin.value(1)
time.sleep_ms(1)
for col_idx, col_pin in enumerate(self.col_pins):
if col_pin.value():
key = self.keypad_layout[row_idx][col_idx]
row_pin.value(0)
# Debounce
while col_pin.value():
time.sleep_ms(10)
return key
row_pin.value(0)
return None
def evaluate_expression(self, expr):
"""Evaluate mathematical expression"""
try:
lexer = Lexer(expr)
parser = Parser(lexer)
# Share variables with parser
[Link] = [Link]
result = [Link]()
# Update variables
[Link] = [Link]
return result
except Exception as e:
raise ValueError(f"Error: {str(e)}")
def update_display(self):
"""Update OLED display"""
if not self.has_display:
return
[Link](0)
# Display expression
[Link]("Expr:", 0, 0)
# Split long expressions
if len([Link]) > 16:
[Link]([Link][-16:], 0, 12)
else:
[Link]([Link], 0, 12)
# Display result
if [Link] is not None:
[Link]("Result:", 0, 30)
result_str = f"{[Link]:.6g}"
if len(result_str) > 16:
result_str = f"{[Link]:.2e}"
[Link](result_str, 0, 42)
[Link]()
def run(self):
"""Main calculator loop"""
print("=== Math Expression Parser ===")
print("Supported operations: +, -, *, /, ^, %, ()")
print("Functions: sin, cos, tan, sqrt, log, exp, abs, min, max, etc.")
print("Variables: x = 5, y = x + 3")
print("Press 'C' to clear, '=' to evaluate")
print()
while True:
# Keypad input
key = self.scan_keypad()
if key:
if key == 'C':
[Link] = ""
[Link] = None
print("\nCleared")
elif key == '=':
if [Link]:
try:
[Link] = self.evaluate_expression([Link])
print(f"\n{[Link]} = {[Link]}")
[Link] = ""
except Exception as e:
print(f"\nError: {e}")
[Link] = None
else:
[Link] += key
print(key, end='')
self.update_display()
time.sleep_ms(50)
def test_parser():
"""Test the expression parser"""
test_expressions = [
"2 + 3 * 4",
"10 / 2 - 3",
"2 ^ 3 ^ 2",
"(2 + 3) * 4",
"sin(0)",
"cos(3.14159)",
"sqrt(16)",
"log(100)",
"abs(-5)",
"min(3, 5, 2, 8)",
"max(1, 9, 3)",
"x = 10",
"y = x + 5",
"x * y",
"2 * (3 + 4) / 7",
"-5 + 3",
"10 % 3"
]
print("=== Expression Parser Tests ===\n")
variables = {}
for expr in test_expressions:
try:
lexer = Lexer(expr)
parser = Parser(lexer)
[Link] = variables
result = [Link]()
variables = [Link]
print(f"{expr:25s} = {result:.6g}")
except Exception as e:
print(f"{expr:25s} => Error: {e}")
print("\nVariables:", variables)
# Main execution
if __name__ == '__main__':
# Run tests first
test_parser()
print("\n" + "="*40)
print("Starting calculator...")
print("="*40 + "\n")
# Start calculator
calculator = MathCalculator()
[Link]()