PDA

View Full Version : any ideas from PIC basic experts



capix
- 25th December 2005, 19:45
hi everyone

well im kind of doing some test using PIC16F877A here...test on ir sharp sensors...well as far from what im done, im able to display the range with the bargraph as the indicators...my problem is, i want to set an alarm for range 14cm and below but before it set the alarm it will countdown for 15sec...

here for short flow:

if (range<15) -> countdown start for 15sec -> check again if (range<15) -> if yes then high LED on portB.7 ->if range>15 take reading again or low LED

problem: when range<15 is detect countdown will engage, but at the countdown if there has a status change range>14 before countdown reach 0 the LED still HIGH or blink...i want if there has a status change in the range there will no blink...

code:

INCLUDE "LCDbar_INC.bas"

'************************************************* ***************

define OSC 4

' Define LCD connections
DEFINE LCD_DREG PORTC ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTD ' Register Select Port
DEFINE LCD_RSBIT 0 ' Register Select Bit
DEFINE LCD_EREG PORTD ' Enable Port
DEFINE LCD_EBIT 1 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command Delay time in uS was 2000
DEFINE LCD_DATAUS 50 ' Data Delay time in uS was 50

'************************************************* ***************

' Allocate variables
a var byte

Loop1 VAR word
Loop2 VAR word
Delay VAR word
countD Var Word
LED var PORTB.7

'************************************************* ***************

TRISA = %11111111
ADCON1 = %00000000 ' Set PortA 0, 1, 3 to A/D inputs
Pause 100 ' Wait for LCD to start
Goto main ' Skip subroutines

main:
call loop
mainloop:
countD = 15
Gosub geta ' Get A value

'************************************************* ***************

Delay = 35
Lcdout $fe,1,"a = " ' Send to LCD
FOR Loop1 = a to a
;syntax-BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Loop1, 2, 0, 16, 30, lines
GOSUB Show_a
PAUSE Delay
NEXT Loop1

if (a<15) then high led
if (a<15) then call countdown
if (a>14) then low led

FOR Loop1 = a to a STEP -1
@ BARgraph _Loop1, 2, 0, 16, 30, lines
GOSUB Show_a
PAUSE Delay
NEXT Loop1

Goto mainloop ' Do it forever

'************************************************* ***************

geta: ADCIN 0, a ' Read channel 0 to adval
pause 15
a = a / 9 + 2
return

'************************************************* ***************

loop: Lcdout $fe,1 ' Clear LCD screen
Lcdout "Range" ' Display Hello
Lcdout $fe,$c0+6 ' Clear LCD screen
Lcdout "Controller"
Pause 5000 ' Wait .5 second
Lcdout $fe,1
Lcdout $fe,$c9 ' Clear LCD screen
Lcdout "Ver 1.0"
Pause 5000 ' Wait .5 second
Delay = 110
LCDOUT $FE,1,"LOADING"
Pause 1000
FOR Loop1 = 0 to 100
;syntax-BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Loop1, 2, 0, 16, 100, lines
GOSUB ShowValue
PAUSE Delay
NEXT Loop1
PAUSE 2000


ShowValue
LCDOUT $FE,$80+12,DEC BAR_value,"%"
RETURN

Show_a
LCDOUT $FE,$80+4,DEC BAR_value," ","cm range"," "
RETURN

countdown
FOR loop1 = 15 to 0 step -1
LCDOUT $FE,$c0," countdown : ", dec countd," "
countd = countd - 1
pause 1000
next loop1
return


any help and ideas would be appreciate....thanx

best regards

capix

arniepj
- 25th December 2005, 23:50
If I understand your question,it looks as though your code is in the count down loop and cannot be updated with a status change until the loop is complete.I also don't understand your use of call as the manual suggest usage for accessing assembly code.With the amount of time delays your code requires,I would suggest using the timer interrupt and accumulate ticks.This will let your program run faster,plus if a status change occurs your code can respond properly.There are demo's of the timer interrupt either with PBP or on Microengineerings web site.

capix
- 26th December 2005, 04:12
the timer interrupt and accumulate ticks.

hmm...i see...thanx for ur ideas i will try to check the example of timer interrupt...to tell the truth im still novice at the pic basic pro...basically how do i use the timer interrupt to implement to this code?

dmairspotter
- 26th December 2005, 14:47
If I understand your desired function correctly, maybe this idea?

counter var byte ' a counter for the alarm condition

mainloop:

gosub getA ' get the range value

'display the bargraph and value here

if a<15 then
counter=counter+1 'if range is low increment counter
else
counter=0 'otherwise reset the counter
endif

if counter>150 then
high led 'if the counter has exceeded 150 the turn the alarm on
else
low led ' turn the alarm off
endif

pause 100 ' wait 1/10 sec

goto mainloop ' do it again


you might have to add a little code to prevent counter from rolling over to 0, depending on your application.

This should force the alarm on after 15 continuous seconds of low range condition., and turn the alarm off immediately that the range exceeds 15

