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.

ADC 10 bit (scale it to volt)

Status
Not open for further replies.

pouchito

New Member
Hi Everyone,

I am writing a code that takes an analog input (values ranges from 0.5V to 3V ) and displays the result on the LCD

I wrote the code but still needs to scale it to volt.
what i got till now is when the analog input is for example 5V ==>the LCD shows 1022 (decimal)

I guess after reading "Gramo's webpage" I can use this :

Result1 = Result1 * 5 / 1023 ' Scale it to volts

in my case is this right or i must multiply it by 5000?
( I am still a newbie in the ADC world :S )


(I am using PIC simulator IDE compiler)

Thanks in advance
 
Last edited:
Perhaps the output of your voltage regulator is not correct, I’m not sure circuit your using, but make sure you have a 0.1uF on the output and a larger one (between 10uF and 100uF) as well, like this;

**broken link removed**

This will really improve ADC accuracy, but if you already have something like the above happening, then just change you algorithm;

Result1 = Result1 * 5 / 1022

This will scale your results to the correct value; I have had your problem in the past, but found that it was my power supply, not the code.

Hope it helps
 
Thanks a lot "Gramo" :)

yep you are right , I m using only a regulator without the capacitors thta's why my results are not accurate, i was just wanted to check if my code will work or no, I will implement the power supply circuit you gave me.

Concerning the code, i will add the Result1 = Result1 * 5 / 1022
and tell you what happens :)

I still have many parts to go on , can you help me or you are busy ?
 
pouchito said:
Concerning the code, i will add the Result1 = Result1 * 5 / 1022
and tell you what happens :)

It depends on the variables you’re using, I think you said earlier that your using assembler, and that you were just learning, is that right?

If you are, I really can’t help - I have a basic knowledge in assembler, but not to 32bit math support. You could even make your own 16 bit math routines (for variables 0-65535) but I really don’t want to go down either road...

Are you playing around with Proton+ yet? If you are we could deffinetly work something out, even with the lite version.
 
I Know assembly but not expert
I am learning the PICBASIC and currently i am writing this code using the picbasic...and i found your site wonderful and will help me learning it faster.
 
It's simple to do with assembler as well, you just need a 16 bit maths routine, which are easily found. However, I suggest you read my analogue PIC tutorial - which avoids the use of maths by careful range selection - this would work fine for your application, and give 0.01V resolution (readings from 0V to 10.23V).

The maths avoidance isn't because of the maths, as I said it's simple to do - BUT if you multiply the reading the minimum resolution is multiplied as well. So while it reads 0-10.23V with 0.01V resolution, if you multiply it by 2 it will read 0-20.46V with 0.2V resolution. This means the least significant digit always changes by two - personally I think this looks really horrible!.
 
How about this, just change the device for the PIC you use and it should work;

PHP:
Device 16F877A
Declare XTAL 4

DECLARE ADIN_RES 10 		' 10-bit result required 
DECLARE ADIN_TAD FRC 		' RC OSC chosen 
DECLARE ADIN_STIME 50 		' Allow 50us sample time 

Declare LCD_TYPE 0 			' Type of LCD Used is Alpha
Declare LCD_DTPIN PORTB.4   ' The control bits B4,B5,B6,B7
Declare LCD_RSPIN PORTB.2 	' RS pin on B2
Declare LCD_ENPIN PORTB.3 	' E pin on B3
Declare LCD_INTERFACE 4 	' Interface method is 4 bit

PORTB_PULLUPS True
 
	Dim Result1 As Float
	
	Dim Last_Result1 As Float
	
	Symbol Input1 = PORTA.0
	
	TRISA = %11111111 			' Configure PORTA to inputs
 
	ADCON1 = %10000000 			' Set analogue input, Vref is Vdd
	
Main:

	 Result1 = ADIN 1			' Grab A0's digital value
	 
	 Result1 = Result1 * 5 / 1023		'  Convert to Volts
	 
	 If Last_Result1 <> Result1 Then	     ' Check if value has changed
	 	Print At 1, 1, Dec3 Result1, "V   "	' If it has, display new data
		Last_Result1 = Result1		 	'  and update last value
	 EndIf
	 
	 Goto Main		   			' Loop for ever

I'd shudder to develope 32 bit floating point math routines, but here they are being used, giving you an accurate ADC to 0.004 of a volt.

Wire up your LCD like this;

**broken link removed**

and connect the pot to PORTA.0 similar to this
**broken link removed**
 
gramo said:
I'd shudder to develope 32 bit floating point math routines

Why would you want to?, there's no requirement for floating point at all, 16 bit integer maths is all that's required and would be more accurate than floating point routines (which lose accuracy because of the conversions).
 
