Floating point display using printf

I am trying a Orangutan 324 and so far the demo works and all. I would like to use floating point math and display results using printf.
This is my attempt but unfortunately does not work. It will display a question mark instead of the value.
Could someone tell me how to handle floating point var (I need double precision if possible) and display them on the LCD?

TIA
Giuseppe Marullo

#include <pololu/orangutan.h>
#include <stdio.h>	// required for printf()

int main()
{
lcd_init_printf();
clear();
    double t;
	t = 0.0;
	printf("Yes %f",t);


	play("L16 ceg>c");

	while(1)
	{
	    red_led(0);
		green_led(1);
       
		delay_ms(25);

		red_led(1);
		green_led(0);
		
		delay_ms(25);
	}

	return 0;
}

Hello, xardomain.

Why do you want to use floating point numbers? Usually, a 32-bit integer with well-chosen units should have more than enough precision and range for typical applications of the Orangutan SVP-324.

That being said, it should be possible to use floating points and print them to the LCD. I haven’t done it myself, but it according to this you just need to use the right linker arguments, which are:

-Wl,-u,vfprintf -lprintf_flt -lm

Also beware that the order of linker arguments matters: “-lm” (the Math library) should come after “-lprintf_flt”.

Beware that these libraries might take a lot of program space and be relatively slow.

–David

Hi David,
strange that every answer about AVR starts like “do you REALLY need them”? It should ring a bell to me, I hope is only about performance.

Short answer, why not?
Long asnwer, I need them because I am helping a friend that is designing a automagic satellite tracker. I will need some trigonometry and so…

BTW, do you happen to know how to enable double precision? I managed to run the example in the tutorial (I was adding the linker parameters instead of replacing them now it works) but I see that a double is still no more than 6 digits accurate.

I would also understand if I could debug the Orangutan 324 without any additional hw, it seems not possible. That’s was the reason for having the printf, to have a minimal debugging about the formulas.
Thanks,

Giuseppe Marullo

Hello, Giuseppe.

I don’t know how to get 64-bit floats on the AVR. I searched the internet a bit and it looks like it’s not possible. You can get 64-bit ints though, using the “long long” type.

The Orangutan SVP does not support debugging in the sense of stepping through your program as it runs and inspecting the variables. You can use the buzzer, LEDs, and LCD for debugging purposes though. You could also send serial data back to your computer using OrangutanSerial.

–David Grayson

David,
thanks for answering about my questions. I checked that single precision should be enough, this is a quick test for a HotBird Satellite seen from Milan, Italy. It seems to work:

#include <pololu/orangutan.h>
#include <stdio.h>	// required for printf()
#include <math.h>	// required for printf()

int main()
{
lcd_init_printf();
clear();
    double PosLat, PosLong, SatLong,v1,v2,SatElevation,SatAzimuth,SatPolarization;

/* Address: milan, Italy
	Latitude: 45.4637°
	Longitude: 9.1881°

	Satellite: 13E HOT BIRD 6 | HOT BIRD 8 | HOT BIRD 9
	Elevation: 37.5°
	Azimuth (true): 174.6°
	Azimuth (magn.): 173.0°
*/
	// play("L16 ceg>c");

             PosLat = 45.4637;
	PosLong = 9.1881;
	SatLong = 13;

    PosLat  = (2*M_PI*PosLat)  / 360.0;
    PosLong = (2*M_PI*PosLong) / 360.0;
    SatLong = (2*M_PI*SatLong) / 360.0;

	SatElevation = 0;
	SatAzimuth = 0;
	SatPolarization = 0;
    
	printf("Pos %fN",PosLat);
	printf("      %fE",PosLong);

	while(1)
    {
	    red_led(255);
		green_led(255);
        v1 = 6.612 * cos(PosLat)*cos(PosLong-SatLong)-1;
        v2 = 6.612 * sqrt(  1-(pow(cos(PosLat),2)) * pow((cos(PosLong-SatLong)),2)  );
     
		SatElevation = atan(v1/v2);
		SatAzimuth = M_PI + atan( tan(PosLong-SatLong) / sin(PosLat) );
		SatPolarization =  -atan( sin(PosLong-SatLong) /tan(PosLat) );

        clear();
		SatElevation = (SatElevation * 360.0) / (2*M_PI);
		SatAzimuth   = (SatAzimuth * 360.0) / (2*M_PI);
        
        printf("Az %f\n",SatElevation);
        printf("El %f",SatAzimuth);
	}
	return 0;
}

Now I need to play with the compass and GPS...

Thanks.
Giuseppe Marullo