Arduino pulse rate monitor

1. System Overview

A pulse rate monitor measures heartbeats using an optical sensing technique called photoplethysmography (PPG). The system works as follows:

  1. An LED emits light into the skin.

  2. A photodiode detects variations in reflected light.

  3. The signal is amplified and filtered.

  4. The microcontroller processes the signal.

  5. Beats per minute (BPM) are calculated.

  6. The result is displayed or transmitted.

The microcontroller used in this guide is the Arduino Uno, but other compatible boards such as the Arduino Nano can also be used.

2. Required Components

Core Components

  • Arduino Uno

  • Pulse Sensor Amped

  • Breadboard

  • Jumper wires

  • USB cable

Optional Components

  • 16×2 LCD display

  • OLED display (I2C)

  • 10kΩ potentiometer (for LCD contrast)

  • Buzzer (heartbeat indication)

  • External power supply (9V battery)

  • Enclosure case

3. Working Principle of the Pulse Sensor

The Pulse Sensor typically contains:

  • A green LED (light source)

  • A photodiode (light detector)

  • Amplifier circuitry

  • Noise filtering stage

Principle of Operation

When the heart pumps blood:

  • Blood volume in the capillaries increases.

  • Light absorption increases.

  • Reflected light decreases.

  • The photodiode output voltage changes.

This produces a waveform known as a PPG signal, which contains periodic peaks corresponding to heartbeats.

4. Circuit Connections

Pulse Sensor to Arduino

Pulse Sensor Pin Arduino Pin
VCC 5V
GND GND
SIGNAL A0

The signal pin connects to analog input A0.

Optional: 16×2 LCD (Parallel Mode)

LCD Pin Arduino Pin
RS 12
EN 11
D4 5
D5 4
D6 3
D7 2
VSS GND
VDD 5V

5. Signal Processing Logic

The sensor outputs an analog waveform that includes noise. The Arduino must:

  1. Continuously read analog values.

  2. Detect peaks above a defined threshold.

  3. Measure time between successive peaks.

  4. Calculate BPM.

BPM Calculation

If IBI is the inter-beat interval in milliseconds:

BPM = 60000 / IBI

Where:

  • 60000 = milliseconds per minute

  • IBI = time between two detected heartbeats

6. Arduino Code (Basic Version)

const int pulsePin = A0;
int signal;
int threshold = 550;
unsigned long lastBeatTime = 0;
unsigned long currentTime;
int BPM = 0;

void setup() {
Serial.begin(9600);
}

void loop() {
signal = analogRead(pulsePin);
currentTime = millis();

if(signal > threshold) {
if(currentTime – lastBeatTime > 300) {
unsigned long IBI = currentTime – lastBeatTime;
lastBeatTime = currentTime;
BPM = 60000 / IBI;
Serial.print(“BPM: “);
Serial.println(BPM);
}
}
}

7. Code Explanation

Threshold

The threshold filters out noise. It must be adjusted depending on:

  • Finger placement

  • Ambient light conditions

  • Individual physiology

Debounce Interval (300 ms)

This prevents double counting. A 300 ms minimum interval limits detection to a maximum of approximately 200 BPM.

8. Adding LCD Display

Include the library:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

In setup():

lcd.begin(16, 2);

In loop():

lcd.setCursor(0, 0);
lcd.print("Heart Rate:");
lcd.setCursor(0, 1);
lcd.print(BPM);
lcd.print(" BPM ");

9. Improving Accuracy

1. Moving Average Filtering

BPM = (BPM + previousBPM) / 2;

This smooths fluctuations.

2. Use Interrupt-Based Sampling

Provides more precise timing than polling in the main loop.

3. Use Hardware Timers

Using Timer2 improves sampling stability and reduces jitter.

4. Reduce Ambient Light

Use a finger clip or dark enclosure to block external light interference.

10. Calibration Procedure

  1. Open Serial Monitor

  2. Observe raw analog values

  3. Identify:

    • Resting signal level

    • Peak signal level

  4. Set threshold midway between these values.

Example:

  • Resting value: 520

  • Peak value: 620

  • Threshold: 570

11. Expected Output

Normal adult resting heart rate:

  • 60–100 BPM

Athletes:

  • 40–60 BPM

If readings fluctuate significantly:

  • Check noise filtering

  • Recalibrate threshold

  • Improve finger positioning

