【雕爷学编程】Arduino动手做(149)---MAX9814咪头传感器模块7

发布时间 2023-07-14 12:43:46作者: 行者花雕

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十二:Adafruit_NeoPixel库的音乐可视化环灯

  Arduino实验开源代码

 

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

 项目五十二:Adafruit_NeoPixel库的音乐可视化环灯

*/

#include <Adafruit_NeoPixel.h>

#define MIC A0 // 麦克风与A0相连接

#define LED_PIN 6 // LED are connected to D6

#define N_PIXELS 12 // Number of LED 

#define N 100 //样本数 

#define fadeDelay 10 // 淡出量

#define noiseLevel 15 // 降噪下限

Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

int samples[N]; // 存储样本

int periodFactor = 0; // 用于周期计算

int t1 = -1;

int T;

int slope;

byte periodChanged = 0;

void setup() {

 // Serial.begin(9600);

 strip.begin();

 ledsOff();

 delay(500);

 displayColor(Wheel(100));

 strip.show();

 delay(500);

}

void loop() {

 Samples();

}

void Samples() {

 for (int i = 0; i < N; i++) {

  samples[i] = analogRead(0);

  if (i > 0) {

   slope = samples[i] - samples[i - 1];

  }

  else {

   slope = samples[i] - samples[N - 1];

  }

  if (abs(slope) > noiseLevel) {

   if (slope < 0) {

    calculatePeriod(i);

    if (periodChanged == 1) {

     displayColor(getColor(T));

    }

   }

  }

  else {

   ledsOff();

  }

  periodFactor += 1;

  delay(1);

 }

}

void calculatePeriod(int i) {

 if (t1 == -1) {

  t1 = i;

 }

 else {

  int period = periodFactor * (i - t1);

  periodChanged = T == period ? 0 : 1;

  T = period;

  // Serial.println(T);

  t1 = i;

  periodFactor = 0;

 }

}

uint32_t getColor(int period) {

 if (period == -1)

  return Wheel(0);

 else if (period > 400)

  return Wheel(5);

 else

  return Wheel(map(-1 * period, -400, -1, 50, 255));

}

void fadeOut()

{

 for (int i = 0; i < 5; i++) {

  strip.setBrightness(110 - i * 20);

  strip.show(); // Update strip

  delay(fadeDelay);

  periodFactor += fadeDelay;

 }

}

void fadeIn() {

 strip.setBrightness(100);

 strip.show();

 for (int i = 0; i < 5; i++) {

  //strip.setBrightness(20*i + 30);

  //strip.show();

  delay(fadeDelay);

  periodFactor += fadeDelay;

 }

}

void ledsOff() {

 fadeOut();

 for (int i = 0; i < N_PIXELS; i++) {

  strip.setPixelColor(i, 0, 0, 0);

 }

}

void displayColor(uint32_t color) {

 for (int i = 0; i < N_PIXELS; i++) {

  strip.setPixelColor(i, color);

 }

 fadeIn();

}

uint32_t Wheel(byte WheelPos) {

 // Serial.println(WheelPos);

 if (WheelPos < 85) {

  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);

 }

 else if (WheelPos < 170) {

  WheelPos -= 85;

  return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);

 }

 else {

  WheelPos -= 170;

  return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);

 }

}

  

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十二:Adafruit_NeoPixel库的音乐可视化环灯


实验视频剪辑

https://v.youku.com/v_show/id_XNTgxMTg4NTQzMg==.html?spm=a2hcb.playlsit.page.1

实验场景 动态图

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十三:十六位直条WS2812音乐可视化柱灯

  Arduino实验开源代码

 

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

 项目五十三:十六位直条WS2812音乐可视化柱灯

*/

#include <Adafruit_NeoPixel.h>

#define N_PIXELS 16 // Number of pixels in strand

#define MIC_PIN  A0 // Microphone is attached to this analog pin

#define LED_PIN  6 // NeoPixel LED strand is connected to this pin

#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0

#define NOISE   300 // Noise/hum/interference in mic signal

