PDA

View Full Version : Help for my project(16f877,2x16LCD,)



karamastik
- 19th March 2008, 17:12
Hello ! As you see i'm a newbee .
(Merhaba arkadaşlar.)
I've started to learn about a pic for about a month ago .
I learned to write something to the LCD with 2 lines(rows).
This was a first step for me to learn the 'p' of pic. :)
I'm an undergraduate student and my final project is to show the voltage change from the output of LM358 IC with 16f877 with using 2x16 LCD.
I'll show the change as the bar graph.
I have square wave 15V from the LM358 IC output.
The output mostly stays about 15V , so the ADC will be vice-versa.
I learned that 16f877 has 10 channels ADC , so we have 0-1023 interval.
As i said above , the peak of the signal is 15V and as i said above it's a square wave.
The most important point is , the ADC must be vice-versa.
For example : for my 15-14V input , the first interval must be 0-68 , for 13-12V input , second interval : 68-136 ...
I'm using pic basic pro and I don't know how to write a program .
And i read about LCD bar graphs , but i couldn't make it. ( http://www.picbasic.co.uk/forum/showthread.php?t=2359 )
Here is what i learned about pic :



@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC


DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2

DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 2
DEFINE ADC_SAMPLEUS 100
ADCON1=%10001110


TRISB=0
TRISE=0


LOW PORTE.2


LCDOUT $FE,1
PAUSE 200

LCDOUT $FE,2,"PIC BASIC"
LCDOUT $FE,$C0,"PRO"

END



I really need help .
Thank you :)

mackrackit
- 19th March 2008, 17:27
First you will need a 3 to 1 voltage divider so that 15 volts looks like 5.

Then this should get you started with ADC.
http://www.rentron.com/PICX2.htm

karamastik
- 19th March 2008, 17:40
Hmm , thank you . :)
Let's think , if i want to make it with 5V not 15V .
I just want to learn the main idea.
I think , if i learn the main idea , maybe i can go on with 15V.
In fact , i can change the output voltage from 1.67 V to 15V .
In this project we wanted to have good resolution , and we decided to get 15V from output.
As i said , let's think , the input changes 0-5V.
Thank you :)
By the way , my main project was to build an cell phone detector and i did it with a small circuit. In this circuit there are 2 same RF subcircuits ; one for the left side detection and the other side is for the right side detection.
We amplified the signals with LM358 and we may get output from 1.67 to 15V . ( with gain changing)
Finally we want to show the voltage change with the LCD bar graphs.
The first line of the LCD will be left channel and the second line will be the right channel .

mackrackit
- 19th March 2008, 18:06
Do small steps.
You have the LCD working.
Now make the ADC work with 8 bit resolution.
Then do two ADC channels.
Then work on 10 bit for more accuracy.
Then work on the bar graph.

karamastik
- 19th March 2008, 20:22
Okay ,
for ADC :



PORTA = %00000001
RAW var word ' the input voltage
volt var word
Mvolt var byte

START:

ADCIN 0,RAW ' Analog read from #ch0 and move it to RAW
LOOK : IF ADCON0.2=1 THEN LOOK ' when ADC finished ADCON0.2=0
' for 0-5V , 0-1024 - > 5/1024 = 0.0048828 = very small number
'0.0048828*1000 = 4.8828 ( raw/V)
'4.8828 * 256 = 1250 ( 1250 = 5/1024 * 256*1000 ) we made 32bits calculation
Volt=(Raw*/1250)/100
MVolt=Volt//10 ' Mvolt = Volt mod 10
Volt=Volt/10
LCDOUT $FE,2,"VOLT=",#VOLT,",",#Mvolt
PAUSE 500
GOTO START


I tried to read the voltage from LM358 and to write the LCD as Volt.Mvolt
I'm waiting for help.
Thanks.

karamastik
- 19th March 2008, 22:36
Sorry for the flood , but i must ;
i changed the ADC codes , but volt variable does not accept floating numbers :



START:

ADCIN 0,RAW
LOOK : IF ADCON0.2=1 THEN LOOK
Volt=(0,0048828125*RAW)*1000
MVolt=Volt//10 ' Mvolt = Volt mod 10
LCDOUT $FE,2,"VOLT=",#VOLT,",",#Mvolt
PAUSE 500
GOTO START

skimask
- 20th March 2008, 03:02
i changed the ADC codes , but volt variable does not accept floating numbers :
Neither does anything else in PBP...

