Arduino Spy Bug Voice Recorder: Build Your Own Spy Voice Recorder

Arduino Spy Bug Voice Recorder Build Your Own Spy Voice Recorder Arduino Spy Bug Voice Recorder Build Your Own Spy Voice Recorder

Have you ever dreamed of having your own covert listening device, a gadget straight out of a spy thriller? While we’re not suggesting you engage in any actual espionage, building a DIY “spy bug” is an incredibly fun and educational electronics project. At the heart of this clandestine creation is the versatile and powerful Arduino microcontroller. This guide will walk you through creating a high-quality Arduino voice recorder that automatically captures sound when it detects it, making it the perfect foundation for your own secret agent projects.

Why Build an Arduino Voice Recorder?

Before we dive into the schematics and components, let’s talk about why this project is so rewarding. Off-the-shelf voice recorders are convenient, but they lack the customization and learning potential of a DIY build. By creating your own Arduino voice recorder, you gain complete control over its functionality. You can tweak the sensitivity, adjust the recording quality, and modify its power consumption to suit your specific needs. More importantly, you’ll gain hands-on experience with core electronics concepts like audio processing, data storage on SD cards, and power management. It’s a fantastic project for hobbyists, students, and anyone curious about the magic behind everyday gadgets.


Arduino Spy Bug Voice Recorder: How Your Spy Bug Works

So, how do all these components work together to create an intelligent recording device? The process is a clever loop of listening, deciding, and recording.

  1. Silent Vigil: The Arduino is constantly powered on, running a sketch that continuously monitors the input from the microphone module. It’s in a state of silent vigil, listening for a sound that crosses a predefined threshold. This threshold is a crucial value that determines the sensitivity of your device.
  2. The Trigger: When the sound level in the room—be it a voice, a cough, or a door slamming—exceeds this threshold, the Arduino’s code springs into action. This is the “automatic sound detection” feature, and it’s what makes the device so hands-off and efficient.
  3. Capture and Encode: Once triggered, the Arduino begins sampling the audio from the microphone at a specific rate (e.g., 8kHz, which is great for voice). It converts these analog sound waves into digital data and formats them in real-time into a standard WAV file format.
  4. Saving the Evidence: The Arduino then communicates with the SD card module, saving the newly created WAV file with a sequential name like REC001.WAV, then REC002.WAV, and so on. This ensures your recordings are organized and won’t overwrite each other.
  5. Status and Standby: Throughout the 30-second recording, the LED indicator will blink, providing a visual cue that the device is active. Once the recording is complete, the Arduino saves the file, stops the recording process, and returns to its silent listening mode, ready for the next sound event.

Required Components

  • Arduino Nano
  • Electret Microphone Module (MAX4466, MAX9814, or similar with built-in amplifier)
  • SD Card Module (standard SPI interface)
  • MicroSD Card (formatted as FAT32, 2GB-32GB works best)
  • Push button (optional)
  • LED + 220Ω resistor
  • 9V battery + connector (for portable spy bug operation)

Circuit Diagram

Connect all the reuired components as shown in the below circuit diagram.

circuit diagram of ARDUINO VOICE RECORDER spy bug

SD Card Module to Arduino:

  • CS -> D10
  • MOSI -> D11
  • MISO -> D12
  • SCK -> D13
  • VCC -> 5V
  • GND -> GND

Microphone (MAX9814) to Arduino:

  • OUT -> A0
  • Vdd -> 5V
  • Gain -> 5V
  • GND -> GND

Button -> D2 (with 10K pulldown resistor)

LED -> D3 (with 220Ω resistor)


From Prototype to Professional: Elevate Your Spy Bug with PCBway

You’ve perfected the code, and your Arduino voice recorder works beautifully on the breadboard. But a true spy gadget can’t be a fragile jungle of wires. To transform your brilliant prototype into a polished, reliable, and discreet device, you need to move beyond the breadboard and bring your vision to life with professional manufacturing.

This is where your project deserves an upgrade, courtesy of PCBway. Stop worrying about loose connections and bulky layouts. With PCBway’s custom PCB manufacturing, you can convert your tangled circuit into a sleek, robust board designed specifically for your recorder. The result is a device that’s not only more reliable but also incredibly compact and easier to conceal.

But what about the perfect disguise? PCBway’s high-resolution 3D printing services let you design and create a custom, weatherproof enclosure that can blend seamlessly into any environment—from a simple box to a cleverly disguised object. For those who seek a truly polished finish without the manual labor, PCBway’s expert assembly services can populate your board with machine precision.

