Pic ADC - Negative voltages.

Status
Not open for further replies.

mbprado

Newbie level 3
Joined
Oct 9, 2007
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,305
Hi everyone.

I have seen in another topic, an exemple in mikrobasic, of a 0v > +5v voltimeter .
Thamid's exemple bellow, works fine for me, but now, I need to work at -5v to +5v and I dont know how to do this.

Any Idea?

Tks for your help.

Code:
program softwarefor887Voltmeter

dim LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D4 as sbit at RB0_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D7 as sbit at RB3_bit

    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit

dim ADCResult as longword
dim voltage as word[5]
dim display as string[5]

sub procedure GlobInit
    ANSEL = 1
    ANSELH = 0
    TRISA = 1
    TRISB = 0
    PORTB = 0
    LCD_Init()
    LCD_Cmd(_LCD_CLEAR)
    LCD_Cmd(_LCD_CURSOR_OFF)
    LCD_Out(1, 1, "Voltage:")
    LCD_Chr(1, 16, "V")
    display[1] = "."

end sub

main:
     GlobInit
     while true
           ADCResult = (ADC_Read(0) * 500) >> 10
           voltage[0] = ADCResult div 100
           voltage[1] = (ADCResult div 10) mod 10
           voltage[2] = ADCResult mod 10
           display[0] = voltage[0] + 48
           display[2] = voltage[1] + 48
           display[3] = voltage[2] + 48
     vout:
           LCD_Out(1, 10, display)
           delay_ms(50)
     wend
end.
 

Hi,
You can try this method:
1. Feed the input voltage to two op-amp circuits: a non-inverting amp and an inverting amp with gain as required.
2. Feed these two op-amp outputs to two PIC input pins.
3. Connect two schottky diodes at the PIC inputs to prevent them going less than 0.3v.
4. Check both the input pins to see which one is greater than 0.3v.
5. Read the positive one, and determine whether it is the positive or negative voltage you are reading.

Hope this helps.
Tahmid.
 


Tks for ur reply!
Its a good idea. In this case, I will have two distinct reads. Sure i´ll try this.
 

program softwarefor887Voltmeter
can u post hex code & ckt diagram also ?
 

Ok. Now, finaly, it's working!

Code:
program voltimetro_PH

dim ADCResult as longword
dim voltage as word[5]
dim ADCResultV as longword
dim voltageV as string[5]
dim display as string[5]


sub procedure GlobInit
    'ANSEL = 1
    'ANSELH = 0
    TRISA = %00000011
    LCD_Init(PORTD)
    LCD_Cmd(LCD_CLEAR)
    LCD_Cmd(LCD_CURSOR_OFF)
    LCD_Out(2, 1, "Voltage:")
    LCD_Chr(2, 16, "V")
    display[1] = "."

end sub

main:
     GlobInit

positive:
     while true
           if ADC_READ(0) = 0 then
           goto negative
           end if

           ADCResult = (ADC_Read(0) * 500) >> 10
           voltage[0] = ADCResult div 100
           voltage[1] = (ADCResult div 10) mod 10
           voltage[2] = ADCResult mod 10
           ADCResultV = (ADC_Read(0) * 5000) >> 10
           voltageV[2] = ADCResultV mod 10

           display[0] = voltage[0] + 48
           display[2] = voltage[1] + 48
           display[3] = voltage[2] + 48
           display[4] = voltageV[2] + 48

           LCD_Out(2, 1, "Voltage:")
           LCD_Chr(2,9, " ")
           LCD_Chr(2, 16, "V")
           display[1] = "."
           LCD_Out(2, 10, display)
           
      wend

negative:
while true
           if ADC_READ(1) = 0 then
           goto positive
           end if

           ADCResult = (ADC_Read(1) * 500) >> 10
           voltage[0] = ADCResult div 100
           voltage[1] = (ADCResult div 10) mod 10
           voltage[2] = ADCResult mod 10
           ADCResultV = (ADC_Read(1) * 5000) >> 10
           voltageV[2] = ADCResultV mod 10

           display[0] = voltage[0] + 48
           display[2] = voltage[1] + 48
           display[3] = voltage[2] + 48
           display[4] = voltageV[2] + 48
           LCD_Chr(2,9, "-")
           LCD_Out(2, 10, display)

wend


end.

adc0 will listen to positive voltages and adc1 will listen to negative voltages inverted by LM741.

sahu said:
program softwarefor887Voltmeter
can u post hex code & ckt diagram also ?

Hex file is here, but Im trying to discover how do save the diagram as an image. Sorry.
 

Code:
positive: 
     while true 
           if ADC_READ(0) = 0 then 
           goto negative 
           end if 

           ADCResult = (ADC_Read(0) * 500) >> 10 
           voltage[0] = ADCResult div 100 
           voltage[1] = (ADCResult div 10) mod 10 
           voltage[2] = ADCResult mod 10 
           ADCResultV = (ADC_Read(0) * 5000) >> 10 
           voltageV[2] = ADCResultV mod 10 

           display[0] = voltage[0] + 48 
           display[2] = voltage[1] + 48 
           display[3] = voltage[2] + 48 
           display[4] = voltageV[2] + 48 

           LCD_Out(2, 1, "Voltage:") 
           LCD_Chr(2,9, " ") 
           LCD_Chr(2, 16, "V") 
           display[1] = "." 
           LCD_Out(2, 10, display) 
            
      wend 

