PDA

View Full Version : Help with Circuit



Art
- 16th December 2009, 20:00
Hi Guys,
Not PBP specific, but I'm trying to make a pic powered voltmeter using an LCD display and Pic 16F876.
and then hope to go on to log voltages, display averages, predict battery behavior, etc.

A couple of the panel voltmeters sold at Jaycar are powered from the line being measured.
I'm wondering if they go about this by regulating the line with a 7805 or similar to power the device,
and then also feed the unregulated side of the 7805 through a voltage divider,
and then straight into one of the ADC channels without being regulated???

Also.. I have an ADC variable being readout to LCD for experimentation.
The LCD shows zero when the ADC is grounded, and 255 when connected to +5 Volts.
Is this what I should be using for a voltmeter? (once some calculation is done)
Cheers, Art.

mackrackit
- 17th December 2009, 07:49
Do you have a data sheet for that Jaycar part or a part number?

8 bit or 10 bit?
Hard to say. Depends on the resolution you want.
Here is something to look over.
http://www.rentron.com/serial.htm

Art
- 18th December 2009, 02:41
Turns out I might by lying about the Jaycar panel meter.
Looking back, I found a picture with a 7805 I used to power it.

It's a 10 bit ADC I think since it's a 16f876.
I have it working as far as it returns 0 if the ADC line is grounded,
and 255 if It's connected to the pic circuit's 5 Volt power.

Re: your link, I've seen many 5 Volt Voltmeter circuits on the net,
but this is to operate in the range of 12 Volt batteries.
I've found a few hints about that on other forums.. ie:


Ok, so you've decided on 0.1V resolution. Set the A-D ref volt to 5V and construct a voltage divider on the A-D input with a mid-point voltage of 5V when 25.5V is applied at the top-end e.g 15k fixed resistor at the top, 10k multi-turn pot at the bottom and take the output off the wiper. (you can refine this but just as an example)

I believe the PIC has a 10-bit A-D converter so RRF the result to give an 8-bit result. You now have a 0-25.5V voltmeter with a 0.1V resolution and a direct relationship between the value returned by the A-D and the input voltage i.e. 125 = 12.5V, 147 = 14.7V ....


I have sound now, and an I2C EEPROM for logging. I'm just ready now to play with voltage dividers
to prepare a voltage input.
http://farm3.static.flickr.com/2551/4194083632_f97d6cc4a1_o.jpg

mackrackit
- 18th December 2009, 07:28
Yup, a voltage divider is the way to go.
Do a search on this forum and what you are planning has been talked about.

The link I referred to was more for the ADC explanation part and not the circuit.

Ioannis
- 18th December 2009, 09:14
I wonder why did you solder components on the copper side of the board.

Ioannis

Art
- 18th December 2009, 09:56
I always surface mount everything on prototype boards.
I like to have one flat side sitting on the desk.

I have a working Voltmeter unit now :)
It also has an interrupt/timer driven real time clock.
I guess the next thing is to start the logging, and make it smarter.

Art
- 18th December 2009, 23:39
The only issue I'd complain about now is that the ADC result used for the
Voltage readout is not stable where an off the shelf Multimeter/Voltmeter would be.
This doesn't seem to happen if the pic circuit is powered by a separate battery.

http://www.youtube.com/watch?v=txb2Tv7-f_w

I used a voltage divider to scale down the input voltage from the battery as
described in the quote (from another forum) in one of my above posts.

What does it mean when it says "Set the A-D ref volt to 5V" ?
Cheers, Art.

mackrackit
- 18th December 2009, 23:59
Try a capacitor of maybe 10 to 22uF from the ADC pin to the zero rail. Should help smooth things out.

VREF needs to be stable/steady. If the voltage swings the ADC will also. Some will power the pic at 5.2 or so. If that is the case then the VREF needs addressed.

Many times if I am powering the PIC at ~5 volt I will have the VREF at 3 or 4 volts. That way if VDD changes a little it will not cause a problem with the ADC reading.

Art
- 19th December 2009, 00:05
Thanks, I'll try adding the capacitor.

By VREF, you mean pin 5?
Should I connect it to the 5 Volt rail?
I imagine the 5 Volt power supply should be stable since it is now powered from the 7805.

Do I need to do anything to tell the pic that I'm providing the + 5 Volt reference voltage?

http://farm3.static.flickr.com/2637/4195583873_c122f2c34f_o.png

The red wire currently connects the battery to the ADC pin.
Cheers, Art.

mackrackit
- 19th December 2009, 00:46
I would have to check the data sheet to see which pin the ADC VREF is on. But if you did not tell the PIC different it will use VDD as a VREF. Show use you code and we can be exact.

Just for giggles check the voltage from the 7805 to see if it swings under a load. It probably is not 5 volt to begin with but if it is stable it might be close enough.