Why PCBWay Delivers Superior Results:

  • Reliability: Professionally assembled PCBs eliminate connection failures in critical security applications
  • Durability: Engineering-grade materials protect components from physical damage and wear
  • Clean Integration: Perfect alignment between electronic and mechanical elements
  • Streamlined Workflow: Single-source responsibility for both PCB and enclosure manufacturing

Take your voice recorder—and every future project—beyond the prototype. Bring your most ambitious ideas to life with the comprehensive manufacturing power by visiting PCBWAY.COM now.


Upload the program code

First, download and install the Arduino IDE from arduino.cc if you haven’t already. Once installed, connect your Arduino board to your computer using a USB cable and wait for the drivers to install automatically.

Open the Arduino IDE and paste the below Arduino Spy bug voice recorder code into the editor window. Before uploading, you need to configure two important settings: go to the Tools menu and select your board type (like Arduino Uno or Nano), then select the correct COM port where your Arduino is connected.

Finally, click the Upload button (the right-pointing arrow icon at the top of the IDE). The code will compile and upload to your Arduino, which takes about 10-30 seconds. You’ll see the TX/RX LEDs blinking on the board during this process. Once you see “Done uploading” at the bottom, your Arduino is programmed and ready to use! You can open the Serial Monitor (Tools → Serial Monitor) and set it to 9600 baud to see status messages from your voice recorder.

/*
 * ===================================================================
 *  Advanced Arduino Voice Recorder for Spy Bug (Circuitschools) V2
 * ===================================================================
 * 
 * Records audio to an SD card in 8-bit mono WAV format when sound is
 * detected or a button is pressed. This version includes critical fixes
 * and improvements for reliable, high-quality operation.
 * 
 * Key Improvements:
 * - Corrected audio sample conversion for clear, undistorted sound.
 * - Implemented a buffer for efficient SD card writing (no audio dropouts).
 * - Dynamic WAV header generation for flexible sample rates.
 * - Built-in threshold calibration for easy setup in any environment.
 * - Button debouncing for reliable manual triggers.
 * - Enhanced error handling during recording.
 */

#include <SD.h>
#include <SPI.h>

// --- Pin Definitions ---
const int micPin = A0;
const int buttonPin = 2;
const int ledPin = 3;
const int chipSelect = 10;

// --- Recording Parameters ---
const unsigned int sampleRate = 8000;       // 8kHz sample rate (good for voice). Can be increased to 16000.
const unsigned long recordingDuration = 30000; // 30 seconds per file (in milliseconds)
int threshold = 30;                         // Sound detection threshold. Will be auto-calibrated in setup().

// --- Audio Buffering for Performance ---
const int BUFFER_SIZE = 128; // A larger buffer is more efficient but uses more RAM
byte audioBuffer[BUFFER_SIZE];
int bufferIndex = 0;

// --- Button Debouncing Variables ---
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50; // 50ms debounce time
int lastButtonState = HIGH;
int buttonState;

// --- WAV File Header Structure ---
struct WAVHeader {
  char riff[4] = {'R', 'I', 'F', 'F'};
  unsigned long fileSize;
  char wave[4] = {'W', 'A', 'V', 'E'};
  char fmt[4] = {'f', 'm', 't', ' '};
  unsigned long fmtSize = 16;
  unsigned short audioFormat = 1; // PCM
  unsigned short numChannels = 1; // Mono
  unsigned long sampleRate_val;
  unsigned long byteRate;
  unsigned short blockAlign;
  unsigned short bitsPerSample = 8;
  char data[4] = {'d', 'a', 't', 'a'};
  unsigned long dataSize;
};

// --- Global State Variables ---
File audioFile;
WAVHeader header;
bool isRecording = false;
unsigned long recordingStartTime = 0;
int fileCounter = 0;
unsigned long sampleInterval;

void setup() {
  Serial.begin(9600);
  Serial.println("=== Advanced Arduino Voice Recorder ===");
  
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor
  
  // Initialize SD card
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println(" FAILED!");
    blinkError(2); // Blink 2 times for SD error
    while (1);
  }
  Serial.println(" OK.");

  // Calibrate the sound threshold based on ambient noise
  calibrateThreshold();

  // Initialize WAV header with correct values
  header.sampleRate_val = sampleRate;
  header.byteRate = sampleRate * header.numChannels * header.bitsPerSample / 8;
  header.blockAlign = header.numChannels * header.bitsPerSample / 8;

  // Calculate sample interval in microseconds for precise timing
  sampleInterval = 1000000 / sampleRate;

  // Find the next available file number
  fileCounter = findNextFileNumber();
  
  // Visual confirmation that setup is complete
  digitalWrite(ledPin, HIGH);
  delay(1000);
  digitalWrite(ledPin, LOW);
  
  Serial.println("Voice Recorder Ready!");
  Serial.print("Sound Threshold set to: ");
  Serial.println(threshold);
  Serial.println("Press button or make a sound to start recording.");
}

