Analog pins give random values?

I bought a new Arduino because my previous one's analog pins started giving weird values. Unfortunately, this one has a similar issue, because even with nothing connected to the analog pins, they still return a count of around 276.

To provide more information, when the pins are connected to 5V, the value is 1023, when connected to GND, it's 0, and when connected to 3.3v, the value is around 667.

The ADC inputs are working correctly. When nothing is connected they are "floating" and will give spurious readings due to electrical charge picked up from the environment.

Connect the inputs to a voltage source within permissible limits before taking readings, and don't forget to connect the grounds.

3 Likes

I plan on using it with an audio sensor called MAX9814. I connected the 5V, GND, and A0 to it, but the A0 still returns somewhere around 260. Here's a photo if it helps.

If the pin is not connected to anything, the reading is meaningless.

If it is connected to something, check whether the reading is correct by measuring the voltage at the pin with your multimeter.

I can't make any sense out of the photo. Post a hand drawn wiring diagram instead, with all pins, parts and connections clearly labeled.

Unfortunately I don't have a multimeter. Here's a diagram.

Without a multimeter, why would you disbelieve the analog reading?

What has your research led you to expect from that audio sensor?

Post a link to the product page or data sheet for the module, and describe how you intend to use it.

I searched for "arduino max9814" and this is the first hit that came up:

The comment in yellow outline explains what to expect:

1024*(1.25V/5V) = 256, so your ADC input is working as expected.

Perhaps check the analog by connecting a pot or even resistors to make a voltage divider to it.

You must test and not assume.

If you decide to try the code from the tutorial linked in post #8, use a more sensible Serial baud rate like 115200 and set the serial monitor/serial plotter to the same rate.

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  }
1 Like

Running this returns a flickering steam around 250, going at it's lowest to 230 and at it's highest to 270. Shouting into the mic makes it go between exactly 500 at the highest and exactly 0 at the lowest. How should I change these values to get what I want? I'm trying to make a robot that takes the frequency from the mic and uses it to move and turn with 4 motors. here's the code:

#include "arduinoFFT.h"

#define SAMPLES 128             //SAMPLES-pt FFT. Must be a base 2 number. Max 128 for Arduino Uno.
#define SAMPLING_FREQUENCY 2048 //Ts = Based on Nyquist, must be 2 times the highest expected frequency.
 
double vReal[SAMPLES]; //create vector of size SAMPLES to hold real values
double vImag[SAMPLES]; //create vector of size SAMPLES to hold imaginary values

ArduinoFFT<double> FFT = ArduinoFFT<double>(vReal, vImag, SAMPLES, SAMPLING_FREQUENCY);
 
unsigned int samplingPeriod;
unsigned long microSeconds;
int BL = 11;
int TL =12;
int BR = 9;
int TR = 8;
void setup() 
{
    Serial.begin(115200); //Baud rate for the Serial Monitor
    samplingPeriod = round(1000000*(1.0/SAMPLING_FREQUENCY)); //Period in microseconds 
    pinMode(BL,OUTPUT);
    pinMode(TL,OUTPUT);
    pinMode(BR,OUTPUT);
    pinMode(TR,OUTPUT);
}