#define SAMPLES  50 // Length of buffer for dynamic level adjustment

#define TOP    (N_PIXELS + 2) // Allow dot to go slightly off scale

#define PEAK_FALL 60 // Rate of peak falling dot

byte

peak   = 0,   // Used for falling dot

dotCount = 0,   // Frame counter for delaying dot-falling speed

volCount = 0;   // Frame counter for storing past volume data

int

vol[SAMPLES],    // Collection of prior volume samples

  lvl    = 100,   // Current "dampened" audio level

  minLvlAvg = 0,   // For dynamic adjustment of graph low & high

  maxLvlAvg = 512;

Adafruit_NeoPixel

strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

 // This is only needed on 5V Arduinos (Uno, Leonardo, etc.).

 // Connect 3.3V to mic AND TO AREF ON ARDUINO and enable this

 // line. Audio samples are 'cleaner' at 3.3V.

 // COMMENT OUT THIS LINE FOR 3.3V ARDUINOS (FLORA, ETC.):

  

 analogReference(EXTERNAL);

 memset(vol, 0, sizeof(vol));

 strip.setBrightness(66);

 strip.begin();

}

void loop() {

 uint8_t i;

 uint16_t minLvl, maxLvl;

 int   n, height;

 n  = analogRead(MIC_PIN);  // Raw reading from mic

 n  = abs(n - 512 - DC_OFFSET); // Center on zero

 n  = (n <= NOISE) ? 0 : (n - NOISE);       // Remove noise/hum

 lvl = ((lvl * 7) + n) >> 3;  // "Dampened" reading (else looks twitchy)

 // Calculate bar height based on dynamic min/max levels (fixed point):

 height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);

 if (height < 0L)    height = 0;   // Clip output

 else if (height > TOP) height = TOP;

 if (height > peak)   peak  = height; // Keep 'peak' dot at top

 // Color pixels based on rainbow gradient

 for (i = 0; i < N_PIXELS; i++) {

  if (i >= height)        strip.setPixelColor(i,  0,  0, 0);

  else strip.setPixelColor(i, Wheel(map(i, 0, strip.numPixels() - 1, 30, 150)));

 }

 // Draw peak dot

 if (peak > 0 && peak <= N_PIXELS - 1) strip.setPixelColor(peak, Wheel(map(peak, 0, strip.numPixels() - 1, 30, 150)));

 strip.show(); // Update strip

 // Every few frames, make the peak pixel drop by 1:

 if (++dotCount >= PEAK_FALL) { //fall rate

  if (peak > 0) peak--;

  dotCount = 0;

 }

 vol[volCount] = n;           // Save sample for dynamic leveling

 if (++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter

 // Get volume range of prior frames

 minLvl = maxLvl = vol[0];

 for (i = 1; i < SAMPLES; i++) {

  if (vol[i] < minLvl)   minLvl = vol[i];

  else if (vol[i] > maxLvl) maxLvl = vol[i];

 }

 // minLvl and maxLvl indicate the volume range over prior frames, used

 // for vertically scaling the output graph (so it looks interesting

 // regardless of volume level). If they're too close together though

 // (e.g. at very low volume levels) the graph becomes super coarse

 // and 'jumpy'...so keep some minimum distance between them (this

 // also lets the graph go to zero when no sound is playing):

 if ((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;

 minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels

 maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)

}

// Input a value 0 to 255 to get a color value.

// The colors are a transition r - g - b - back to r.

uint32_t Wheel(byte WheelPos) {

 if (WheelPos < 85) {

  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);

 } else if (WheelPos < 170) {

  WheelPos -= 85;

  return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);

 } else {

  WheelPos -= 170;

  return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);

 }

}

  

Arduino实验场景图

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十三:十六位直条WS2812音乐可视化柱灯


实验视频剪辑

https://v.youku.com/v_show/id_XNTgxMTkwNjMwNA==.html?spm=a2hcb.playlsit.page.1

