naseerak
Inactive
Muted
Offline
Posts: 4
Thank You
Given: 3
Receive: 1


« on: January 23, 2014, 02:56:51 14:56 » 

Hi! I am trying to build an voltmeter using PIC16f72 and 3digit 7segment display, but don,t know how to implement the decimal point my code snippets are: adreader:
'read a/d VIN = ADIn 0 'read AD cha 0 value, place in Vin VIN = VIN/4 VIN = VIN*511
VIN = VIN/10
'sort a/d value in 100, 10, 1 's adrd: ONE = Dig VIN , 0 TEN = Dig VIN , 1 HUN = Dig VIN , 2 Return
My highest voltage is 50V and voltage divider consists of 10k in the upper arm and 1k in the lower arm.



Logged




TucoRamirez
Senior Member
Offline
Posts: 277
Thank You
Given: 197
Receive: 95
Tuco ... dead or Alive


« Reply #1 on: January 23, 2014, 03:54:30 15:54 » 

no idea, where do you want to display or use the point in?



Logged

Whoever double crosses me and leaves me alive... he understands nothing about Tuco.



pablo2048
Active Member
Offline
Posts: 103
Thank You
Given: 96
Receive: 82


« Reply #2 on: January 23, 2014, 04:24:40 16:24 » 

Ok, according to datasheet this type of MCU has 8 bit A/D converter. In line VIN = VIN/4 You loose 2 bits of resolution. Better is 1. multiply and then divide... What is Your reference voltage? If 5V, then maximum voltage on the A/D input is approximately 4.54V@50V input.



Logged




sam_des
Active Member
Offline
Posts: 221
Thank You
Given: 47
Receive: 111


« Reply #3 on: January 23, 2014, 07:16:11 19:16 » 

@naseerak,  pablo2048 is right, you should multiply first then divide. Although sequence of operation for mul/div is not important in our math, but with integers it is always multiply first.
e.g. Consider this, (2/5)*50 = 20, but with integer math, result is 0 So you should do it as (2*50)/5.  When you multiply/divide by power of 2, use shift operation instead of math mul/div. It will be faster and code efficient.
 Watch out when multiply two nos., result may require additional byte. 8BIT x 8BIT may result in 16BIT no.
 Your Resistor divider causes ADC input to vary from 0V(0V) to 4.5454V(50V). For simplicity, can you modify your upper arm to be (18k18k) or Even better if you can use a variable res . This will give you exact 1/10th value. Even better if you can use a varres to get correct ratio. Also check power dissipation in resistors. At 50V, upper arm nearly dissipates 225mW. I think 5mA is too much current for sensing. 1mA is enough. Modify resistors accordingly, keeping ratio same. Note this gives no head room for overvoltage.
 Watch out for temp cos of resistors in divider, if you need long term stability. MFRs (metal film resistors) may be a good choice.
Now with precise 1/10th value at adc input, it is very easy to get 1 digit beyond decimal point, with only integer math. Simply scale the calculations by 10. For 50V > ADC INPUT = 5V > ADC Conversion = 1023, Now if 1023 represents 500, any adc result "x" will represent, (x*500)>>10. e.g. For ADC result = 150, V = (150*500)>>10 = 73.24 precise or 73 for integer math giving 07.3 as 3 digit display. Note that you will require 16BIT x 16BIT=>32BIT math multiply. You can work on it further to optimize in terms of code as well as hardware. Hope this helps, sam_des


« Last Edit: January 23, 2014, 07:18:23 19:18 by sam_des »

Logged

Never be afraid to do something new. Remember Amateurs built the Ark, Professionals built the Titanic !



naseerak
Inactive
Muted
Offline
Posts: 4
Thank You
Given: 3
Receive: 1


« Reply #4 on: January 25, 2014, 09:27:24 21:27 » 

@Sam_des You are right but my problem is 8bit of ADC i 16f72. I have done my display code but stuck ni the calculation and display of decimal point, the 50v limit may increased in the upward direction as I am measuring two PVs in series, The Variable VIN has a word size thats why I have implied divided by 4.



Logged




gan_canny
Junior Member
Warned
Offline
Posts: 85
Thank You
Given: 98
Receive: 25


« Reply #5 on: January 26, 2014, 02:14:31 14:14 » 

