1

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
        
    }
}
3
  • 1
    Impossible to tell. Maybe Atmel studio is using actual double-precision values for double whereas Arduino uses only float (single precision).
    – Majenko
    Jan 2, 2021 at 12:51
  • 1
    It's not impossible to tell. You could compare the assembler generated by both. I'm not very familiar with AVR assembler, so I wouldn't be the best choice to do that analysis, but I'm sure somebody on this board could suss it out.
    – Duncan C
    Jan 2, 2021 at 14:35
  • You could also get something of a fuzzy confirmation on whether float vs double is responsible by just altering your code to make use of float types everywhere. This includes using sqrtf rather than sqrt. As said, there may still be other differences, so the timing results may not completely converge.
    – timemage
    Jan 2, 2021 at 16:02

1 Answer 1

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.

3
  • I did float.the result is the same again.And I did sqrtf instead of sqrt. 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 standard sqrt() even for sqrtf(). 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. Jan 9, 2021 at 21:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.