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
}
}
doublewhereas Arduino uses onlyfloat(single precision).floatvsdoubleis responsible by just altering your code to make use offloattypes everywhere. This includes usingsqrtfrather thansqrt. As said, there may still be other differences, so the timing results may not completely converge.