Art
- 19th December 2009, 01:25
The output of the 7805 does seem to sit on 4.90 when the circuit is operating.

I tried the capacitor, and it didn't seem to have any effect.
Studying the datasheet a little revealed the correct settings for ADCON registers.
I'm using an0

I have come across one solution using software to display the mean average
of the last ten readings instead of just the current reading.
So when you turn the unit on that way, it takes ten cycles to display the steady voltage.
I'd prefer a proper fix though.



'
'
' Battery Monitor 2009
' Art
'

DEFINE INTHAND ROLLOVER

wsave var BYTE $020 SYSTEM
wsave1 var BYTE $0a0 SYSTEM
wsave2 var BYTE $120 SYSTEM
wsave3 var BYTE $1a0 SYSTEM
ssave var BYTE BANK0 SYSTEM
psave var BYTE BANK0 SYSTEM
i_hour var BYTE
i_minu var BYTE
i_sec var BYTE
i_tic var BYTE

GOTO AFTERINT 'Jump past interrupthandler

ASM

ROLLOVER

; interrupcode follows here

movlw 0x58
movwf TMR1L
movlw 0x9e ;restart timer from ffff - 9e58 => 5Hz if using 4MHz
movwf TMR1H
decfsz _i_tic,f
goto slutint
incf _i_sec,f
movlw 5 ;5 = 1Hz if using 4MHz (change to 10 for 8MHz and so on)
movwf _i_tic

movf _i_sec,w
sublw 60
btfss STATUS,Z ;check for 60 sec
goto slutint ;no
clrf _i_sec ;yes
incf _i_minu,f

movf _i_minu,w
sublw 60
btfss STATUS,Z ;check for 60 minutes
goto slutint ;no
clrf _i_minu ;yes
incf _i_hour

movf _i_hour,w
sublw 24
btfss STATUS,Z ;check for 24 hours
goto slutint ;no
clrf _i_hour ;yes

slutint
bcf PIR1,0 ;zero tmr1 interrupt flag

;end of interruptcode
; restorecode follows here

movf psave,w ;restore
movwf PCLATH
swapf ssave,w
movwf STATUS
swapf wsave,f
swapf wsave,w
retfie

ENDASM

AFTERINT:

INTCON = %00000000 'all interrupts off
PIR1 = %00000000 'zero tmr1 interrupt flag
PIE1 = %00000001 'enable timer1 interrupt
TMR1L = $58
TMR1H = $9e
i_hour = 0
i_minu = 0
i_sec = 0
i_tic = 5 'this value should be the same as the value of line 8 in the ISR
T1CON = %00110001 'timer1 on, prescaler=1/8
INTCON = %11000000 'interrupt on


@ DEVICE LVP_OFF,BOD_OFF,LP_OSC 'set device configuration
'
TRISA = %111111 'Set porta to all imputs
ADCON1 = %10001001 'configure ADC port pins
ADCON0 = 0 '
'
DEFINE LCD_DREG PORTB 'set LCD display congiguration
DEFINE LCD_DBIT 4 '
DEFINE LCD_RSREG PORTB '
DEFINE LCD_RSBIT 1 '
DEFINE LCD_EREG PORTB '
DEFINE LCD_EBIT 0 '
DEFINE LCD_BITS 4 '
DEFINE LCD_LINES 2 '
DEFINE LCD_COMMANDUS 2000 '
DEFINE LCD_DATAUS 50 '
'
DEFINE ADC_BITS 10 'set ADC configuration
DEFINE ADC_CLOCK 0 '
DEFINE ADC_SAMPLEUS 50 '
'
WORK0 var word '
LAST0 var byte 'padding buffers
LAST1 var byte '
LAST2 var byte '
LAST3 var byte '
LAST4 var byte '
LAST5 var byte 'padding buffers
LAST6 var byte '
LAST7 var byte '
LAST8 var byte '
LAST9 var byte '
'
DAT0 var byte 'define variables
DAT1 var byte '
DAT2 var byte '
ADDR var byte 'I2C variables
CONT var byte '
CNT0 var byte 'counters
CNT1 var byte '
CNT2 var byte '
CNT3 var byte '
SNDF var bit 'sound flag
CHAR var byte 'LCD character
scomp var byte 'second compare
TENS var byte '
UNTS var byte '
DECS var byte '
'
'
DAT0 = 0 : DAT1 = 0 : DAT2 = 0 'reset variables to zero
ADDR = 0 : CONT = 0 : CNT0 = 0 '
CNT1 = 0 : CNT2 = 0 : CNT3 = 0 '
SNDF = 0 : CHAR = 0 '
LAST0 = 0 : LAST1 = 0 : LAST2 = 0 '
LAST3 = 0 : LAST4 = 0 : WORK0 = 0 '
LAST5 = 0 : LAST6 = 0 : LAST7 = 0 '
LAST8 = 0 : LAST9 = 0 '
'
PAUSE 1000 'LCD startup time
LCDOUT $FE,1 'clear LCD
'
CONT = %10100000 'set I2C control variable - %1010bbb0
'
'FOR CNT1 = 0 TO 255 'write loop
'ADDR = CNT1 '
'I2CWRITE PORTC.4,PORTC.5,CONT,ADDR,[ADDR] 'test write
'PAUSE 10 '
'NEXT CNT1 '
'CNT1 = 0 '
'
LCDOUT $FE,$40,128,138,138,128,145,145,142,128 'set LCD custom smiley character
'
SOUND PORTB.2,[20,10,70,10] 'make startup sound
'
'
cycle:
'
LCDOUT $FE,2 'LCD cursor return home
CNT3 = CNT2 'store current scroll position
FOR CNT1 = 0 TO 15 '
READ CNT2,CHAR 'read character from on-chip EEPROM
LCDOUT CHAR 'print character
CNT2 = CNT2 + 1 '
IF CNT2 > 254 THEN CNT2 = 0 '
NEXT CNT1 '
CNT2 = CNT3 'restore scroll position
'
CNT2 = CNT2 + 1 'advance scroll position
IF CNT2 > 254 THEN CNT2 = 0 '
'
'
scomp = 0
IF scomp = 0 THEN
'
ADCIN 0,DAT0 'read ADC to variable
'ADDR = CNT0 'set EEPROM address
'I2CREAD PORTC.4,PORTC.5,CONT,ADDR,[DAT1] 'read from EEPROM
LCDOUT $FE,$C0 'second line

