PIC 18F : C18 A/D conversion into characters

I have some other articles on PIC A/D using Microchip C18 compiler and MPLAB IDE. Here I want to focus on what to do with the actual converted analog values once we have them.
Basically they are read into 2 variables ADRESH and ADRESL which are a byte each. The value that the PIC creates in these 2 locations is 10 bits long and is left-justified ( this can be changed by messing with some bit in ADCON2 ) spread out across the 2 registers.

Therefore we need to convert the bits in the registers ADRESH and ADRESL into a presentable format that we can do something with, like send to a serial interface or LCD screen.

Firstly we convert to ints and then get the value of the voltage that the bits ( and thus the ints ) respresent:

        // Declare the variables we will be using.
	unsigned int highb, lowb;
        float total;
        long adresult;

        // Put the 2 A/D result registers into 2 int storage variables.
        highb = (unsigned int) ADRESH;

	lowb = (unsigned int) ADRESL;

	// This next bit converts the total to a long ( int is too small ) from the 8 bits
        // of the ADRESH and the far 2 bits of the ADRESL ( which are now in highb and lowb )

	adresult = highb*4 + lowb/64; // *4 shifts 2 bits to the left, /64 shifts 6 bits to the right

        // Now we convert to the voltage ( the range is 0.0 - 5.0 volts )
        // Divide by 1024 as that is the maximum representable by 10 bits.
	total =  (float)(adresult * 5.0 / 1024.0);

So now we have the volts as a floating point number compared to before where we just had 2 registers with bits in them.

In order to send this to useful places like an LCD display it may be necessary to convert this to a sequence of characters and so, for example, 2.55 becomes 4 characters of ’2′, ‘.’,’5′ and ’5′. Some of these devices will only take character input.

So this can be done using the following function where we use a standard c routine called sprintf:

void ConvertToChars( float voltage )
{
	int lpart=0; // Stores digits left of decimal point.
	int rpart=0; // Stores digits right of decimal point.

        // Create 2 buffers for the characters.
	char cbufl[ 1 ];

	char cbufr[ 2 ];

	// The number is converted to two parts firstly and so we end up with 2 ints
        // to represent the part before and after the decimal point.

	lpart = (int) voltage;
	rpart = (int) ( (voltage*100.0)-lpart*100.0 ); // This gets the number after the decimal point.

        // Now we use sprintf to convert each int to an array of chars.
        sprintf(cbufl, "%1i", lpart );

 	sprintf(cbufr, "%2i", rpart );

        // Now we have 2 arrays of char variables to represent the A/D value in terms of before and after the decimal point.
}

So sprintf does some cool things like convert ints to chars using a format specified that start with a percentage ( the second argument to the function ). The 1 and 2 specify the number of characters that we are going to place in the output buffers cbufl and cbufr. The ‘i’ tell the function that we are throwing some ints in there ( lpart and rpart ).

This then gives us a pair of char arrays that we can send into UART or LCD devices.

Although it seems a lengthy and involved process, it is necessary to perform such steps when programming PICs.

This entry was posted in Technical / Programming and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>