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
}
}
1 Answer 1
Different compilers produce different machine code.
As Majenko pointed out, the Arduino IDE's compiler, which happens to be GCC, uses float
even when you write double
.
The Atmel Studio creates double
for double
, using twice as much bits.
Calculating with more bits takes longer.
-
I did float.the result is the same again.And I did sqrtf instead of sqrt.harun caliskanoglu– harun caliskanoglu2021年01月08日 11:47:11 +00:00Commented Jan 8, 2021 at 11:47
-
Did you look into the generated assembly? There might be some implicit conversions to
double
, or Atmel's compiler uses the standardsqrt()
even forsqrtf()
.the busybee– the busybee2021年01月08日 13:01:41 +00:00Commented Jan 8, 2021 at 13:01 -
no I haven't examined.But,Why would there be such a thing?Instead of sqrt I typed sqrtf because I didn't want to use double numbers unnecessarily. As for the main problem, I think it's related to compiler configurations. But I haven't figured it out yet.harun caliskanoglu– harun caliskanoglu2021年01月09日 21:03:32 +00:00Commented Jan 9, 2021 at 21:03
Explore related questions
See similar questions with these tags.
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.