Many dogs feel lonely or anxious when their family is out, and barking is how they show it. But you can't hear it, because you're not there. Neighbours might, though! This bark monitor listens while you are away. It recognises barks by their length, so a door slam or a car doesn't count. It counts them, notices long barking spells and draws an hourly bar chart right on the LCD, using custom characters as bars. When you come home you can see at a glance whether your dog was calm or had a hard time, and when. That's useful information for you, and for a vet or dog trainer if you need help. During a long barking spell, it can play a soft, slow tune that some dogs find soothing.
What you'll learn
- How to recognise a sound event (a bark) by its length
- How to keep a count per hour in an array, and shift it when a new hour starts
- How to draw a bar chart on a character LCD with 8 custom characters
- How a short and a long button press can do different things
What you need
- UNO R3 board and USB cable (UNO R3 Starter Kit)
- High-sensitivity sound sensor module (45-in-1 Sensor Kit)
- 1602 LCD display, 10 kΩ potentiometer and 1 resistor, 220 Ω (UNO R3 Starter Kit)
- Passive buzzer (UNO R3 Starter Kit)
- 1 push button (UNO R3 Starter Kit)
- Breadboard and jumper wires (UNO R3 Starter Kit)
Be kind to your dog. This monitor is for understanding your dog, never for punishing it. Don't use beeps or any other sound to stop barking: dogs bark for a reason. If your dog barks a lot when alone, talk to a vet or a qualified dog trainer. Ask an adult before leaving electronics switched on while nobody is at home.
Wiring

