I have a basic code about reading true rms.I compiled the same code with arduino ide and atmel studio, then ran it in a proteus simulation.I'm trying to measure how long the read_rms() function takes.
My mcu:attiny84
1.experiment)I have added board to arduino ide with board manager.And I chose attiny84 and internal 1Mhz from tools menu in arduino menu. The result was that the read_rms() function took 23.25 milliseconds.
2.experiment)I compiled the same code without any changes in Atmel Studio.Device,attiny84 selected. The result was that the read_rms() function took 44 milliseconds.
44 miliseconds vs 23.25 miliseconds. Why?
Note:The following settings are selected in the proteus.Internal RC Osc. 8 Mhz,and CKDIV8=Programmed.
My code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
const uint8_t muxbits = 1<<MUX3 | 1<<MUX2 | 1<<MUX1 | 1<<MUX0;
void adc_init()
{
ADMUX = 0; //Vcc_ref_
ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADPS0); //adc_enable_and_prescaler_8_ 125000 Hz (1000000/8)
//first_try
ADCSRA |= (1<<ADSC);
while ((ADCSRA & (1<<ADSC)) != 0);
}
uint16_t adc_read(uint8_t channel)
{
ADMUX = (ADMUX & ~muxbits) | channel;
// start_single_convertion
ADCSRA |= (1<<ADSC);
// wait for conversion to complete
while ((ADCSRA & (1<<ADSC)) != 0);
return (ADC);
}
double read_rms()
{
uint16_t i=0;
uint16_t a_data=0;
uint32_t sum=0;
float avarage=0;
double rms=0;
for(i=0;i<200;i++)
{
a_data=adc_read(1);
sum=sum+(a_data*a_data);
}
avarage=(float)sum/200;
rms=sqrt((double)avarage);
return rms;
}
int main(void)
{
DDRA|=(1<<7);
PORTA &=~ (1<<7);
adc_init();
while(1)
{
read_rms();
PORTA ^= (1<<7);// TOOGLE_PA7 for_measure_time_of_read_rms()_with_oscilloscope
}
}
double
whereas Arduino uses onlyfloat
(single precision).float
vsdouble
is responsible by just altering your code to make use offloat
types everywhere. This includes usingsqrtf
rather thansqrt
. As said, there may still be other differences, so the timing results may not completely converge.