Convert uint16_t to float

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everyone,

I'm having problems converting my uint16_t variable to int. What I'm trying to do is, to read the ADC value, which is saved in a uint16_t variable, and convert it to float to read 4.66V instead of 954 (954 of 1023). Here is my code.

 

void adc_init(){

ADMUX |= (1 << REFS0); //VRef = AVCC

ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2); //ADC Enable. Prescaler = 128 (125kHz)

}

 

int main(void){

 

DDRD |= (1 << 2); //PD2, OUTPUT

 

adc_init();

 

while(1){

ADCSRA |= (1<<ADSC); //Start the conversion

while (!(ADCSRA & (1<<ADIF))){

PORTD &= ~(1 << 2);

}

 

uint16_t adc_value = ADC;

//printf("%" PRIu16 " ", adc_value);

 

float total;

 

total = (adc_value * 5) / 1023.0;

 

printf("%.2f" " ", total);

}

 

This topic has a solution.
Last Edited: Wed. Feb 19, 2020 - 08:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So what is the problem? 

What were you expecting?

What do you get?

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On the output, I'm getting '?' that symbol. And what I'm trying to see on the output is 4.66 for example, that is the volts of 954 out of 1023 ((954*5)/1023). In Arduino they use something like map(). 

Attachment(s): 

Last Edited: Mon. Feb 3, 2020 - 05:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Life is always better if a human can read it:

void adc_init() {
    ADMUX |= (1 << REFS0); //VRef = AVCC
    ADCSRA = (1 << ADEN) | (1 << ADPS0) | (1 << ADPS1) | (1 << ADPS2); //ADC Enable. Prescaler = 128 (125kHz)
}

int main(void) {
    DDRD |= (1 << 2); //PD2, OUTPUT
    adc_init();
    while (1) {
        ADCSRA |= (1 << ADSC); //Start the conversion
        while (!(ADCSRA & (1 << ADIF))) {
            PORTD &= ~(1 << 2);
        }
        uint16_t adc_value = ADC;
        //printf("%" PRIu16 " ", adc_value);
        float total;
        total = (adc_value * 5) / 1023.0;
        printf("%.2f" " ", total);
    }
}

You never clear the ADIF flag.

It is much safer to watch the ADSC bit.  Hardware clears ADSC when the conversion completes.

 

Your code looks ok.   954 * 5 = 4770 which is a legal integer.   4770 / 1023.0 will cast to 4.6628.   And print as 4.67 4.66

 

I would say (adc_value * 5.0) / 1023; which is a little safer.

We will not argue about div 1023 or div 1024

 

David.

Last Edited: Mon. Feb 3, 2020 - 06:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Arduino map() function:

long map(long x, long in_min, long in_max, long out_min, long out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

 

Use as needed.

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your help, but I want to convert it to float, not to long. I want to have 2 decimals.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Radiikal wrote:
On the output, I'm getting '?' that symbol

There are several printf libs available for the AVR, the one that supports floating point is quite large, so is not the default, did you choose to link your program with the correct lib to get floating point output?

I'll leave it to gcc users to point you to the correct version to link with.

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't know there were more than one library to print a floating point variable. Maybe that's the problem.

 

There's another thing I would like to ask. I have to do change the brightness of a LED but without using PWM, just using a exponential delay on a blinking led. So that, if I would like 50% brightness, I have to put the same delay when the led is on and when the led is off. All I know is theory, but I don't really know how to implement it because _delay_ms() only accepts const int.

Last Edited: Mon. Feb 3, 2020 - 06:17 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need libprintf_flt.a and -Wl,-u,vfprintf to use float. If using AS7 this is easy, there's a tick box for the latter and "Libraries" for the former.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Radiikal wrote:
There's another thing I would like to ask.

Start a new thread for a new question.

 

If this question is resolved, see Tip #5 (in my signature, below; may not be visible on mobile)

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...