PORTA=1 : RAW var word : volt var long
START: ADCIN 0,RAW : IF ADCON0.2=1 THEN START
Volt = Raw * 4882813 'round up
LCDOUT $FE , 2 , "V=" , DEC ( volt dig 9 ) , "." , DEC ( volt dig 8 ) , DEC ( volt dig 7 )
LCDOUT DEC ( volt dig 6 ) , DEC ( volt dig 5 ) , DEC ( volt dig 4 ) , DEC ( volt dig 3 )
LCDOUT DEC ( volt dig 2 ) , DEC ( volt dig 1 ) , DEC ( volt dig 0 ) 'get all them digits in there
PAUSE 500
GOTO START

karamastik
- 20th March 2008, 18:04
I was at school ,sorry for the delay. :)
Thanks for the help but in pbp , i saw that there is no " long " . :(
It gives error.

skimask
- 20th March 2008, 18:20
I was at school ,sorry for the delay. :)
Thanks for the help but in pbp , i saw that there is no " long " . :(
It gives error.

There is if you upgrade to PBP 2.50a.

karamastik
- 21st March 2008, 10:55
Hello again ! :)
I changed my code like that :
(Arkadaşlar yok mu yardımcı olacak ? )



@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC

TRISA=%00000001
TRISB=0
TRISE=0


LCDOUT $FE, $40, $00, $1F, $1F, $1F, $1F, $1F, $1F, $00

bar var byte
raw var word
I var byte


DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 2
DEFINE ADC_SAMPLEUS 100

ADCON1=%10001110
LOW PORTE.2

LCDOUT $FE,1
PAUSE 200


ADCIN 0,raw
bar=(1023-raw)/64
lcdout $fe,2
for I=1 to bar
lcdout ,255
next

END