12. Troubleshooting

Problem Possible Cause Solution
No reading Wiring issue Check connections
Unstable BPM Noise Improve filtering
Constant zero Threshold too high Lower threshold
Very high BPM Threshold too low Increase threshold
[mai mult...]

ESP32 Light sensor

ESP32 Light Sensor

1. Introduction

Light sensors allow the ESP32 to measure ambient light levels and react intelligently to environmental changes. Typical projects include automatic lighting, brightness control, weather stations, smart blinds, energy-saving systems, and IoT monitoring dashboards.

This guide provides a complete and detailed technical walkthrough for using light sensors with the ESP32. It covers sensor selection, wiring, ADC behavior, calibration, power optimization, software design, and real-world applications.

2. Types of Light Sensors for ESP32

2.1 LDR (Light Dependent Resistor / Photoresistor)

Best for: Simple and low-cost ambient light detection

An LDR changes its resistance based on the amount of light falling on it. As light intensity increases, resistance decreases. Because the ESP32 cannot measure resistance directly, an LDR must be used with a voltage divider circuit.

  • Very inexpensive and widely available
  • Simple analog interface
  • Non-linear response curve
  • Slow response compared to digital sensors

2.2 Photodiode / Phototransistor

Photodiodes and phototransistors provide faster and more precise light detection than LDRs. They generate current proportional to light intensity and are commonly used in applications requiring quick response times or better linearity.

These sensors often require additional circuitry such as transimpedance amplifiers or comparator circuits.

2.3 Digital Light Sensors

Digital light sensors communicate with the ESP32 using I2C and output calibrated light measurements directly in lux.

  • BH1750 – Ambient light sensor (lux output)
  • TSL2561 / TSL2591 – High dynamic range sensors
  • VEML7700 – High precision, ultra-low power

Advantages: High accuracy, wide dynamic range, no ADC noise issues, and factory calibration.

3. ESP32 ADC Overview

The ESP32 features a 12-bit Analog-to-Digital Converter (ADC). While powerful, it has limitations that must be understood to achieve reliable light measurements.

3.1 ADC Channels

  • ADC1: GPIO 32–39 (recommended)
  • ADC2: Shared with Wi-Fi (avoid when Wi-Fi is active)

3.2 ADC Resolution and Attenuation

Attenuation Input Voltage Range
0 dB ~1.1 V
2.5 dB ~1.5 V
6 dB ~2.2 V
11 dB ~3.9 V

Correct attenuation settings are essential to avoid ADC saturation and inaccurate readings.

4. Using an LDR with ESP32

4.1 Wiring an LDR (Voltage Divider)

An LDR must be connected in a voltage divider configuration to convert resistance changes into voltage.

  • LDR → 3.3V
  • 10kΩ resistor → GND
  • Junction point → GPIO 34 (ADC1)

4.2 Arduino Code Example (LDR)

#define LDR_PIN 34

void setup() {
  Serial.begin(115200);
  analogReadResolution(12);
}

void loop() {
  int rawValue = analogRead(LDR_PIN);
  Serial.println(rawValue);
  delay(500);
}

4.3 Improving LDR Accuracy

  • Use ADC1 pins only
  • Add a 0.1µF capacitor for noise filtering
  • Average multiple ADC readings
  • Shield sensor from electrical noise

5. Using BH1750 Digital Light Sensor

5.1 BH1750 Features

  • Measures ambient light in lux
  • I2C interface
  • Range: 1–65,535 lux
  • Operating voltage: 3.3V

5.2 Wiring BH1750 to ESP32

  • VCC → 3.3V
  • GND → GND
  • SDA → GPIO 21
  • SCL → GPIO 22

5.3 Arduino Code Example (BH1750)

#include 
#include 

BH1750 lightMeter;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  lightMeter.begin();
}

void loop() {
  float lux = lightMeter.readLightLevel();
  Serial.print("Light: ");
  Serial.print(lux);
  Serial.println(" lx");
  delay(1000);
}

6. Calibration and Lux Mapping

LDRs are non-linear and require calibration to map ADC values to real-world light levels. This is typically done using known light sources and curve fitting or lookup tables.

  • Measure ADC values at known lux levels
  • Plot logarithmic response curve
  • Apply scaling or lookup table in software