实验场景动态图

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十四:八段分频8X8点阵屏的音乐频谱灯

  Arduino实验开源代码

 

/*

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

 项目五十四:八段分频8X8点阵屏的音乐频谱灯

接脚连线:MAX9814 接A0

MAX7219 UNO

VCC →→→→→ 5V

GND →→→→→ GND

DIN →→→→→ D12(数据,数据接收引脚)

CS →→→→→ D11(负载,命令接收引脚)

CLK →→→→→ D10(时钟,时钟引脚)

*/

#include "LedControl.h"

/* Led matrix - Max7219 Declared */

LedControl lc = LedControl(12, 11, 10, 1);

const int maxScale = 11;

/* Sensor - Max9812 Declared */

const int sensorPin = A4;

const int sampleWindow = 50; // 50ms = 20Hz

unsigned int sample;

unsigned long startMillis;

unsigned long timeCycle;

unsigned int signalMax = 0;

unsigned int signalMin = 1024;

unsigned char index = 0;

unsigned int peakToPeak[8];

unsigned int displayPeak[8];

unsigned int temp[8]={0,0,0,0,0,0,0,0};

unsigned int signalMaxBuff[8];

unsigned int signalMinBuff[8];

void setup() {

// Led matrix

lc.shutdown(0, false); // bật hiện thị

lc.setIntensity(0, 1); // chỉnh độ sáng

lc.clearDisplay(0); // tắt tất cả led

Serial.begin(9600);

}

void loop() {

startMillis = millis();

//peakToPeak = 0;

signalMax = 0;

signalMin = 1024;

// Get data in 50ms

while (millis() - startMillis < sampleWindow) {

sample = analogRead(sensorPin);

if (sample < 1024) {

if (sample > signalMax) {

signalMax = sample;

}

if (sample < signalMin) {

signalMin = sample;

}

}

// 20Hz - 64Hz - 125Hz - 250Hz - 500Hz - 1kHz (timeCycle = 1/F)(ms)

timeCycle = millis() - startMillis;

if (timeCycle == 1 || timeCycle == 2 || timeCycle == 4 || timeCycle == 8

|| timeCycle == 16 || timeCycle == 32 || timeCycle == 40 || timeCycle == 50) {

signalMaxBuff[index] = signalMax;

signalMinBuff[index] = signalMin;

index = (index + 1) % 8;

delay(1);

//Serial.println(timeCycle);

}

}

// Delete pointer to array

index = 0;

// Calculation after get samples

for (int i = 0; i < 8; i++) { // i = row (led matrix)

// sound level

peakToPeak[i] = signalMaxBuff[i] - signalMinBuff[i];

// Map 1v p-p level to the max scale of the display

displayPeak[i] = map(peakToPeak[i], 0, 1023, 0, maxScale);

// Show to led matrix

displayLed(displayPeak[i], i);

// Led drop down

if (displayPeak[i] >= temp[i]) {

temp[i] = displayPeak[i];

}

else {

temp[i]--;

}

lc.setLed(0, i, temp[i], true);

delayMicroseconds(250);

}

}

void displayLed(int displayPeak, int row) {

switch (displayPeak) {

case 0 : lc.setRow(0, row, 0x80); break;

case 1 : lc.setRow(0, row, 0xC0); break;

case 2 : lc.setRow(0, row, 0xE0); break;

case 3 : lc.setRow(0, row, 0xF0); break;

case 4 : lc.setRow(0, row, 0xF8); break;

case 5 : lc.setRow(0, row, 0xFC); break;

case 6 : lc.setRow(0, row, 0xFE); break;

case 7 : lc.setRow(0, row, 0xFF); break;

}

}

  Arduino实验场景图

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

实验一百四十九:MAX9814麦克风放大器模块 MIC话筒声音放大/咪头传感器

项目五十四:八段分频8X8点阵屏的音乐频谱灯

实验视频剪辑

https://v.youku.com/v_show/id_XNTgxMjY3Nzc4MA==.html?firsttime=0

实验场景动态图