In mathematics numbers are notation. You have two types of notation base 10 decimal and yes your PIC is binary and uses base 2 notation. The two notations are compatible across the integers (whole numbers). Now we know the pic will use integers to maintain notational accuracy we need to think about the number of base 10 decimal places we need in our result. Suppose it is two base 10 decimal places. The pic is binary so we are only compatible in our notation if we scale everything up by 100 ( base 10). An aside Now binary also has a binary point just as decimal has a decimal point you will encounter the binary point if you were to use float variables with your pic. Notation is not perfect ..Ex 1/3 can't be expressed fully in the decimal ( base 10) system and 0.1 decimal can't be fully expressed in the binary system. Coders often call this inability to fully express things as rounding errors. It is common usage but not perfectly pure mathematics. There is valid math rounding where the notation of numbers is shortened by looking at the least significant digit and rounding up or down. Again scale all your calculations up and use integers within the pic code. On output convert back to the decimal system and place the decimal point taking into account your scaling factor. Now when things need displaying another notation comes in namely ASCII. Your LCD uses this notation for activating pixels. The character representing '0' ( zero) in this notation is 48 (base10). The conversion from 1 base 2 ( binary) to ASCII character notation would involve adding 110000 ( 48 base 10) to get get the character '1'.
Oh, coders can assume the pic calculates like a handheld calculator. A hand held calculator uses BCD ( binary coded decimal) for its calculations. It is slow and cumbersome but it never leaves the decimal notation system so it is notionally accurate in the decimal system. The hand calculator is fine for humans but too slow for a pic. Coders can think a 64 bit PC avoids the notational issue...it does in a way since it is pushed back to very small quote "coder rounding error" in about the 20th least significant digit place.


« Last Edit: January 26, 2014, 02:18:22 14:18 by gan_canny »

Logged




naseerak
Inactive
Muted
Offline
Posts: 4
Thank You
Given: 3
Receive: 1


« Reply #6 on: January 27, 2014, 07:53:51 19:53 » 

Comments from you people were helpful I have solved my problem



Logged




thunderer
Junior Member
Offline
Posts: 54
Thank You
Given: 18
Receive: 61
I try to be patient


« Reply #7 on: February 16, 2014, 03:09:47 03:09 » 

Code for printing a voltage on a LCD (in a format like 12,345V). adc_rd0 = ADC_read(0) ' Read ADC channel 0 tlong0 = adc_rd0 * 5000 * 12 (transform 1024 in 60000  coresponding to 60,000V) tlong0 = tlong0 >> 10 ch0 = tlong0 div 10000 'Extract the tens of thousands if ch0 = 0 then ' If 0, do not print Lcd_Out(1, 1," ") else Lcd_Chr(1, 1, 48+ch0) end if ch0 = (tlong0 div 1000) mod 10 'Extract the thousands Lcd_Chr(1, 2, 48+ch0) Lcd_Chr(1, 3, ".") ch0 = (tlong0 div 100) mod 10 'Extract the hundreads Lcd_Chr(1, 4, 48+ch0) ch0 = (tlong0 div 10) mod 10 'Extract the tens Lcd_Chr(1, 5, 48+ch0) ch0 = (tlong0 div 1) mod 10 'Extract the units Lcd_Chr(1, 6, 48+ch0) I know this answer comes late, but better have a working code posted.



Logged

Interested and hopefully helpful in: DC brushed motor control (mainly R/C  PPM/PWM), analog audio, PIC (mikrobasic PRO). Feel free to ask, and if I can, I will help. But only on forum topics, any started private conversation will continue in a public topic.



pablo2048
Active Member
Offline
Posts: 103
Thank You
Given: 96
Receive: 82


« Reply #8 on: February 16, 2014, 09:40:56 09:40 » 

I think that if you have 10bit A/D convertor, the accuracy is 60/1024 = 0.05859 V/bit. That means the maximum valuable precision is 1 decimal place... Displaying three decimal places is wrong.



Logged




krishna.velu
Newbie
Offline
Posts: 13
Thank You
Given: 10
Receive: 1


« Reply #9 on: July 30, 2014, 12:43:50 12:43 » 

The ADC you have in PIC16f72 is 8Bit.
2^8 = 256.
You will get 255 counts of ADC if your input is full (Assuming 50V = Full Analog Input).
You need to increase your ADC resolution. An ADC resolution of 10 can get you a good result.



Logged