Is the idea correct , isn't it ?
But it does not work :(

skimask
- 21st March 2008, 15:08
Are you using a 16F877 or 16F877A?
Probably doesn't matter much, but, put the config registers first, then your define's, then you variables, then your code.


@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 2
DEFINE ADC_SAMPLEUS 100
bar var byte:raw var word:I var byte
trisa=1:trisb=0:trise=0:lcdout $FE,$40,0,$1F,$1F,$1F,$1F,$1F,$1F,0,$fe,1
ADCON1=$8e:PAUSE 200:ADCIN 0,raw:bar=(1023-raw)/64:lcdout $fe,2:for I=1 to bar
lcdout ,255:next I
END

Looks like something might be missing from that lcdout command...(and the next I shouldn't matter, but it might).
How do you know you ADCIN is actually reading something?
Have you tried just reading the RAW value and displaying it in a loop?
lcdout DEC3 RAW

karamastik
- 21st March 2008, 19:37
Hello :)
I'm using 16f877;
i changed the lcdout command like yours and
here , i checked for the ADC reading:


@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 2
DEFINE ADC_SAMPLEUS 100

bar var byte
raw var word
I var byte

trisa=1
trisb=0
trise=0

lcdout $FE,$40,0,$1F,$1F,$1F,$1F,$1F,$1F,0,$fe,1
ADCON1=$8e
PAUSE 200
ADCIN 0,raw
bar=(1023-raw)/64
for I=1 to bar
lcdout dec3 raw
next I
END

there is a 16 digit number : 2732732732732732 and does not change;
if i reset the pic , there is another number 2742742742742742 , so goes on ...
I think i it couldn't read raw.
And the number does not change;maybe my loop is wrong :(

skimask
- 21st March 2008, 19:56
Try this...don't know if it'll work or not, but it should put a value on your LCD that matches the A/D result register, assuming you have something wired to PortA.0, like the wiper of a pot, with +5v on one side and ground on the other...


@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225
raw var word : trisa=1 : trisb=0 : trise=0 : adcon0 = $c1 : adcon1 = $ce
main: adcon0.2 = 1 'start A/D conversion
wait_for_it: if adcon0.2 = 1 then wait_for_it 'wait for A/D to finish
raw.highbyte = adresh : raw.lowbyte = adresl
lcdout $fe , 1 , DEC4 raw : goto main
END

karamastik
- 21st March 2008, 19:56
By the way , i applied the codes from the " LCD BARgraphs" subject:


; Initialize your hardware and LCD first.

DEFINE ADC_BITS 8 ' Number of bits in ADCIN result
ADCON1.7 = 1 ' Right Justify AD result

INCLUDE "LCDbar_INC.bas" ' Include the BARgraph routines

Value VAR WORD ' Must be a WORD even though AD is 8bit

LCDOUT $FE, 1 ' Clear Screen

Loop1:
ADCIN 0, Value
LCDOUT $FE,2,"Value = ",DEC Value," "
; syntax- BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Value, 2, 0, 16, 255, lines
GOTO Loop1


It works but the lines change very fast and i can't recognize also the 'value' word changes ?
In fact , i don't need value, i just need line bars.

skimask
- 21st March 2008, 19:58
By the way , i applied the codes from the " LCD BARgraphs" subject: ?
In fact , i don't need value, i just need line bars.

If you can't get the value of your A/D to change....how do you expect to see changing bars?

Small steps....

I'm done....

karamastik
- 21st March 2008, 20:13
Yes , you are wright ;it should read the analog value.
I have cell phone detector , and whene there is no cell phone activity ; i have 5V at the output.When there is a phone activity , my circuit detects the electromagnetic wave thus the current increases at the output .
As the current increases , the voltage drops from 5V to approximately 3.8V .
I must see no bars at 5V , and must see full bars at appr. 3.8V .
I wish i'm understood. :)
Thank you for your helps.
Can you explain , why the bars are appearing very fast ?
I can't see them.They are like a ghost.
I'm using 20MHz pic , does it differ ?
I think it mustn't .
I won't stop, will try.If i stop, my school stops me :(
Thanks again :)

karamastik
- 21st March 2008, 20:15
Try this...don't know if it'll work or not, but it should put a value on your LCD that matches the A/D result register, assuming you have something wired to PortA.0, like the wiper of a pot, with +5v on one side and ground on the other...


@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, HS_OSC
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 1
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_RWREG PORTE
DEFINE LCD_RWBIT 2
DEFINE LCD_BITS 8
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 1000
DEFINE LCD_DATAUS 225
raw var word : trisa=1 : trisb=0 : trise=0 : adcon0 = $c1 : adcon1 = $ce
main: adcon0.2 = 1 'start A/D conversion
wait_for_it: if adcon0.2 = 1 then wait_for_it 'wait for A/D to finish
raw.highbyte = adresh : raw.lowbyte = adresl
lcdout $fe , 1 , DEC4 raw : goto main
END


There is no activity on the screen :(

skimask
- 21st March 2008, 20:17
There is no activity on the screen :(

change lcdout $fe,1,.........
to
lcdout $fe , $80

Hook up a potentiometer connected as I described earlier and try that....

SMALL STEPS!!!!

karamastik
- 21st March 2008, 20:58
ADC works . :)
I connected the Vcc of pic to the portA.0 and it shows 1023 .
After that ; i tried


; Initialize your hardware and LCD first.

DEFINE ADC_BITS 8 ' Number of bits in ADCIN result
ADCON1.7 = 1 ' Right Justify AD result

INCLUDE "LCDbar_INC.bas" ' Include the BARgraph routines

Value VAR WORD ' Must be a WORD even though AD is 8bit

LCDOUT $FE, 1 ' Clear Screen

Loop1:
ADCIN 0, Value
LCDOUT $FE,2,"Value = ",DEC Value," "
; syntax- BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Value, 2, 0, 16, 255, lines
GOTO Loop1

The bars are ok , don't flickr
but the word "value" always flickering , why ?
And whene there is no input to the portA.0 , the value becomes 276 and there are still full bars ? (I know there are too many questions :( , but i want to learn )

It seems , the problem is my circuit output :(
By the way , as i said before , whene there is 5V , i don't want any bars , there must be full bars at 3.9V
How can i change this code to run like for my project or there must be a different code ?



Loop1:
ADCIN 0, ham
LCDOUT $FE,2,"Value = ",DEC ham," "
; syntax- BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _ham, 2, 0, 16, 255, lines

Goto Loop1

Thank you very much again.

skimask
- 21st March 2008, 21:30
but the word "value" always flickering , why ?
Probably because something is overwriting it or clearing the screen, then you re-print the VALUE on the LCD...


as i said before , whene there is 5V , i don't want any bars , there must be full bars at 3.9V
Simple math
Minimum = 5V (1023 ADC counts)
Maximum = 3.9V (798 ADC counts)
Spread = 1.1V (225 counts)
raw = 1024 - raw 'flips the value upside-down
raw = raw / 14 '14 counts per box, assuming 16 boxes
Surely you can do something with that...

karamastik
- 21st March 2008, 21:38
Okey my friend , thank you for your patience and for your helps :)
Today is enough for me ;
i'm working about this project from 9 o'clock to now.
I think , it's time to make my brain free.
And one last question ; i don't know that you are interested in integrated circuits; if you are ; i want to ask something.
I have 2 op-amps LM358 and i learned that , the maximum supply current for LM358 is 600mA . I have a power supply with 6-9-12-15 adjustable ; and it says , it can give a current of 2.5A
So, if i connect it to my op-amps , do they blow out ?
Thank you .

mackrackit
- 21st March 2008, 23:29
The op amps will be fine. The PS rating is the maximum it can handle, the op amps will only draw what they need.

As for the flicker, you need a pause of maybe 100 in the loop.