negative: 
while true 
           if ADC_READ(1) = 0 then 
           goto positive 
           end if 

           ADCResult = (ADC_Read(1) * 500) >> 10 
           voltage[0] = ADCResult div 100 
           voltage[1] = (ADCResult div 10) mod 10 
           voltage[2] = ADCResult mod 10 
           ADCResultV = (ADC_Read(1) * 5000) >> 10 
           voltageV[2] = ADCResultV mod 10 

           display[0] = voltage[0] + 48 
           display[2] = voltage[1] + 48 
           display[3] = voltage[2] + 48 
           display[4] = voltageV[2] + 48 
           LCD_Chr(2,9, "-") 
           LCD_Out(2, 10, display) 

wend

You can improve this part to:
Code:
while true

     	while ADC_Read(1) = 0

           ADCResult = (ADC_Read(0) * 500) >> 10 
           voltage[0] = ADCResult div 100 
           voltage[1] = (ADCResult div 10) mod 10 
           voltage[2] = ADCResult mod 10 
           ADCResultV = (ADC_Read(0) * 5000) >> 10 
           voltageV[2] = ADCResultV mod 10 

           display[0] = voltage[0] + 48 
           display[2] = voltage[1] + 48 
           display[3] = voltage[2] + 48 
           display[4] = voltageV[2] + 48 

           LCD_Out(2, 1, "Voltage:") 
           LCD_Chr(2,9, " ") 
           LCD_Chr(2, 16, "V") 
           display[1] = "." 
           LCD_Out(2, 10, display) 
            
	wend 


	while ADC_Read(0) = 0


           ADCResult = (ADC_Read(1) * 500) >> 10 
           voltage[0] = ADCResult div 100 
           voltage[1] = (ADCResult div 10) mod 10 
           voltage[2] = ADCResult mod 10 
           ADCResultV = (ADC_Read(1) * 5000) >> 10 
           voltageV[2] = ADCResultV mod 10 

           display[0] = voltage[0] + 48 
           display[2] = voltage[1] + 48 
           display[3] = voltage[2] + 48 
           display[4] = voltageV[2] + 48 
           LCD_Chr(2,9, "-") 
           LCD_Out(2, 10, display) 

	wend
wend

Your code will work fine, the latter just seems more organized.

Hope this helps.
Tahmid.
 

Hmmm, hi... Im reading the post and Im wondering why to repeat the whole block of code in the conversion of the readed data to ASCII... It would be more efficient and faster to write the common conversion one time and the negative/positive reading in the if then else structure...

PD: Its just a point of view, but perhaps Im wrong... Im a newbie in PICs.

PD2: Wich application did you used to make the schematic????... It could be Proteus??? If its so, you only have to use the option File/Export Graphics and convert your schematic as your wishes.

Have a nice day and hello to all of you.
 

Hi,
Just coded this, should work:
Code:
program voltmeterplusminus5v

dim ADCResult as longword
dim voltage as word[5]
dim ADCResultV as longword
dim display as string[5]


sub procedure GlobInit 
    'ANSEL = 1 
    'ANSELH = 0 
    TRISA = %00000011 
    LCD_Init(PORTD) 
    LCD_Cmd(LCD_CLEAR) 
    LCD_Cmd(LCD_CURSOR_OFF) 
    LCD_Out(2, 1, "Voltage:") 
    LCD_Chr(2, 16, "V") 
    display[1] = "." 

end sub 

main: 

GlobInit

while true
	if ADC_Read(0) = 0 then
		ADCResult = ADC_Read(1)
		LCD_Chr(2, 9, "-")
	end if

	if ADC_Read(1) = 0 then
		ADCResult = ADC_Read(0)
		LCD_Chr(2, 9, " ")
	end if

	ADCResult = (ADCResult * 5000) >> 10

	voltage[0] = ADCResult div 1000
	voltage[1] = (ADCResult div 100) mod 10
	voltage[2] = (ADCResult div 10) mod 10
	voltage[3] = ADCResult mod 10

	display[0] = voltage[0] + 48
	display[2] = voltage[1] + 48
	display[3] = voltage[2] + 48
	display[4] = voltageV[2] + 48

	LCD_Out(2, 10, display)

wend
end
You can try this. As albejanon said, it is more efficient.

Hope this helps.
Tahmid.
 



only 0v > +5v voltimeter not -5 to +5 v/is my req.
 


Hi... Yes, thats what I wanted to said... thanks Tahmid.
 

See this link:

**broken link removed**

Mr.Cube
 

hi everybody
i m working on strain gauge project .my out put voltage from -2.5V to +2.5V,which i have scaled from 0V to +5V .
so how can i program it.
like if adc_result=read_adc();
so after this how can i program
thanks &regrads
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…