void loop() {
  // --- Debounce Button ---
  int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
    }
  }
  lastButtonState = reading;

  // --- Check for Triggers ---
  bool buttonPressed = (buttonState == LOW);
  bool soundDetected = detectSound();

  if ((buttonPressed || soundDetected) && !isRecording) {
    startRecording();
  }
  
  // --- Handle Recording ---
  if (isRecording) {
    recordAudio();
    
    // Stop recording after the set duration
    if (millis() - recordingStartTime >= recordingDuration) {
      stopRecording();
    }
  }
  
  delay(1); // Small delay to prevent loop from spinning too fast
}

void calibrateThreshold() {
  Serial.println("\n--- Calibrating Sound Threshold ---");
  Serial.println("Please be quiet for 5 seconds...");
  
  long peakToPeak = 0;
  unsigned long startTime = millis();
  int maxVal = 0;
  int minVal = 1024;

  while (millis() - startTime < 5000) { // Sample for 5 seconds
    int soundLevel = analogRead(micPin);
    if (soundLevel > maxVal) {
      maxVal = soundLevel;
    }
    if (soundLevel < minVal) {
      minVal = soundLevel;
    }
    delay(10);
  }
  
  peakToPeak = maxVal - minVal;
  // Set threshold slightly above the ambient noise peak-to-peak value
  threshold = peakToPeak / 2 + 10; // A simple heuristic, adjust as needed
  Serial.print("Calibration complete. Ambient peak-to-peak: ");
  Serial.print(peakToPeak);
  Serial.print(". Recommended Threshold: ");
  Serial.println(threshold);
  Serial.println("------------------------------------\n");
}

bool detectSound() {
  long peakToPeak = 0;
  unsigned long startTime = millis();
  int maxVal = 0;
  int minVal = 1024;

  // Sample for a short window (e.g., 50ms)
  while (millis() - startTime < 50) {
    int soundLevel = analogRead(micPin);
    if (soundLevel > 1023) soundLevel = 1023; // Clamp values
    if (soundLevel < 0) soundLevel = 0;
    
    if (soundLevel > maxVal) {
      maxVal = soundLevel;
    }
    if (soundLevel < minVal) {
      minVal = soundLevel;
    }
  }
  
  peakToPeak = maxVal - minVal;
  return (peakToPeak > threshold);
}

void startRecording() {
  isRecording = true;
  recordingStartTime = millis();
  bufferIndex = 0; // Reset buffer index
  
  String fileName = getFileName(fileCounter);
  Serial.print("Starting recording: ");
  Serial.println(fileName);
  
  audioFile = SD.open(fileName, FILE_WRITE);
  if (!audioFile) {
    Serial.println("Error: Could not open file for writing!");
    isRecording = false;
    blinkError(3); // Blink 3 times for file error
    return;
  }
  
  // Write a placeholder header. We'll update the size later.
  audioFile.write((byte*)&header, sizeof(header));
  
  digitalWrite(ledPin, HIGH); // Turn LED on to indicate recording
}

void recordAudio() {
  static unsigned long lastSampleTime = 0;
  unsigned long currentTime = micros();
  
  if (currentTime - lastSampleTime >= sampleInterval) {
    lastSampleTime = currentTime;
    
    // Read microphone value
    int audioValue = analogRead(micPin);
    
    // *** CRITICAL FIX: Correct Audio Conversion ***
    // Map the 10-bit ADC value (0-1023) to an 8-bit unsigned value (0-255)
    // The waveform is centered around 128 (the midpoint of 0-255).
    byte sample = (byte)(map(audioValue, 0, 1023, -128, 127) + 128);
    
    // Store sample in buffer
    audioBuffer[bufferIndex] = sample;
    bufferIndex++;
    
    // If buffer is full, write it to the SD card
    if (bufferIndex >= BUFFER_SIZE) {
      if (audioFile.write(audioBuffer, BUFFER_SIZE) != BUFFER_SIZE) {
        Serial.println("Error: SD card write failed!");
        stopRecording(); // Stop recording on failure
        return;
      }
      bufferIndex = 0;
    }
  }
}