7. Power Optimization

For battery-powered projects, power consumption must be minimized.

  • Reduce sampling frequency
  • Use sensor sleep modes
  • Enable ESP32 deep sleep

esp_sleep_enable_timer_wakeup(10 * 1000000);
esp_deep_sleep_start();

8. Automation and Logic Integration

  • Turn lights ON when lux falls below a threshold
  • Adjust LED brightness using PWM
  • Disable motion detection during daylight

9. Common Issues and Troubleshooting

  • Noisy readings: Improve grounding and average samples
  • Incorrect lux values: Check I2C wiring and sensor mode
  • ADC saturation: Adjust attenuation

10. Real-World Applications

  • Smart street lighting
  • Automatic display brightness
  • Greenhouse and agriculture monitoring
  • Weather stations
  • Solar tracking systems

11. Advanced Enhancements

  • Combine LDR and digital sensors for redundancy
  • Send lux data via MQTT
  • Cloud logging and dashboards
  • Machine learning for light pattern analysis.

[mai mult...]

ESP32 Motion sensor

The ESP32 is a powerful, low-cost microcontroller with built-in Wi-Fi and Bluetooth, making it an excellent platform for motion-sensing projects such as smart lighting, security systems, occupancy tracking, and IoT automation.

1. Motion Sensors Compatible with ESP32

1.1 PIR Motion Sensor (HC-SR501)

Best for: Human motion detection, low power consumption, simple digital output

  • Detects changes in infrared radiation from warm objects
  • Outputs HIGH when motion is detected
  • Detection range: 3–7 meters (typical)

Limitations: Cannot detect stationary objects and has slower response than radar sensors.

1.2 Microwave Radar Sensor (RCWL-0516)

Uses Doppler radar instead of infrared. It is more sensitive than PIR sensors and can detect motion through thin walls, but may cause more false triggers.

1.3 Accelerometer / IMU (MPU6050)

  • Detects motion, tilt, and vibration
  • Common in robotics and wearables
  • Uses I2C communication

2. PIR Motion Sensor Basics

2.1 PIR Sensor Pinout (HC-SR501)

Pin Name Description
1 VCC 5V (some support 3.3V)
2 OUT Digital output (HIGH on motion)
3 GND Ground

Note: Most HC-SR501 modules output 3.3V logic, which is safe for ESP32 GPIO pins.

2.2 Onboard Adjustments

  • Sensitivity potentiometer (detection range)
  • Time delay potentiometer (output HIGH duration)
  • Trigger mode jumper: H = repeat, L = single trigger

3. ESP32 GPIO and Power Considerations

Recommended GPIO pins: 13, 14, 25, 26, 27, 32, 33

Avoid boot-sensitive pins: 0, 2, 12, 15 unless you understand ESP32 boot modes.

ESP32 uses 3.3V logic. PIR sensors may require 5V power. Always connect grounds together.

4. Wiring the PIR Sensor to ESP32

  • VCC → VIN (5V) or 3.3V (if supported)
  • GND → GND
  • OUT → GPIO 27

5. Basic Arduino Code Example

#define PIR_PIN 27

void setup() {
  Serial.begin(115200);
  pinMode(PIR_PIN, INPUT);
}

void loop() {
  if (digitalRead(PIR_PIN)) {
    Serial.println("Motion detected!");
    delay(500);
  }
}

6. Interrupt-Based Motion Detection

#define PIR_PIN 27
volatile bool motionDetected = false;

void IRAM_ATTR motionISR() {
  motionDetected = true;
}

void setup() {
  Serial.begin(115200);
  pinMode(PIR_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(PIR_PIN), motionISR, RISING);
}

void loop() {
  if (motionDetected) {
    Serial.println("Motion detected via interrupt!");
    motionDetected = false;
  }
}

7. Power Saving with Deep Sleep

esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, 1);
esp_deep_sleep_start();

This allows the ESP32 to sleep until motion is detected, ideal for battery-powered systems.

8. Common Problems and Solutions

  • False triggers: Reduce sensitivity and avoid heat sources
  • No detection: Allow sensor warm-up time (30–60 seconds)
  • Random resets: Ensure stable power supply

9. Applications

  • Smart lighting systems
  • Home security and alarms
  • Occupancy detection
  • Energy-saving automation.

[mai mult...]