Preview build — page text is a draft awaiting human review. Code badges come from real compiles. The flasher is real but not yet hardware-tested; the Playground is still a preview.
Whistle Counter: the finished build
NanoIndia utility

Pressure cooker whistle counter with alarm (Arduino Nano + sound sensor)

Counts the cooker’s whistles and beeps when the dal is done — no more “was that 2 or 3?”

Difficulty
Easy
Build time
1 h
Parts cost
₹685 · $8
Verified — core avr 1.8.8, TM1637 1.2.0, 3 Nov 2026Compile-only

Community draft — report a mistake

Parts list

PartQtyApprox.Buy
Arduino Nano (CH340, ATmega328P)1₹300Buy Arduino Nano (CH340, ATmega328P)
KY-038 sound sensor module (microphone + LM393)1₹50Buy KY-038 sound sensor module (microphone + LM393)
TM1637 4-digit display module1₹70Buy TM1637 4-digit display module
Active buzzer module1₹25Buy Active buzzer module
Push button1₹10Buy Push button
Small plastic box + double-sided tape1₹80Buy Small plastic box + double-sided tape
5 V USB adapter or power bank1₹150Buy 5 V USB adapter or power bank
Total₹685

Affiliate disclosure: “Buy” links may earn FlashReady a small commission at no extra cost to you. Prices are indicative.

Wiring

Arduino NanoOnly the pins used are shown · 5 V logicKY-038 sound sensor (microphone + LM393)TM1637 4-digit 7-segment displayActive buzzer module (high-level trigger)Push button (6 mm tactile switch)A05VGNDD8D4D3D2A0G+D0 (not connected)CLKDIOVCCGNDI/OVCCGND12
Every connection
Arduino NanoPart · pinWireNotes
A0KY-038 sound sensor (microphone + LM393) · A0greenAnalog microphone signal
5VKY-038 sound sensor (microphone + LM393) · +red
GNDKY-038 sound sensor (microphone + LM393) · Gblack
D2TM1637 4-digit 7-segment display · CLKorange
D3TM1637 4-digit 7-segment display · DIOgreen
5VTM1637 4-digit 7-segment display · VCCred
GNDTM1637 4-digit 7-segment display · GNDblack
D8Active buzzer module (high-level trigger) · I/Oorange
5VActive buzzer module (high-level trigger) · VCCred
GNDActive buzzer module (high-level trigger) · GNDblack
D4Push button (6 mm tactile switch) · 1blueTap = target, hold 2 s = reset, any press = stop alarm
GNDPush button (6 mm tactile switch) · 2black

Board quirks: Put it on a shelf or wall about 1–2 m from the stove — close enough to hear the whistle clearly, far enough from the heat, steam and oil splashes. Never on the stove top. A whistle is a loud sound that lasts at least 0.6 s. The pressure cooker’s steady hiss before the whistle, a tadka’s splutter, or a dropped spoon are shorter or quieter and are ignored. After each whistle the counter waits 4 s, so one long whistle counts once. Turn the blue trimmer on the KY-038 so its D0 LED is just off in a quiet kitchen; that centres the microphone signal. Then adjust LOUD in the sketch while watching the Serial Monitor. It’s a reminder, not a safety device — don’t leave a cooker on the flame with nobody at home.

Code

pressure-cooker-whistle-counter.inoArduino C++Open in PlaygroundOpen in PlaygroundFlash
// Pressure cooker whistle counter — Arduino Nano + KY-038 sound sensor + TM1637 + buzzer module
// KY-038: A0 -> A0, + -> 5V, G -> GND. TM1637: CLK D2, DIO D3. Buzzer module on D8.
// Push button D4 to GND: tap = whistles wanted (1-9), hold 2 s = start counting again from 0.
// Display "02:03" = 2 whistles heard of 3 wanted. At the target it beeps until you press the button.
#include <TM1637Display.h>

constexpr uint8_t MIC_PIN = A0;
constexpr uint8_t CLK_PIN = 2;
constexpr uint8_t DIO_PIN = 3;
constexpr uint8_t BUZZER_PIN = 8;
constexpr uint8_t BUTTON_PIN = 4;
constexpr int LOUD = 60;                   // peak-to-peak ADC counts that count as "whistling"
constexpr unsigned long WHISTLE_MS = 600;  // a whistle is loud for at least this long
constexpr unsigned long GAP_MS = 4000;     // ignore everything for 4 s after a whistle
constexpr unsigned long ALARM_MAX_MS = 60000UL;

TM1637Display display(CLK_PIN, DIO_PIN);
uint8_t target = 3, whistles = 0;
unsigned long loudSince = 0, quietSince = 0, lastWhistle = 0, alarmSince = 0;
bool alarming = false;

// Loudness: peak-to-peak of the microphone signal over 20 ms (one mains cycle of hum).
int loudness() {
  int lo = 1023, hi = 0;
  unsigned long t0 = millis();
  while (millis() - t0 < 20) {
    int v = analogRead(MIC_PIN);
    if (v < lo) lo = v;
    if (v > hi) hi = v;
  }
  return hi - lo;
}

