PDA

View Full Version : PIC16F877A, How to add timer delays on output?



joseph
- 2nd March 2011, 19:50
I have two analog input, one for a humidity sensor and one for soil moisture, once the analog reading on humidity sensor falls an output is driven high, and for the soil moisture when the analog reading get's high another output is driven high and the PWM servo position is changed to open a ball valve



here's my circuit:
http://i51.tinypic.com/15plvvc.jpg

and my code:


@ DEVICE pic16f877a,WDT_ON, PWRT_ON, BOD_ON
DEFINE OSC 4
define ADIN_RES 10
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

RLH VAR word
SLM var word
position var word


TRISA = %00000011
TRISB = %00000000
TRISD.0 = %0
TRISD.1 = %0
ADCON0 = %11000101
ADCON1 = %10000000
low portd.7



START:

ADCIN 0 , RLH
ADCIN 1 , SLM


IF RLH =< 621 then
high PORTD.5
else
low PORTD.5
endif

IF SLM => 621 then
high PORTD.6
position = 100
else
low PORTD.6
position = 170
endif



PULSOUT PORTD.7, position
pause 18


GOTO START

the circuit and code posted above works in simulation and in actual testing

my problem is i need to add a delay on each outputs, like a one shot timer once an output is triggered it will wait for 30 seconds or 1 minute to turn off again, cause the pause command i think is inappropriate for my application it kinda mess my PWM timing that controls the PWM servo

Can someone please guide me on these?

TIA! :)

cncmachineguy
- 2nd March 2011, 20:32
@ DEVICE pic16f877a,WDT_ON, PWRT_ON, BOD_ON
DEFINE OSC 4
define ADIN_RES 10
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

RLH VAR word
SLM var word
position var word
COUNT1 VAR BYTE ' COUNTER FOR PORTD.5
COUNT2 VAR BYTE ' COUNTER FOR PORTD.6
TRISA = %00000011
TRISB = %00000000
TRISD.0 = %0
TRISD.1 = %0
ADCON0 = %11000101
ADCON1 = %10000000
low portd.7

COUNT1 = 0
COUNT2 = 0

START:

ADCIN 0 , RLH
ADCIN 1 , SLM

IF (PORTD.5=1) AND (COUNT1<50) THEN SKIP1 '50 LOOPS WILL BE ~1 SEC
IF RLH =< 621 then
high PORTD.5
else
low PORTD.5
endif
COUNT1 = 0

SKIP1:
IF (PORTD.6=1) AND (COUNT2<50) THEN SKIP2
IF SLM => 621 then
high PORTD.6
position = 100
else
low PORTD.6
position = 170
endif
COUNT2 = 0

SKIP2:

PULSOUT PORTD.7, position
pause 18
COUNT1 = COUNT1 + 1
COUNT2 = COUNT2 + 1
GOTO START

QUOTE]
I made some assumptions here. I assumed if you wanted to keep them high, you didn't need to check the sensor readings.

I used 50 for the loop count because of this: pulseout will be between 1-2 mSec, then an 18mSec pause. this is 19-20 mSec. * 5= .1sec * 10 = 1 sec. This won't be exact, but you can play with the numbers to get it right

joseph
- 6th March 2011, 11:01
thanks cncmachineguy! the code posted above works i just change the byte variable into a word and i can time upto my requirements :D




however i have another similar project that is having problem, the code is:


@ DEVICE pic16f877a,WDT_ON, PWRT_ON, BOD_ON
DEFINE OSC 8
define ADIN_RES 10
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

TMP VAR word
SLM var word
delay var word


COUNT1 VAR word ' COUNTER FOR PORTD.5
TRISA = %00000011
TRISB = %00000000
TRISD.0 = %0
TRISD.1 = %0
ADCON0 = %11000101
ADCON1 = %10000000


COUNT1 = 0


START:
delay = 0
ADCIN 0 , SLM
ADCIN 1 , TMP

delay =((tmp * (46/200)) + 8)*384
if tmp =< 30 THEN
DELay = 3625
ELSE
IF tmp => 80 THEN
delay = 10244
ELSE
delay = 384 * ((tmp * (46/200)) + 8) / 2
ENDIF
ENDIF

IF(PORTb.5=1) AND (COUNT1<delay) THEN skip1
IF SLM => 621 then
high PORTb.5
else
low PORTb.5
endif
COUNT1 = 0



SKIP1:
pause 20
COUNT1 = COUNT1 + 1


GOTO START



i need to vary the output delay based on the ambient temperature, but the result is inaccurate

joseph
- 6th March 2011, 18:18
UP! :


@ DEVICE pic16f877a,WDT_ON, PWRT_ON, BOD_ON
DEFINE OSC 8
define ADIN_RES 10
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

TMP VAR word
SLM var word
delay var word


COUNT1 VAR word ' COUNTER FOR PORTD.5
TRISA = %00000011
TRISB = %00000000
TRISD.0 = %0
TRISD.1 = %0
ADCON0 = %11000101
ADCON1 = %10000000


COUNT1 = 0


START:
delay = 0
ADCIN 0 , SLM
ADCIN 1 , TMP


if tmp =< 30 THEN
DELay = 3625
ELSE
IF tmp => 80 THEN
delay = 10244
ELSE
delay = 384 * (tmp * (46/200) + 8)
ENDIF
ENDIF

IF SLM => 621 then
high PORTb.5
else
low PORTb.5
endif
COUNT1 = 0

lod:
IF (PORTb.5=1) AND (COUNT1<DELAY) THEN skip1
goto start
SKIP1:
pause 100
COUNT1 = COUNT1 + 1
goto lod

tried the code posted above with no luck :(

cncmachineguy
- 6th March 2011, 18:38
Can you give us any clues? What does it do or not do?

joseph
- 6th March 2011, 18:49
the circuit has two analog inputs, SLM and TMP, if SLM reaches the value 621 then PORTB.5 is turned on for a period of time proportional to TMP with the formula 384 * (tmp * (46/200) + 8)

the minimum time is 3625 seconds if TMP is less than 30, maximum is 10244 if TMP is equal or higher than 80

vref is set to VDD