void stopRecording() {
  if (!isRecording) return;
  
  isRecording = false;
  digitalWrite(ledPin, LOW); // Turn LED off
  
  // Write any remaining samples in the buffer to the file
  if (bufferIndex > 0) {
    audioFile.write(audioBuffer, bufferIndex);
  }
  
  // Update WAV header with the correct file sizes
  unsigned long totalDataSize = audioFile.size() - sizeof(header);
  header.dataSize = totalDataSize;
  header.fileSize = totalDataSize + sizeof(header) - 8;
  
  // Go back to the beginning of the file and write the correct header
  audioFile.seek(0);
  audioFile.write((byte*)&header, sizeof(header));
  
  audioFile.close();
  
  Serial.print("Recording stopped. File size: ");
  Serial.print(audioFile.size());
  Serial.println(" bytes");
  
  fileCounter++;
  
  // Blink LED 3 times to indicate successful completion
  for (int i = 0; i < 3; i++) {
    digitalWrite(ledPin, HIGH);
    delay(200);
    digitalWrite(ledPin, LOW);
    delay(200);
  }
}

String getFileName(int counter) {
  String fileName = "REC";
  if (counter < 10) fileName += "00";
  else if (counter < 100) fileName += "0";
  fileName += String(counter);
  fileName += ".WAV";
  return fileName;
}

int findNextFileNumber() {
  int i = 0;
  while (SD.exists(getFileName(i))) {
    i++;
  }
  return i;
}

void blinkError(int blinks) {
  while(true) {
    for (int i = 0; i < blinks; i++) {
      digitalWrite(ledPin, HIGH);
      delay(200);
      digitalWrite(ledPin, LOW);
      delay(200);
    }
    delay(2000); // Long pause between error sequences
  }
}

How to Use This Code

  1. Upload the Sketch: Connect your Arduino and upload this code.
  2. Open the Serial Monitor: After uploading, open the Serial Monitor (set to 9600 baud). You will see the initialization messages.
  3. Calibrate: The device will automatically run a 5-second calibration routine. During this time, be as quiet as possible. The device will listen to the ambient noise and calculate a suitable threshold value automatically. It will print the calculated value for you.
  4. Test: Once it says “Voice Recorder Ready!”, you can test it. Clap your hands or speak loudly near the microphone. The LED should turn on, and the Serial Monitor will confirm that a recording has started. It will automatically stop after 30 seconds.
  5. Listen: Remove the SD card from the module and insert it into your computer. You will find a REC000.WAV file (or similar) that you can play with any media player. The audio should be clear and correctly formatted.

Pro Tips to Optimize Your Spy Bug

Building the device is just the first step. To make it a truly effective tool, you need to fine-tune it for the field. Here are some professional tips to get the most out of your Arduino voice recorder.

  • Master the Threshold: The most critical adjustment you’ll make is the sound threshold value in the code (often found around line 45 of the sketch). This isn’t a one-size-fits-all setting. In a quiet environment like a library, you’ll need a very low threshold to pick up faint whispers. In a noisy office, you’ll need to raise it significantly to avoid recording small sounds like printer sounds and keyboard clatter. Experiment to find the perfect balance for your mission.
  • Extend Battery Life: A standard 9V battery is good for portability, but it won’t last forever under continuous use. For longer-term deployments, consider using a larger battery pack, like a holder for multiple AA batteries, or a rechargeable LiPo battery with a voltage regulator. You can also modify the code to put the Arduino into a deep sleep mode between recordings to conserve power.
  • The Art of Concealment: The best spy bug is the one that’s never seen. Think creatively about your enclosure. A small, weatherproof box is a good start, but you can get more creative. Consider hollowing out an old book, placing it inside a fake rock for outdoor surveillance, or concealing it within a tissue box. The small size of the Arduino Nano makes these creative enclosures very feasible.
  • Balance Quality and Size: The default sample rate of 8kHz is optimized for voice recording, creating relatively small files that are perfect for long-duration monitoring. If you need higher fidelity audio—for instance, to clearly record music—you can increase the sample rate to 16kHz. Be warned: this will double the size of your WAV files, meaning your SD card will fill up twice as fast. It’s a trade-off between quality and storage capacity.

By following this guide, you can transform a handful of components into a sophisticated and customizable Arduino voice recorder. It’s a project that perfectly blends the thrill of spy gadgetry with the tangible satisfaction of building something with your own hands. So gather your gear, fire up your soldering iron, and get ready to start your next covert mission.

 

Add a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *