Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Need help programming MCU in Winavr

Status
Not open for further replies.

polashd

Member
I’m learning MCU programming with Atmega32 & winavr. I need to convert ADC value to something else (say voltage=5*ADCvalue/1023) which needs to deal with floating point/double. Then to display on LCD I need to convert the calculated value to string/array (eg. Sprintf(….)). Both these (floating point number & print function) consumes large memory/code area of the microcontroller (even with the small versions made for MCU).

Can any one please help me with any alternative way. I goggled a lot but failed to figure out solution specific to my case (I’m not an expert in programming/MCU).
*****
ISR(ADC_vect)
{
uint8_t thelow=ADCL;
uint16_t adc10bit=ADCH<<2 |thelow>>6;

float adcvolt=4.8*((adc10bit)/1023);
char adcvoltstr[10];
sprintf(adcvoltstr,"%.2f",adcvolt); //sprintf() may not be used
PrintValuetolcd(adcvolt,2,1); //display ADC value
PrintStringtolcd(adcvoltstr); //display volt

_delay_ms(50);
ADCSRA |=1<<ADSC; //start the next conversion
}
****
 
I program PIC's.. But they also have a problem with sprintf..


See if your compiler has an ftoa() function..

All else fails.... Swap to fixed point math..

ie.. 4.678 * 1000 = 4678.... then insert your own decimal point...
 
Can any one please help me with any alternative way.

The alternative way is not to use floating point. Just display the raw ADC value.
 
I program PIC's.. But they also have a problem with sprintf..


See if your compiler has an ftoa() function..

All else fails.... Swap to fixed point math..

ie.. 4.678 * 1000 = 4678.... then insert your own decimal point...

I tried with this solution. but its i get unexpected value . Is it because of data type.
If so, what variable type i should use?
---
uint8_t thelow=ADCL;
uint16_t adc10bit=ADCH<<2 |thelow>>6;

uint16_t adcvolt=5*((adc10bit*1000)/1023);


Printlcdval(adc10bit,1,1); //display the value
Sendastring(" "); //clear 0 of previous display
Printlcdval(adcvolt,2,1);
--
how to impliment fixed point math (sorry, I'm a newbie).
 
Just cast it after you have done the calculations..


Code:
float adcvolt=4.8*((adc10bit)/1023);
int16 FPM = (int16)adcvolt *1000;

Or you can miss out the floating part altogether.


Code:
int32 adcvolt=4800 *adc10bit /1023; //<-- see Romans article about  this

Then insert your own decimal point...
 
Sure... Heres a small routine that will yield a four digit number with a decimal in position 1 with negative sign

You need to pass a string pointer with room for 7 characters...

C:
#define  abs(x)   (((x) < 0) ? (-(x)) : (x)) 


void printFloat(char * flt, int value)
	{
	char sign = 32;				// space
	if(value < 0)
		{
		value = abs(value);		// just in case it goes negative
		sign = 45;			// minus
		}
	flt[0] = sign;
	flt[1] = value / 1000 + 48;		// thousands
	flt[2] = 46;				// decimal point
	flt[3] = ((value % 1000) / 100)+ 48;	// hundreds
	flt[4] = ((value % 100) / 10)+ 48;	// tens
	flt[5] = (value % 10) + 48;		// units
	flt[6] = 0;	
	}
You need to include the abs() definition ( pasted as well )
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top