82 views|0 replies

29

Posts

0

Resources
The OP
 

【Follow me Season 2 Episode 4】Advanced Task 1: Displaying MIC amplitude using LED color [Copy link]

 
Prerequisites
Energy detection is probably the simplest algorithm in audio. Its calculation logic is:
energy = sqrt((a0 * a0 + a1 * a1 + ... + an * an) / (n + 1))
Principle Analysis
After the previous part of recording and printing the signal with the mic, we can get the following information through the waveform. In the Arduino Nano RP2040 Connect, the audio processing accuracy is 16 bits, which means that including the sign bit, the distortion value is between 32767 and -32768.
After analyzing the above function and combining it with the mic signal range, the energy information we finally calculated should be between 0 and 32767. If we need to convert it into PWM between 0 and 255, it is very simple. We just need to shift the data to the right by 7 bits (if it is a fixed-point number).
Then customize the interaction logic to adjust the brightness of three different lamp beads.
Software Coding
Based on the above analysis, I used floating point numbers to calculate the energy (just to prevent data overflow, in fact, the m0+ core of 2040 does not support floating point operations). After the calculation, the floating point number is converted into the duty cycle information of 0~255 of the pwm light, and then the red and green lights are controlled separately according to a certain logic (the reason why the blue light is not controlled is that without the light cover, three lights really cannot produce any effect, but two lights can show changes through the fingernail).
#include <WiFiNINA.h>
#include <PDM.h>

static const char channels = 1;
static const int frequency = 16000;
short sampleBuffer[512];
volatile int samplesRead;

void setup() {
 //pinMode(LEDB, OUTPUT);
 pinMode(LEDR,OUTPUT);
 pinMode(LEDG,OUTPUT);
 analogWrite(LEDR,255);
 analogWrite(LEDG,255);
 Serial.println("Hello DigiKey & EEWorld!");
 Serial.println();
 Serial.begin(9600);
 while (!Serial);
 PDM.onReceive(onPDMdata);
 if (!PDM.begin(channels, frequency)) {
  Serial.println("Failed to start PDM!");
  while (1);
 }
}

void rgbledShow(float level) {
  unsigned short value = level / 128;
  unsigned char r,g,b;
  Serial.print("value : ");
  Serial.print(value);
  Serial.print(" level: ");
  Serial.println(level);
  r = value;
  g = 255 - value;
  analogWrite(LEDR,r);
  analogWrite(LEDG,g);
}

void micHandle() {
 float level = 0;
 if (samplesRead) {
  for (int i = 0; i < samplesRead; i++) {
   level += (sampleBuffer[i] * sampleBuffer[i]);
  }
  level /= samplesRead;
  level = sqrt(level);
  rgbledShow(level);
  samplesRead = 0;
 }
}

void loop() {
  micHandle();
}

void onPDMdata() {
 // Query the number of available bytes
 int bytesAvailable = PDM.available();
 PDM.read(sampleBuffer, bytesAvailable);
 samplesRead = bytesAvailable / 2;
}

Summarize

Here, we have reviewed the common practices in audio processing again. If necessary, we can further experiment with gadgets like USB mic, but I am not sure whether Arduino supports this.

This post is from DigiKey Technology Zone
 
 

Guess Your Favourite
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list