void loop() 
{  
    /*Sample SAMPLES times*/
    for(int i=0; i<SAMPLES; i++)
    {
        microSeconds = micros();    //Returns the number of microseconds since the Arduino board began running the current script. 
     
        vReal[i] = analogRead(A0); //Reads the value from analog pin 0 (A0), quantize it and save it as a real term.
        vImag[i] = 0; //Makes imaginary term 0 always

        /*remaining wait time between samples if necessary*/
        while(micros() < (microSeconds + samplingPeriod))
        {
          //do nothing
        }
    }
/*Perform FFT on samples*/
    FFT.windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.complexToMagnitude(vReal, vImag, SAMPLES);

/*Find peak frequency and print peak*/
    double peak = FFT.majorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY); 
    Serial.println(peak);
    Serial.println(analogRead(A0));
    if (peak<200){
      digitalWrite(BL, LOW);
      digitalWrite(TL, LOW);
      digitalWrite(BR, LOW);
      digitalWrite(TR, LOW);
    }
    if ((peak>230 and peak<245) || (peak>465 and peak<510)){
      Serial.println("C");
      digitalWrite(BL, HIGH);
      digitalWrite(TL, HIGH);
      digitalWrite(BR, HIGH);
      digitalWrite(TR, HIGH);
    }

    if ((peak>250 and peak<280) || (peak>510 and peak<540)){
      Serial.println("D");
      digitalWrite(BL, LOW);
      digitalWrite(TL, LOW);
      digitalWrite(BR, HIGH);
      digitalWrite(TR, HIGH);
    }

    if ((peak>285 and peak<310) || (peak>560 and peak<610)){
      Serial.println("E");
      digitalWrite(BL, HIGH);
      digitalWrite(TL, HIGH);
      digitalWrite(BR, HIGH);
      digitalWrite(TR, HIGH);
    }

    if ((peak>310 and peak<330) || (peak>610 and peak<650)){
      Serial.println("F");
      digitalWrite(BL, HIGH);
      digitalWrite(TL, HIGH);
      digitalWrite(BR, LOW);
      digitalWrite(TR, LOW);
    }

    if ((peak>345 and peak<360) || (peak>700 and peak<770)){
      Serial.println("G");
      digitalWrite(BL, HIGH);
      digitalWrite(TL, HIGH);
      digitalWrite(BR, HIGH);
      digitalWrite(TR, HIGH);
    }
    
    if ((peak>380 and peak<410) || (peak>790 and peak<900)){
      Serial.println("A");
      digitalWrite(BL, HIGH);
      digitalWrite(TL, HIGH);
      digitalWrite(BR, LOW);
      digitalWrite(TR, LOW);
    }

    if ((peak>200 and peak<230) || (peak>430 and peak<460)){
      Serial.println("B");
      digitalWrite(BL, LOW);
      digitalWrite(TL, LOW);
      digitalWrite(BR, HIGH);
      digitalWrite(TR, HIGH);
    }
}

Start with just a sketch that determines frequency and maybe don't substitute volume for frequency.

@GoForSmoke I got that part of the code from this video:

The person in the video also used a similar audio sensor that senses volume if you put in something like the code in post #8 . Admittedly, I don't know why it turns to frequency rather than volume (but it's probably something in the FFT library). I used to use the KY-037 in the video but it had very low sensitivity and required me to play very loudly on my trumpet to hear the pitch (but it DID work). I got the MAX9814 because it's description mentioned that it had an auto-gain system, making quieter things louder. I figured it would work the same and I can't tell why not.

The board you show is an Arduino Uno so why did you post this in the Opta category of the forum?

Topic moved to a more suitable location on the forum.

Oh, sorry, thank you! I just meant to put it under "official hardware", the Opta part was an acccident.

You should AC couple the sound signal to the analogue input, and then DC bias the signal to the mid point of the supply with a pull up and pull down resistor of about 100K.
Like this diagram.

This plot shows four analogue inputs being read in turn, with one pin unconnected, see how the residual charge on the sampling A/D capacitor follows the previous channel, and what happens when you touch the pin, thus injecting pick up noise.


Make it go without the motor, first.
Do not add complication until you get that right.

Do all of your programming that way just to cut a chunk of your life spent debugging. The extra code is extra weight and time to drag along. If you keep at it, you will see this sooner or later.

Thank you, I agree. I have been working without the motors as of current, I just included them to explain the full project. It basically breaks down to a tuner and some motors, and I'm trying to get the tuner part down right now.

You can get a inexpensive one for under $10.00 from your favorite china supplier.

Or your local thrift shop.

1 Like