PDA

View Full Version : strange A2D 5V scaling result - 16F819



Max Power
- 6th April 2010, 15:58
5V PIC16F819, olimex pic18 dev board, PBPW in MPLAB, PICKIT3

Hello everybody,

Nothing extrodinary here, except the amount of time I've spent on this :-) I'm simply trying to read a voltage (right now it's off a pot, but eventually it would be a battery) and send the value out over RS-232. I'm getting some strange results from the scaling math. Here is the code.




' PIC16F819 Configuration
' ================
@ __CONFIG _HS_OSC & _MCLR_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF

DEFINE DEBUG_REG PORTB 'RS-232 output on PORTB.4
DEFINE DEBUG_BIT 4
DEFINE DEBUG_BAUD 19200 ' 19200 Baud,
DEFINE DEBUG_MODE 0 ' not inverted. using (MAX232) RS-232 level shifer

DEFINE ADC_BITS 10 ' Set number of bits in result
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS

DEFINE OSC 20

ADCON0 = %11000001
ADCON1 = %10001110 ' AN0 (PORTA.0) is analog

TRISB = %00000110
TRISA = %00000011

PushB var PORTB.2 ' Pushbutton (OLIMEX 18 pin PIC dev board)
LED var PORTB.3 ' Indicator LED (OLIMEX 18 pin PIC dev board)
A2DPIN var PORTA.0 ' AN0
A2Dvalue var WORD ' to store result
W0 var WORD ' division remainder
W1 var WORD ' division modulus

A2Dvalue = 0
W0 = 0
W1 = 0

DEBUG REP $00\8,13,10,"Start Up"

LED = 1 'Wait at startup
pause 7000
LED = 0

mainloop:

pause 250

ADCIN 0, A2Dvalue ' Read channel 0 to variable advalue

W0 = (A2Dvalue * 5) / 1024
W1 = (A2Dvalue * 5) // 1024

DEBUG REP $00\8,13,10, "Voltage = ",DEC W0,".",DEC3 W1, " A2D value = ",DEC A2Dvalue

Goto mainloop
END



and here are the results I get. notice the strange readings when the A2D count is 201 and 202, also 406, also 1021.




Start Up
Voltage = 0.000 A2D value = 0
Voltage = 0.080 A2D value = 16
Voltage = 0.125 A2D value = 25
Voltage = 0.190 A2D value = 38
Voltage = 0.310 A2D value = 62
Voltage = 0.335 A2D value = 67
Voltage = 0.405 A2D value = 81
Voltage = 0.445 A2D value = 89
Voltage = 0.500 A2D value = 100
Voltage = 0.565 A2D value = 113
Voltage = 0.630 A2D value = 126
Voltage = 0.675 A2D value = 135
Voltage = 0.700 A2D value = 140
Voltage = 0.750 A2D value = 150
Voltage = 0.845 A2D value = 169
Voltage = 0.900 A2D value = 180
Voltage = 0.920 A2D value = 184
Voltage = 0.930 A2D value = 186
Voltage = 0.940 A2D value = 188
Voltage = 0.950 A2D value = 190
Voltage = 0.960 A2D value = 192
Voltage = 0.975 A2D value = 195
Voltage = 0.005 A2D value = 201
Voltage = 0.010 A2D value = 202
Voltage = 1.026 A2D value = 210
Voltage = 1.076 A2D value = 220
Voltage = 1.141 A2D value = 233
Voltage = 1.196 A2D value = 244
Voltage = 1.246 A2D value = 254
Voltage = 1.306 A2D value = 266
Voltage = 1.356 A2D value = 276
Voltage = 1.356 A2D value = 276
Voltage = 1.366 A2D value = 278
Voltage = 1.611 A2D value = 327
Voltage = 1.771 A2D value = 359
Voltage = 1.851 A2D value = 375
Voltage = 1.891 A2D value = 383
Voltage = 1.901 A2D value = 385
Voltage = 1.901 A2D value = 385
Voltage = 1.926 A2D value = 390
Voltage = 1.956 A2D value = 396
Voltage = 1.956 A2D value = 396
Voltage = 1.006 A2D value = 406
Voltage = 2.037 A2D value = 417
Voltage = 2.082 A2D value = 426
Voltage = 2.157 A2D value = 441
Voltage = 2.207 A2D value = 451
Voltage = 2.207 A2D value = 451
Voltage = 2.207 A2D value = 451
Voltage = 2.612 A2D value = 532
Voltage = 2.727 A2D value = 555
Voltage = 2.807 A2D value = 571
Voltage = 2.837 A2D value = 577
Voltage = 2.022 A2D value = 614
Voltage = 3.068 A2D value = 628
Voltage = 3.098 A2D value = 634
Voltage = 3.153 A2D value = 645
Voltage = 3.228 A2D value = 660
Voltage = 4.894 A2D value = 998
Voltage = 4.894 A2D value = 998
Voltage = 4.009 A2D value = 1021



..a better way????

Darrel Taylor
- 6th April 2010, 21:45
While it is incorrect, the results are not strange at all.

The Modulus operator only returns a decimal number if you are dividing by a factor of 10 (10,100,1000).

When you // 1024, the result will be from 0 to 1023.
The numbers at 201, 202 are where the value goes over 1000, but you are displaying the lowest 3 digits.

For 3 decimals, the easiest way to do it is ...

W0 = A2Dvalue * 5000
W0 = DIV32 1023

DEBUG REP $00\8,13,10, "Voltage = ",DEC W0/1000,".",DEC3 W0, " A2D value = ",DEC A2Dvalue

Max Power
- 7th April 2010, 14:49
Darrel,

Thanks so much for the insight and the code correction. It works as expected. Now, I can see a light at the end of this tunnel. Thats what I get for saying "that should be an easy project, shouldn't take too much time at all"...mental note: never say that. :)

Thanks again.

Darrel Taylor
- 8th April 2010, 02:28
The end, or the train?
<img Height=160 Width=212 src="http://www.pbpgroup.com/files/Freight-train-light.jpg" />

Cheers,
&nbsp; &nbsp; DT