Go Down

Topic: How to get values from a speaker ? (Read 658 times) previous topic - next topic

sdimitri31

Hello,
I'm building a bluetooth speaker with an arduino and a bluetooth Amp,
I'm able to play music, but I have issues to understand how to get any value from the speaker to make an LED strip react to the sound.

I looked on many website to get informations on how can I make it, what I have learn is :
- Audio is an AC signal
- Arduino cannot work AC signal
- A Peak to Peak circuit seems to be what I need, but I didn't manage to make it work...


I'm beggining in hardware I know few things in theory but I never build anything else than connecting an arduino to a LED strip, I hope you can help me.

Thank you.

slipstick

There are many ways of allowing an Arduino to work with audio signals. Trying Googling "Arduino color organ". There are hundreds of them and they all react to audio either from a microphone or the input to a speaker/amplifier.

Or show us what you have tried and say what it does and doesn't do.

Steve


sdimitri31

Thanks for your answer

I tried to look for "Arduino color organ" on google but I found only with microphone or audio jack as inputs... If you found one with speaker input I would like to check it .

I put some pictures of what I've made in the attachements, I tried to make a peak-to-peak circuit like here but maybe I missunderstood something ?

For the software I used the code I found in this guide

Code: [Select]
#include <Adafruit_NeoPixel.h>

#define PIN 6


Adafruit_NeoPixel strip = Adafruit_NeoPixel(30, PIN, NEO_GRB + NEO_KHZ800);

const int sampleWindow = 10; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;
int maximum = 110;
int peak;
int dotCount;
#define PEAK_FALL 4  // Rate of peak falling dot

void setup()
{
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop()
{
   unsigned long startMillis= millis();  // Start of sample window
   unsigned int peakToPeak = 0;   // peak-to-peak level

   unsigned int signalMax = 0;
   unsigned int signalMin = 100;

   // collect data for 50 mS
   while (millis() - startMillis < sampleWindow)
   {
      sample = analogRead(6)*2;
      if (sample < 1024)  // toss out spurious readings
      {
         if (sample > signalMax)
         {
            signalMax = sample;  // save just the max levels
         }
         else if (sample < signalMin)
         {
            signalMin = sample;  // save just the min levels
         }
      }
   }
   peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
   
   int led = map(peakToPeak, 0, maximum, 0, strip.numPixels()) -1;
   
   for(int i; i <= led; i++)
   {
     int color = map(i, 0, strip.numPixels(), 0, 255);
     strip.setPixelColor(i, Wheel(color));
     
   }
   
   for(int i = strip.numPixels() ; i > led; i--)
   {
     strip.setPixelColor(i, 0);
     
   }
  strip.show();
 
  if(led > peak)  peak = led; // Keep 'peak' dot at top
   
   if(peak > 0 && peak <= strip.numPixels()-1) strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,0,255)));

   strip.show();
   
// Every few frames, make the peak pixel drop by 1:

    if(++dotCount >= PEAK_FALL) { //fall rate
     
      if(peak > 0) peak--;
      dotCount = 0;
    }
   
}

uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else if(WheelPos < 170) {
    WheelPos -= 85;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  }
}

void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}


For now the LED strip is just flickering in the middle no matter how loud the sound is...

MarkT

Still an audio signal going into a speaker, just lower impedance.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Grumpy_Mike

#4
Nov 25, 2018, 10:37 pm Last Edit: Nov 25, 2018, 10:40 pm by Grumpy_Mike
Quote
I tried to make a peak-to-peak circuit
Lets get the terminology right. What that circuit is, is a peak detector or envelope follower. It only follows positive peaks, nothing to do with peak to peak.

Quote
- Arduino cannot work AC signal
Not true. An Arduino can only manage positive voltages not negitave ones. But if you add a DC bias to the AC signal then the Arduino is quite happy handling one. You make this DC bias circuit with two resistors and a capacitor.

Quote
tried to make a peak-to-peak circuit like here but maybe I missunderstood something ?
Yes you did. You have not got a common ground between your audio source and the rest of the circuit.

It is quite a poor page, apart from getting the name of the circuit wrong, you don't need that diode to ground, also there is no resistor across the capacitor on the right to control the discharge time. Better circuit is here:- https://en.wikipedia.org/wiki/Envelope_detector

sdimitri31

Thank you for your help Grumpy_Mike

This is the envelope detector :


But I don't understand how to use it.
What are the two areas that I have circled into my circuit?


And how do I choose the values of the resistor and the capacitor ?

Grumpy_Mike

#6
Nov 26, 2018, 04:37 pm Last Edit: Nov 26, 2018, 04:38 pm by Grumpy_Mike
The area on the left is your audio input, connect it to your audio source. You have to have an audio in excess of 0.7V peak for it to start to work. The area in the right is your envelope output, connect that to the analogue input of your Arduino.

Make the capacitor 0.1uF and the resistor 10 K play about with these values until you get the responsiveness you want. The resistor controls the decay, and the capacitor controls the speed of following. They are not critical.

sdimitri31

So I have to connect it like that ?

MarkT

Yes, and you can add 10k output resistor to protect the Arduino pin from overvoltage, probably wise.

A schottky diode will reduce that 0.7V excess to around 0.4V if that helps, they have lower forward
voltages.

Adding 100 ohms or so input resistor would reduce any audible artifacts that this circuit might
produce in the speaker (limit the inrush current spikes).
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

sdimitri31

Thank you for your answer, sorry I couldn't work on this project since last week.

The circuit seems to work, but the arduino is acting weirdly,
when there is nothing connected to A0 and GND the analogread() give me random values between 0 and 5V,
if I use my multimeter on it, the arduino stop reading random and give me 0V this seems legit,
but if I connect the circuit to the arduino I still get 0 with analogread() but with the voltmeter I get values different from 0V.

Any ideas of what is going on ?

Grumpy_Mike

Quote
when there is nothing connected to A0 and GND the analogread() give me random values between 0 and 5V,
That is perfectly normal. It is known as a floating input. It is picking up radio interference.

Adding your multimeter is pulling the input down and so that is stopping it from picking up interference.

A multimeter might be more sensitive that the analogue input. You need at least 4.5mV to register an analogue  reading of one.

namirarahman

The area on the left is your audio input, connect it to your audio supply. you have got to own AN audio in more than zero.7V peak for it to start out to figure. the world within the right is your envelope output, connect that to the analogue input of your Arduino.

Make the condenser zero.1uF and therefore the resistance ten K play regarding with these values till you get the responsiveness you wish. The resistance controls the decay, and therefore the condenser controls the speed of following. they're not crucial.for more if you want to know about forex trading perfectly and want to make money from here then read this https://bit.ly/2E82mst

Go Up