sprintf() and float data type

G’day all,

has anyone had any issues using the sprintf() function when compiling with WinAVR. I try to compile with a float in the data format and WinAVR gives me a warning saying that the compiler was expecting a double instead it has been presented with a float, however it does compile. When i run the prog it doesn’t give any value.

I can verify that the sprintf() function does work, cos when you change the appropriate data type values for an int, it works like a charm.

The program is for a simple voltmeter for an Atmega8. it uses ADC0 and the LCD is connected to PORTD.

#include <stdio.h> 
#include <stdlib.h>
#include <avr/io.h>
#include "lcd.h"
#include <util/delay.h>


#define F_CPU 16000000UL  // 16 MHz

void delay_ms(uint16_t x); //General purpose delay


int main(void)
{

	float 	adc_data = 0,
			volts = 0;

	char 	lcd_buff[20];
	
	int j =0;
	

	DDRD = 0x00;	//makes all outputs
	PORTD = 0x00;


	/* initialize display, cursor off */
	lcd_init(LCD_DISP_ON);

	/* clear display and home cursor */
    lcd_clrscr();
		
	delay_ms(3000);
		
	ADCSRA = 0b11100111;
		
	ADMUX = 0b00000000; //0b 00000000
		
		
		while(1==1)
		{
				
				ADCSRA=0b11100111; //0b 10001110
				
				ADMUX=0b0000000;

				delay_ms(2000);
				
				adc_data = ADC;
				
				//j = ADC;
				
				//adc_data = adc_data*5/1023; //convert into volts
				
				//adc_data = adc_data - 1.650; //shift midpoint
				
				lcd_clrscr();
				lcd_gotoxy(4,1);
				
				sprintf(lcd_buff,"%1.4f",adc_data); 
				//sprintf(lcd_buff,"%4d",j);

				lcd_puts(lcd_buff);
				
				lcd_gotoxy(8,1);
				lcd_puts("mV");
		}

}


void delay_ms(uint16_t x)
{
  uint8_t y, z;
  for ( ; x > 0 ; x--){
    for ( y = 0 ; y < 90 ; y++){
      for ( z = 0 ; z < 6 ; z++){
        asm volatile ("nop");
      }
    }
  }
}

Any suggestions or info from people who have used sprintf() successfully with floats would be most appreciated.

Cheers,

Timmy

just for curiosity sake, remove the formating and try this and see if you get any different results.

sprintf(lcd_buff,“%f”,adc_data);

I don’t have winavr on this machine so I can’t check, but I seem to remember there’s a setting in the makefile for which version of printf and sprintf to use. By default, it uses a simplified printf to save space. That version probably doesn’t know about floats. You may have to add the math library too (-lm to LDFLAGS)

/mike

n1ist,

changing the printf() info in the makefile from simplified printf to the more advanced printf solved the issue. Works a charm now.

cheers,

Timmy

yes, the standard libraries don’t support printf() for floats - to save space in flash.

Hello, can you tell me how you changed the printf() to the more advanced to allow floats? I cannot find it in AVR Studio.

Thanks

from http://www.nongnu.org/avr-libc/user-man … stdio.html might be what you want…

If the full functionality including the floating point conversions is required, the following options should be used:

-Wl,-u,vfprintf -lprintf_flt -lm

floats, doubles. Try to avoid and use ints and longs. Or longs with a fixed implicit decimal point, such as 1.54 scaled up by 100 to be an integer.