| From | To |
|---|---|
| LCD VSS, RW and K | GND |
| LCD VDD | 5V |
| LCD V0 | Middle pin (W) of the potentiometer |
| LCD RS | UNO pin 12 |
| LCD E | UNO pin 11 |
| LCD D4, D5, D6, D7 | UNO pins 5, 4, 3, 2 |
| LCD D0 to D3 | Not connected |
| LCD A (backlight +) | 220 Ω resistor, then 5V |
| Potentiometer outer pins | 5V and GND |
| Sound sensor G, + | GND, 5V |
| Sound sensor DO | UNO pin 7 |
| Passive buzzer +, − | UNO pin 8, GND |
| Push button, one leg | UNO pin 6 |
| Push button, the diagonally opposite leg | GND |
Turn the sound sensor's blue knob so that its small LED is off in a quiet room but lights clearly when you clap from a few metres away. Put the monitor in the room where your dog stays, out of its reach.
The sketch
LiquidCrystal comes with the Arduino IDE. PLAY_TUNE switches the calm tune on (true) or off (false).
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
const int SOUND_PIN = 7, BUZZER_PIN = 8, BUTTON_PIN = 6;
const bool PLAY_TUNE = true; // soft tune during long barking spells
const unsigned long QUIET_GAP = 60; // ms of silence = the sound has ended
const unsigned long BARK_MIN = 80, BARK_MAX = 1200; // a bark lasts 0.08 to 1.2 s
const int SPELL_BARKS = 8; // this many barks in 2 minutes = a barking spell
const unsigned long HOUR = 3600000UL;
int hourly[16]; // barks per hour, [15] is the current hour
long total = 0;
int spells = 0;
unsigned long hourStart = 0, lastSound = 0, soundStart = 0, lastBark = 0, lastTune = 0;
unsigned long recent[SPELL_BARKS]; // times of the latest barks
int recentNext = 0;
bool inSound = false, chartScreen = false, lastButton = HIGH;
unsigned long pressStart = 0;
int quietLevel;
// 8 bar heights for the chart: 1 to 8 dark rows at the bottom
void makeBars() {
for (int h = 1; h <= 8; h++) {
byte rows[8];
for (int r = 0; r < 8; r++) rows[r] = (r >= 8 - h) ? 0b11111 : 0;
lcd.createChar(h - 1, rows);
}
}
void calmTune() { // slow, low and soft
const int notes[] = {392, 330, 294, 262, 294, 330, 262};
for (int i = 0; i < 7; i++) {
tone(BUZZER_PIN, notes[i], 500);
delay(700);
}
noTone(BUZZER_PIN);
}
void countBark(unsigned long now) {
total++;
hourly[15]++;
lastBark = now;
recent[recentNext] = now;
recentNext = (recentNext + 1) % SPELL_BARKS;
unsigned long oldest = recent[recentNext]; // the 8th bark back
if (oldest != 0 && now - oldest < 120000UL) {
spells++;
for (int i = 0; i < SPELL_BARKS; i++) recent[i] = 0; // start counting again
if (PLAY_TUNE && now - lastTune > 600000UL) { // at most every 10 minutes
lastTune = now;
calmTune();
}
}
}
void listen(unsigned long now) {
if (digitalRead(SOUND_PIN) != quietLevel) lastSound = now;
bool loud = now - lastSound < QUIET_GAP;
if (loud && !inSound) { inSound = true; soundStart = now; }
if (!loud && inSound) {
inSound = false;
unsigned long length = lastSound - soundStart;
if (length >= BARK_MIN && length <= BARK_MAX) countBark(now); // too short = click, too long = noise
}
}
void showSummary(unsigned long now) {
lcd.setCursor(0, 0);
lcd.print("Barks ");
lcd.print(total);
lcd.print(" Spells ");
lcd.print(spells);
lcd.print(" ");
lcd.setCursor(0, 1);
if (lastBark == 0) {
lcd.print("No barks yet :) ");
} else {
unsigned long mins = (now - lastBark) / 60000;
lcd.print("Last ");
lcd.print(mins);
lcd.print(" min ago ");
}
}
void showChart() {
int most = 1;
for (int i = 0; i < 16; i++) most = max(most, hourly[i]);
lcd.setCursor(0, 0);
lcd.print("Last 16 h max");
lcd.print(most < 10 ? " " : "");
lcd.print(min(most, 99));
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
if (hourly[i] == 0) lcd.print('_');
else lcd.write((uint8_t)(map(hourly[i], 1, max(most, 1), 0, 7)));
}
}
void setup() {
pinMode(SOUND_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
lcd.begin(16, 2);
makeBars();
lcd.print("Bark monitor");
lcd.setCursor(0, 1);
lcd.print("Keep quiet...");
delay(1500);
quietLevel = digitalRead(SOUND_PIN); // the sensor's output in silence
lcd.clear();
hourStart = millis();
}
void loop() {
unsigned long now = millis();
listen(now);
if (now - hourStart >= HOUR) { // a new hour: move the chart one step left
hourStart += HOUR;
for (int i = 0; i < 15; i++) hourly[i] = hourly[i + 1];
hourly[15] = 0;
}
// Button: short press = other screen, hold 3 s = reset all counts
bool button = digitalRead(BUTTON_PIN);
if (lastButton == HIGH && button == LOW) pressStart = now;
if (lastButton == LOW && button == HIGH) {
if (now - pressStart > 3000) {
total = 0; spells = 0; lastBark = 0;
for (int i = 0; i < 16; i++) hourly[i] = 0;
lcd.clear();
lcd.print("Counts reset");
delay(1000);
} else if (now - pressStart > 30) {
chartScreen = !chartScreen;
}
lcd.clear();
}
lastButton = button;
static unsigned long lastDraw = 0;
if (now - lastDraw > 250) {
lastDraw = now;
if (chartScreen) showChart();
else showSummary(now);
}
}
Try it
- Upload the sketch and keep the room quiet for the first two seconds while it learns what silence looks like.
- Play a video of a barking dog on your phone near the sensor, or say "woof!" a few times. The bark count goes up. Clap once: a clap is too short to count. Talk for a while: long sounds don't count either.
- Bark eight times within two minutes: that's a barking spell. If
PLAY_TUNEis true, the buzzer plays a slow tune (at most once every 10 minutes). - Press the button for the chart screen: one bar for each of the last 16 hours, the newest on the right. Hold the button for 3 seconds to reset all counts.
- Leave it running while you go out (with an adult's OK), and look at the chart when you come home.
How it works
The sound sensor's output flickers with the sound wave, so the sketch treats the sound as "still going" until it has been quiet for 60 ms. The time from the start to the end of the sound is its length. A dog's bark is short and sharp, typically between 0.1 and 1 second. A clap, a click or a dropped spoon is shorter, while talking, music or a vacuum cleaner go on much longer. Counting only sounds with a bark-like length is a simple but surprisingly good filter.
The chart uses an array of 16 numbers, one per hour. The newest hour is always at the end. When an hour is over, every number moves one place to the left and the last place starts again at 0, just like a scrolling graph. To draw it, the sketch designs 8 custom characters, each a bar with 1 to 8 dark rows, and picks the right height for each hour with map(). The busiest hour gets the full-height bar.
For barking spells the sketch remembers the times of the last 8 barks in a small ring buffer. If the oldest of those 8 is less than 2 minutes old, eight barks came within two minutes: a spell.
Try this next
- Rebuild it on the ESP32 and send a phone message with ntfy when a barking spell starts.
- Add a second sound sensor in another room to see where the barking happens (door, window).
- Record the "busiest hour" and show it on the summary screen.
- Measure the length of your own dog's barks with the Serial Monitor and tune
BARK_MINandBARK_MAXto them.
Troubleshooting
- The LCD lights up but shows nothing, or only black boxes: turn the potentiometer slowly from one end to the other until the text appears.
- It counts everything, or nothing: turn the sensor's knob. The LED should be off in silence and flash for a bark a few metres away. Restart in silence after turning it.
-
Barks are counted twice: the dog barks with a short break inside. Raise
QUIET_GAPto 100. - The chart shows only "_": no barks yet in the last 16 hours, or the button reset everything.