How to refer to the built in microphone?

@noweare This is very handy to know for the next phase, thank you!

@rsmls I don't understand how to implement this concept. The basic principle is that a state is changed based on the input, but there is input continuously. Or do you mean I should give one function the lead and run it when needed, and only run the other function when the lead function isn't running?

Why do you think that is a problem?

Read input(s), make state change decisions.

So I have this now. At least there is data coming in, only it doesn't look like audio data.

Current code:

// Main tab =======================================================--
#include <PDM.h>
#include <Arduino_HS300x.h>
#include <SD.h>
#include <SPI.h>

float temperature;
float humidity;

void setup() {
  Serial.begin(9600);
  while (!Serial);
  PDM.setBufferSize(2048);  //bytes!

initializeSDCard();

  if (!HS300x.begin()) {
    Serial.println("Failed to initialize humidity temperature sensor!");
    while (1);
  }
}

void loop() {
  Serial.println("run loop");
  temperature = HS300x.readTemperature();
  humidity    = HS300x.readHumidity();
  recordAudio();
  delay(99999999);
}

// Record audio tab =================================================

// Define constants
const int sampleRate = 16000;
const int sampleBufferSize = 8192;

// Declare buffers
int16_t sampleBuffer[sampleBufferSize];
uint8_t cpBuffer[sampleBufferSize * 2]; // 2 bytes per sample
volatile int audioSamplesRead = 0;
volatile int totalAudioSamplesRead = 0;

void recordAudio() {
  Serial.println("Try to record audio");
  totalAudioSamplesRead = 0;

  PDM.onReceive(onPDMdata);
  if (!PDM.begin(1, sampleRate)) {
    Serial.println("Failed to start PDM!");
    while (1);
  } else {
    Serial.println("PDM started successfully.");
  }

  while (totalAudioSamplesRead < 8000) {
    if (audioSamplesRead > 0) {
      Serial.print("TotalAudioSamplesRead: ");
      Serial.println(totalAudioSamplesRead);
      Serial.print("AudioSamplesRead: ");
      Serial.println(audioSamplesRead);

      for (int i = 0; i < audioSamplesRead; i++) {
        cpBuffer[2 * i] = (sampleBuffer[i] >> 8) & 0xFF;
        cpBuffer[2 * i + 1] = sampleBuffer[i] & 0xFF;
      }

      totalAudioSamplesRead += audioSamplesRead;
      audioSamplesRead = 0;
    }
  }
  PDM.end();
  processAudio();
}

void onPDMdata() {
  // Query the number of bytes available
  int bytesAvailable = PDM.available();

  // Read into the sample buffer
  PDM.read(sampleBuffer, bytesAvailable);

  // Update the number of samples read
  audioSamplesRead = bytesAvailable / 2; // 16-bit, 2 bytes per sample
}

void processAudio(){
  sendValues();
}

// Send values tab ================================================

void sendValues(){
  Serial.println("Sending values...");
  Serial.print("Temperature: ");
  Serial.println(temperature);
  Serial.print("Humidity: ");
  Serial.println(humidity);
  Serial.println("Audio 16 bit: ");
  for (int i = 0; i < sizeof(sampleBuffer);i++){
    Serial.print(" ");
    Serial.print(sampleBuffer[i]);
  }
  Serial.println("");
  Serial.println("Audio 8 bit: ");
  for (int i = 0; i < sizeof(cpBuffer);i++){
    Serial.print(" ");
    Serial.print(cpBuffer[i]);
  }
  Serial.println();
}

// Functions tab =================================================

void initializeSDCard(){
  #define SD_CSPin 10

  int file_number = 0;
  char filePrefixname[50] = "buzz";
  char exten[10] = ".wav";


  Serial.println("loading... SD card");
  if (!SD.begin(SD_CSPin)) {
            Serial.println("An Error has occurred while mounting SD");
  }
  while (!SD.begin(SD_CSPin)) {
            Serial.print(".");
            delay(500);
  }
}

Output:

16:36:24.358 -> AudioSamplesRead: 1024
16:36:24.425 -> TotalAudioSamplesRead: 2048
16:36:24.425 -> AudioSamplesRead: 1024
16:36:24.518 -> TotalAudioSamplesRead: 3072
16:36:24.518 -> AudioSamplesRead: 1024
16:36:24.553 -> TotalAudioSamplesRead: 4096
16:36:24.553 -> AudioSamplesRead: 1024
16:36:24.619 -> TotalAudioSamplesRead: 5120
16:36:24.619 -> AudioSamplesRead: 1024
16:36:24.702 -> TotalAudioSamplesRead: 6144
16:36:24.702 -> AudioSamplesRead: 1024
16:36:24.742 -> TotalAudioSamplesRead: 7168
16:36:24.773 -> AudioSamplesRead: 1024
16:36:24.773 -> Sending values...
16:36:24.773 -> Temperature: 25.57
16:36:24.773 -> Humidity: 56.85
16:36:24.773 -> Audio 16 bit: 
16:36:24.773 ->  298 305 296 286 291 304 301 296 298 295 295 298 303 293 290 ...
16:36:28.521 -> Audio 8 bit: 
16:36:28.521 ->  1 42 1 49 1 40 1 30 1 35 1 48 1 45 1 40 1 42 1 39 1 39 1 42 1 ...

The 16 bit (source for 8 bit) audio has strange values; the 8192 samples can be divided in these groups:

  • The first part contains samples that are pretty stable around 330, slowly decreasing to around 70
  • The middle part contains mainly zeros with here and there a small bunch of other samples
  • The last part contains only value -13108

When I reset the Arduino I get approximately the same over and over. When I run the example code called PDMSerialPlotter, I get audio-like values from around -40 to 40 that increase when I make noise, so the mic seems to work fine. Any ideas how to get real audio data?

What is the above supposed to be doing, and why?

Maybe I am making it too difficult in my head.
Basically the onPDMdata() function copies the recorded data to the sample buffer. Because of the few seconds that I have to record, I could maybe even stop recording after a timeout and handle the recording then.
Like:

 PDM.onReceive(onPDMdata); 
 if (!PDM.begin(1, sampleRate)) { // Initialize PDM with 1 channel (mono) and the specified sample rate
    Serial.println("Failed to start PDM!");
    while (1);
  } else {
    Serial.println("PDM started successfully.");
  }
  delay(1000);
  PDM.end;
  processAudio();

Please answer the question.

I posted a complete, working example showing how to collect and store a short bit of PDM audio. Did you even look at it, or make any effort to understand the code?

I found that on the forum ; it is to convert 16 bit audio to 8 bit to store it on a SD.
My problem for now is before that conversion already, that strange data is recorded.

In that forum post, the OP is asking why the code doesn't work as expected, and did not get an answer. So it was not a good example to follow.

The code you copied swaps bytes (for some unknown reason), and makes nonsense of the data.

What question do you mean?
Yes I did the effort. While it is nice that the shared example works, I try to make a more lean program than this; this solution depends on a heavy library with lots of dependencies where most code will not be used. Besides, I am first focussing on recording data, and planned to dive into storing it on SD later. I try different paths and improve step by step, and along the road learn from it.

No, the basic principle is that the system has a pre-determined number of well-defined states, and that the logic for switching between these states is equally well-defined and in line with the system requirement. This doesn't mean that state changes occur necessarily based on a momentary input. They can also be triggered by a certain amount of time passing, a sequence of inputs, data being fed to the controller through some kind of interface etc.

The one you attempted to answer in post #29 above, but failed.

Good luck with your project!