IF i_hour < 10 THEN LCDOUT "0" '
LCDOUT #i_hour 'print variables
LCDOUT ":" '
IF i_minu < 10 THEN LCDOUT "0" '
LCDOUT #i_minu '
LCDOUT ":" '
IF i_sec < 10 THEN LCDOUT "0" '
LCDOUT #i_sec '
'
LAST9 = LAST8 '
LAST8 = LAST7 '
LAST7 = LAST6 '
LAST6 = LAST5 '
LAST5 = LAST4 '
LAST4 = LAST3 '
LAST3 = LAST2 '
LAST2 = LAST1 '
LAST1 = LAST0 '
LAST0 = DAT0 '
'
WORK0 = LAST0 + LAST1 + LAST2 + LAST3 + LAST4 'calculate mean average
WORK0 = WORK0 + LAST5 + LAST6 + LAST7 + LAST8 '
WORK0 = WORK0 + LAST9 '
WORK0 = WORK0 / 10 '
DAT0 = WORK0 '
'
TENS = DAT0 DIG 2 'get separate digits
UNTS = DAT0 DIG 1 '
DECS = DAT0 DIG 0 '
'
LCDOUT " " 'print Voltage
IF DAT0 < 100 THEN '
LCDOUT " " '
ELSE '
LCDOUT #TENS '
ENDIF '
LCDOUT #UNTS '
LCDOUT "." '
LCDOUT #DECS '
LCDOUT "V" '

IF DAT0 = 0 THEN
SOUND PORTB.2,[100,10,50,10] 'sound alarm for zero Volts
PAUSE 150 '
ELSE '
PAUSE 300 '
ENDIF '

SNDF = 1 'set sound flag
CNT0 = CNT0 + 1 'increment counter
ENDIF '
'
IF SNDF = 0 THEN
PAUSE 300 'delay
ELSE
SNDF = 0
ENDIF
'
goto cycle
'

Art
- 19th December 2009, 08:44
It seems the problem was solved when I soldered in the 0.1uF cap at the pic's vdd/vss pins ! :)

Art
- 23rd December 2009, 06:51
So now the Volt meter is ok, I'd like to add an Ammeter into the same circuit to
display the current output of whatever device is being used to charge the battery (probably solar).

I've never tried to make an ammeter before. This is a little hint I found off the net:


put a small value precision resistor (like a 0.01 ohm 5-20W)in series with the load and measure the voltage drop across the resistor. Let's say the voltage across the resistor is 1 Volt, then 1V/0.01=100 Amps.


So it sounds like I could read the voltage across the resistor with another
ADC input pin.
This being an independent supply from that powering the pic circuit,
I should be able to connect directly to the resistor?
Thanks, Art.

Ioannis
- 23rd December 2009, 07:28
I hope you did not tried it yet!

In that case, think to put this resistor on the ground terminal and not on the + line.

After this an op-amp I think is necessary to amplify the signal by a factor of X to raise the voltage from the resistor (a few mV) up to the max level the ADC will need.

A good op-amp might be the LMC66x series from National or the Microchip's low voltage op-amps (not tried them yet).

Ioannis

Art
- 23rd December 2009, 13:21
Thanks for the hint :)