Some circuits require the sensitivity/accuracy of floating math, but if you’re going to use a single float in your program, you may as well use floats as the float math libraries are already loaded into the program.

I'm not sure what resolution is required for the app, I’m just giving an example of how the most complex of math functions can be solved so easily, and with so many pic micros with 10K+ program memory, its no hassle these days to use DWords / Floats in most apps.

To roll the program back and use Words (16bit) is as simple as declareing you variables as Words, and scailing the answer to allow for decimal values, i.e.

Code:
	 Result1 = Result1 * 50
	 
	 If Last_Result1 <> Result1 Then	' Check if value has changed
	 	Print At 1, 1, Dec Dig Result1, 1, ".", Dec Dig Result1, 0, "V  "
		Last_Result1 = Result1		'  and update last value
	 EndIf

Using the DIG command allows for each character of the number to be extracted, i.e. an answer of 45 would be displayed as 4.5V with the above
 
gramo said:
Some circuits require the sensitivity/accuracy of floating math, but if you’re going to use a single float in your program, you may as well use floats as the float math libraries are already loaded into the program.

It's fairly rare to need floating point maths, and it's best avoided because of it's inaccuracies - the conversions required cause loss of accuracy.

To roll the program back and use Words (16bit) is as simple as declareing you variables as Words, and scailing the answer to allow for decimal values, i.e.

Exactly, by using words it's fully accurate, and smaller and faster - but most important is the accuracy. If you do use floats you really need to correct it afterwards - multiply it up until the resolution you need is all integer, add 0.5 to it, then chop everything below the decimal point. Then reinsert the decimal point.

That's the floating point solution - it's far easier to use integers in the first place - which is why spreadsheets use integers for monetary calculations. You may be too young to remember the stupid bills you used to get due to bad programming using floats? - such as electric bills for £123.09867563523895745 instead of £123.10

Really the root cause is using a high level language, it makes it too easy to make poor choices.
 
Thanks a lot for all your help.

Nigel's tutorials are great and Excellent for assembly language.
I really thank you for sharing it with us.

But i m using the picbasic in writing this code.

So what about the float stuff ?
 
pouchito said:
Hi Everyone,

I am writing a code that takes an analog input (values ranges from 0.5V to 3V ) and displays the result on the LCD

I wrote the code but still needs to scale it to volt.
what i got till now is when the analog input is for example 5V ==>the LCD shows 1022 (decimal)

I guess after reading "Gramo's webpage" I can use this :

Result1 = Result1 * 5 / 1023 ' Scale it to volts

in my case is this right or i must multiply it by 5000?
( I am still a newbie in the ADC world :S )


(I am using PIC simulator IDE compiler)

Thanks in advance

I think this will help u.
i am also beginer, sorry for mistake if any.

Supose u want to make a volt meter it's maximum range will be 5 Volt(as u say)
Ur ADC converter has 10 Bit resulotion it mean in it has maximum value in decimal 1023.
it means as u apply maximum voltage(as u say 5 volt) to ADC it will give u 1023 in decimal.
So the formula is
Code:
Voltage = Applied voltage * maximum range / ADC resulotion

Voltage > measured voltage (we don't know it's value)

Applied Voltage > This is our applied voltage which we apply on ADC leg it rage will be 0 ~ 1023.

Maximum range > for which range u want to scale it( as u say 5 volt)

ADC resulotion > 10 Bit it means it maximum value in binary = (1111111111) or in Decimal 1023.

Now we start,
u want to scale it for 5 Volt( it mean it's maximum reading will 5 volt)
The formula will be
Code:
Voltage = Applied voltage * 5 / 1023
for example u apply 5 volt to ADC.
then ADC will convert this value into binary so it will be (1111111111) or if we see it in decimal then it will be 1023
It means
Code:
Applied Voltage = 1023
So we put this value in our formula
Code:
Voltage = 1023 * 5 / 1023
So the answer will be
Code:
Voltage = 5

Now an other example
Supose u apply 2.5 volt to ADC
So it will conver it into binary (0111111111) or it will eqaul to 511 in decimal.
Code:
Applied Voltage = 511
So we put this value in our formula
Code:
Voltage = 511 * 5 / 1023
So the answer will be
Code:
Voltage = 2.497

I think now u can understand that whis is going on.
 
Yes, it means not equal to.
 
Anyone use picsimulator compiler ?
because i want to show up the value after the comma, and this compiler s not understanging the DIG

Please help
 
my problem was solved using modulos but i m not getting accurate results.
Thus i m satisfied cz my application does not need to be too much specific
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top