void show(bool on = true) {
  if (on) display.showNumberDecEx(whistles * 100 + target, 0b01000000, true);  // "WW:TT" with colon
  else display.clear();
}

void setup() {
  Serial.begin(115200);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  display.setBrightness(6);
  show();
  Serial.println(F("Whistle counter: tap = target, hold 2 s = reset"));
}

void loop() {
  unsigned long now = millis();

  // Button
  if (digitalRead(BUTTON_PIN) == LOW) {
    unsigned long t0 = now;
    while (digitalRead(BUTTON_PIN) == LOW && millis() - t0 < 2000) delay(10);
    bool held = millis() - t0 >= 2000;
    if (alarming) {
      alarming = false;  // any press silences the alarm
    } else if (held) {
      whistles = 0;
      Serial.println(F("Reset"));
    } else {
      target = target % 9 + 1;
    }
    digitalWrite(BUZZER_PIN, LOW);
    show();
    while (digitalRead(BUTTON_PIN) == LOW) delay(10);
    now = millis();
  }

  int level = loudness();
  bool loud = level > LOUD;
  if (now - lastWhistle > GAP_MS || lastWhistle == 0) {
    if (loud) {
      quietSince = 0;
      if (!loudSince) loudSince = now;
      if (now - loudSince > WHISTLE_MS) {
        whistles++;
        lastWhistle = now;
        loudSince = 0;
        Serial.print(F("Whistle "));
        Serial.print(whistles);
        Serial.print('/');
        Serial.println(target);
        show();
        if (whistles >= target && !alarming) {
          alarming = true;
          alarmSince = now;
          Serial.println(F("Target reached - turn off the gas!"));
        }
      }
    } else if (loudSince) {
      // Allow short dips inside one whistle (the weight rattles).
      if (!quietSince) quietSince = now;
      if (now - quietSince > 150) loudSince = quietSince = 0;
    }
  }

  if (alarming) {
    bool on = (now / 300) % 2;
    digitalWrite(BUZZER_PIN, on);
    show(on);
    if (now - alarmSince > ALARM_MAX_MS) {
      alarming = false;
      digitalWrite(BUZZER_PIN, LOW);
      show();
    }
  }

  static unsigned long lastLog = 0;
  if (now - lastLog > 1000) {
    lastLog = now;
    Serial.print(F("loud="));
    Serial.print(level);
    Serial.print(F(" whistles="));
    Serial.print(whistles);
    Serial.print('/');
    Serial.println(target);
  }
}

Compiled for nano on avr 1.8.8 with TM1637 1.2.0 · 3 Nov 2026

How it works

“Three whistles for dal, five for rajma, one for rice” — every Indian kitchen counts pressure cooker whistles, and everyone has lost count while doing something else. This little box counts them for you and beeps when the number you set is reached.

How it works

The KY-038 has an electret microphone and an amplifier. Its A0 output is the raw sound waveform riding on about 2.5 V. Every 20 ms the Nano reads A0 as fast as it can and takes the peak-to-peak value — how loud the kitchen is right now.

A pressure cooker whistle is loud and long. The sketch only counts a whistle when the level stays above LOUD for at least 0.6 s (short dips of up to 150 ms, from the weight rattling, are allowed inside one whistle). After counting, it ignores sound for 4 s.

The TM1637 shows 02:03 — two whistles heard, three wanted. Tap the button to change the target (1–9); hold it for 2 s to start again from zero. When the count reaches the target, the display blinks and the buzzer beeps until you press the button (or for one minute).

Why these parts

  • KY-038’s analog output — the module’s D0 comparator only says “loud or not”, which can’t tell a whistle from a spoon. The analog waveform lets the sketch measure how long the sound lasts.
  • TM1637 — readable across the kitchen.
  • Nano — small, and its 5 V ADC reads the module directly.

Calibration

Open the Serial Monitor (115200 baud). It prints loud=… every second. Note the value in a quiet kitchen (often 5–20), with the mixer running, and during a real whistle (often 150+). Set LOUD between the mixer and the whistle.

India notes

Kitchens here are loud — the exhaust fan, the mixer, the TV next door. The duration rule handles most of it; the rest is placement. Keep the box away from the chimney/exhaust fan’s airflow, which also carries oil.

Troubleshooting

It counts the mixer grinder or the TV

Raise LOUD (watch the loud= numbers on the Serial Monitor while the whistle blows and while the mixer runs, and pick a value between) or WHISTLE_MS. The mixer is loud but steady; moving the sensor nearer the cooker helps more than anything.

It misses whistles

The sensor is too far or the trimmer is off-centre. Check loud= reaches well above LOUD during a whistle; lower LOUD or move closer.

The display shows 00:03 and never changes

Check A0 goes to the module’s A0 pin, not D0. The A0 value should jump when you clap.

Upgrades

  • Add a repeat reminder that beeps every minute until you press the button. (Don’t try to shut the gas automatically — a hobby board must never control an LPG valve on a lit stove.)
  • Show the time since the last whistle, for recipes that say “simmer 10 minutes after 1 whistle”.
  • Use an ESP32 and send the “done” to your phone through ntfy.sh when you’re in another room.

↑↓ to move · Enter to open