capix
- 26th December 2005, 15:53
dear arniepj

i have try what u had told me...looks like its works but why my LED keep blinking when its countdown the numbers and the countdown doesnt start at 15sec but it start randomly sometime its start at 3 sometime 10...

here's the code:


' include .bas file
Include "MODEDEFS.bas"
INCLUDE "LCDbar_INC.bas"

'************************************************* ***************

define OSC 4

' Define LCD connections
DEFINE LCD_DREG PORTC ' LCD Data Port
DEFINE LCD_DBIT 0 ' Starting Data Bit
DEFINE LCD_RSREG PORTD ' Register Select Port
DEFINE LCD_RSBIT 0 ' Register Select Bit
DEFINE LCD_EREG PORTD ' Enable Port
DEFINE LCD_EBIT 1 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command Delay time in uS was 2000
DEFINE LCD_DATAUS 50 ' Data Delay time in uS was 50

'************************************************* ***************

' Allocate variables
a var byte

Loop1 VAR word
Loop2 VAR word
Delay VAR word
countD Var Word
second var byte
ticks var byte
update var byte
i var byte
LED var PORTB.7
@ device WDT_OFF

'************************************************* ***************

second = 0
ticks = 0
update = 1

'************************************************* ***************

OPTION_REG = $55 ' Set TMR0 configuration and enable PORTB pullups
INTCON = $c0 ' Enable TMR0 interrupts
On Interrupt Goto tickint

TRISA = %11111111
ADCON1 = %00000000 ' Set PortA 0, 1, 3 to A/D inputs
Pause 100 ' Wait for LCD to start

Goto main ' Skip subroutines

'************************************************* ***************

main:
low PORTB
Lcdout $fe,1 ' Clear LCD screen
Lcdout "Range" ' Display Hello
Lcdout $fe,$c0+6 ' Clear LCD screen
Lcdout "Controller"
Pause 5000 ' Wait .5 second
Lcdout $fe,1
Lcdout $fe,$c9 ' Clear LCD screen
Lcdout "Ver 1.0"
Pause 5000 ' Wait .5 second
Delay = 110
LCDOUT $FE,1,"LOADING"
Pause 1000
FOR Loop1 = 0 to 100
;syntax-BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Loop1, 2, 0, 16, 100, lines
GOSUB ShowValue
PAUSE Delay
NEXT Loop1
PAUSE 2000

'************************************************* ***************

mainloop:
Gosub geta ' Get A value
Delay = 35
Lcdout $fe,1,"a = " ' Send to LCD
FOR Loop1 = a to a
;syntax-BARgraph Value, Row, Col, Width, Range, Style
@ BARgraph _Loop1, 2, 0, 16, 30, lines
GOSUB Show_a
PAUSE Delay
NEXT Loop1

if (a<15) then gosub mainloop2
if (a>14) then mainloop

FOR Loop1 = a to a STEP -1
@ BARgraph _Loop1, 2, 0, 16, 30, lines
GOSUB Show_a
PAUSE Delay
NEXT Loop1

Goto mainloop ' Do it forever

'************************************************* ***************

geta: ADCIN 0, a ' Read channel 0 to adval
pause 15
a = a / 9 + 2
return

'************************************************* ***************

mainloop2:
Gosub geta

if (a<15) then decmin
if (a>14) then mainloop

chkup: If update = 1 Then
LCDOUT $fe,1,$c0," countdown : ", dec second
update = 0 ' Screen updated
Endif
Goto mainloop2 ' Do it all forever

decmin: second = second - 1 ' Decrement minutes
If second >= 15 Then
second = 14
Endif
pause 900
Goto debounce

debounce: ' Debounce and delay for 250ms
For i = 1 to 25
Pause 10 ' 10ms at a time so no interrupts are lost
Next i
update = 1 ' Set to update screen
Goto chkup

'************************************************* ***************

' Interrupt routine to handle each timer tick
disable ' Disable interrupts during interrupt handler
tickint:
ticks = ticks + 1 ' Count pieces of seconds
If ticks < 61 Then tiexit ' 61 ticks/second (16.384ms per tick)

' One second elasped - update time
ticks = 0
second = second + 1
If second >= 15 Then
second = 0
Endif

update = 1 ' Set to update LCD

tiexit: INTCON.2 = 0 ' Reset timer interrupt flag
Resume

'************************************************* ***************

ShowValue
LCDOUT $FE,$80+12,DEC BAR_value,"%"
RETURN

Show_a
LCDOUT $FE,$80+4,DEC BAR_value," ","cm range"," "
RETURN

capix
- 26th December 2005, 16:10
If I understand your desired function correctly, maybe this idea?

counter var byte ' a counter for the alarm condition

you might have to add a little code to prevent counter from rolling over to 0, depending on your application.

This should force the alarm on after 15 continuous seconds of low range condition., and turn the alarm off immediately that the range exceeds 15

thanx dmairpotter...