Hello,
I am working on a project which calculates true RMS of an audio signal. I am using Arduino UNO+Seven segment display to achieve this.
I have defined prescalar to be 32 to achieve sampling frequency of 38.5kHz, and used fast read analog input ADCH instead of analogRead().
The results are not as desired when tested with sine wave and square wave of 10kHz(offset applied). It works fine for DC voltage input.
The code is as follows:
#include <DigitShield.h> // Includes header file for digit shield display
long x=0; // For calculating number of samples read
float RMS = 0 ; // Variable to store final result
float inputRead = 0 ; // Variable to read and store input samples
float sum = 0 ; // Variable to store and manipulate the samples
float voltage = 0 ;
void setup()
{
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
interrupts();//enable interrupts
DigitShield.begin(); // Initiate digit shield for displaying output value
Serial.begin(9600); // Initialize serial monitor
}
/*ISR(ADC_vect)
{//when new ADC value ready
inputRead = ADCH ;
}*/
void loop()
{
while(millis()<=10000)
{
inputRead = ADCH ;
voltage = inputRead * (5.0/255.0);
x++;
sum = sum + ((voltage*voltage));
}
RMS = sqrt(sum/x);
Serial.println(inputRead);
Serial.println(voltage); // Displays number of samples in serial monitor
Serial.println(sum);
Serial.println(x);
Serial.println(RMS); // Displays final result in serial monitor
Serial.println("\n");
if(RMS)
{
DigitShield.setValue(RMS); // Display the final RMS value
DigitShield.setPrecision(3);
}
}
Please look at attachments for test wave and serial monitor results.
Please help…