PDA

View Full Version : Do Loop



skybox
- 15th December 2012, 14:34
I have a project with a few relays and a 12 volt dc motor. The motor opens and closes a door based on a light and dark (LDR) The door has hall sensors to limit travel. For the most part everything works fine but every so often the door starts to open and then the program goes into a loop or crashes. I compiled the program with the watchdog timer off. Since this start happening I did some research and found that without the watchdog timer employed the program can be reset after a per-determined time period. Obviously, I need to turn watchdog on. However, I have a question about my code that may be contributing to the problem.

Below is a sample of a "DO Loop" I use:

If (Light = 1) and (DoorClosed = 0) then

Relay2 = 1
DO
Loop until DoorOpen = 0
Relay2 = 0

End if

Notice there is no statement after "DO". It goes immediately to the "loop until DoorOpen = 0." This does work but I'm wondering if this might be contributing to the problem. Is this a proper way of using the DO Loop? That is without a statement in between DO and Loop?

longpole001
- 15th December 2012, 16:09
i would not think its a problem , but you can always try using while wend loop see if changes the problem

while dooropen <> 0
wend

spcw1234
- 16th December 2012, 01:30
Using while wend is a better method, but nothing shown here should cause your problem. Can you share all of your code? I had a similar issue by not exiting a subroutine properly, the program worked for a while then would eventually crash. It took me a while to pin point it.

skybox
- 16th December 2012, 04:36
Shawn,

Thanks for the reply. I do have a question concerning your answer. In the PBP manual it states the "While...Wend" has been deprecated and to use the "DO...Loop" instead. I never completely trust manuals because most become outdated with code updates. As such, I'd very much appreciate an elaboration as to why I should use the "While...Wend' when the manual states otherwise.

Thanks

Skybox

SteveB
- 16th December 2012, 05:42
For what you are doing, you can also use this method:


WaitForDoor:
IF DoorOpen <> 0 THEN WaitForDoor

mister_e
- 16th December 2012, 08:53
WHILE DoorOpen : WEND
'
' or
Repeat : Until !DoorOpen
'
' or
SitAndSpin: If DoorOpen then SitAndSpin
'
' or
Do Until !DoorOpen : Loop
'
' or
do : Loop WHILE DoorOpen

As far as I'm aware of, PBP take care of the WatchDog timer, so it shouldn't be an issue...

skybox
- 17th December 2012, 14:11
Thanks everyone for your assistance. The problem end up being associated with the LDR. I have the output of the LDR circuit going to the comparator of the PIC. The result is then assigned to a variable and subsequent code is used to make decisions. Here is a simplified example of my original code- VL is the variable.

For I = 1 to 20

Pause 500
ADCIN 0, VL

If VL => 300 then
Light = 1
Indicator LED = 1
Endif

If VL =< 100 then
Light = 0
IndicatorLED = 0
Endif

Next I

My thinking was that I could bypass the threshold that exists in a LDR between light and dark by inserting a gap of 100 ( difference between 300 and 100) and a half second Pause in the For / Next loop. I used the For/Next loop count to 20 along with the Pause to ensue the light change was permanent and not from some errant source.

This did work but during the time VL hovered around the threshold zone (between 300 and 100) I start receiving unpredictable results. If at the end of the 20 count the threshold was still present the program became confused and would open the door halfway, stop, and crash.

So I changed the code to this:


For I = 1 to 20

Pause 500
ADCIN 0, VL

If VL => 300 then
Light = 1
Indicator LED = 1

Else

Light = 0
IndicatorLED = 0
Endif

Next I


This seems to work but only have one night of results but I'm optimistic.

skybox

tasmod
- 17th December 2012, 16:53
I did something similar for a chicken coop door and originally had problems with the ldr as well.

I countered this and shadows etc by flipping a counter. Single microswitch and a small 12v model motor.

This code worked well.


'###############################################
'# #
'# Automatic chicken coop sliding door. #
'# #
'# 12 Volt Battery powered. #
'# Open when light, close when dark. #
'# Sleep 4 hours between to conserve power #
'# and to prevent retriggering. #
'# #
'# Uses single microswitch as feed back. #
'# #
'# Pic 16f818 --- Rob Lane - Dec 2011 #
'# #
'###############################################

OSCCON=$60 'set 4mhz internal oscillator
'(Set INT_OSC in programmer fuses)

' Define ADCIN parameters
Define ADC_BITS 10 'Set number of bits in result
Define ADC_SAMPLEUS 50 'Set sampling time in uS

Photo var word 'Create 'photo' to store result of ldr input
Counter1 var byte 'flip flop counter variable

'PIN ASSIGNMENTS
LDR var porta.0

MotorUp var portb.4
MotorDown var portb.5
Switch var portb.6

Counter1=1 'Set counter for power up, door must
'be closed in daylight for startup.
pause 5000
TRISA=%00000001 ' Set PORTA
TRISB=%01000000 ' Set PORTB
input switch


'################################################# ########

Main:
ADCIN ldr, photo 'read ldr adc value
IF Photo <15000 Then checkup 'daylight
IF Photo >30000 Then checkdown 'darkness
'sleep 300 'about 5 minutes low power
goto Main

'################################################# #########

checkup:
if counter1=1 then up
goto main

up:
High MotorUp 'start motor up
pause 1000 'wait 1 sec so micro switch opens
stopup:
if switch = 1 then pressedup 'check microswitch state
goto stopup 'check again till true

pressedup:
low motorup 'stop motor
Counter1=2 'flip flop counter for up/down of door
sleep 150
'sleep 14400 'sleep 4 hours
goto main

'################################################# #########

checkdown:
if counter1=2 then down
goto main
down:
high MotorDown 'start motor down
pause 1000
stopdown:
if switch = 1 then presseddown 'check again
goto stopdown

presseddown:
low MotorDown
Counter1=1
sleep 150
'sleep 14400
goto main

end

mister_e
- 17th December 2012, 22:53
Problem often lie in how you interface the LDR to the PIC. But a software crash... well something's wrong somewhere else. Code, hardware... hard to pin point without having the whole thing here...

skybox
- 18th December 2012, 14:59
Hello Rob,

Thanks for sharing your code. It is always interesting to see others' solutions to common challenges. Would it be too much to ask to see the schematic of your LDR circuit? I'm curious as to how you configured it.

Thanks

Skybox

spcw1234
- 18th December 2012, 16:36
Shawn,

Thanks for the reply. I do have a question concerning your answer. In the PBP manual it states the "While...Wend" has been deprecated and to use the "DO...Loop" instead. I never completely trust manuals because most become outdated with code updates. As such, I'd very much appreciate an elaboration as to why I should use the "While...Wend' when the manual states otherwise.

Thanks

Skybox

I have found the while wend to always work, I know I had problems with the do loop, but that may have been something else causing the problem. Some of the other suggestions here look to be a better alternative to either of these anyways.

Vett58
- 25th December 2012, 01:41
I am not sure if this would help or not , but I did have problem with some simple code that I had included Do,Loop.
The code worked fine when it was compiled using PBP3.0 but it did not work if it was compiled by PBP2.50B , which I had on an older machine.
The problem was solved when I changed the Do,Loop section to GOTO , and then the result from both PBP3.0 and 2.50B worked flawlessly.:)

skybox
- 26th December 2012, 13:54
Vett58,

Thanks for the response. The problem end up being in how I had the LDR circuit constructed. The code was not the issue. Originally, I had the LDR in a configuration that turned on a transistor when light changed. This did not work well so I reconfigured it into a simple voltage divider fed into a comparator. This works much better especially with a potentiometer serving as a variable resistor in the divider.

Happy holidays

Vett58
- 27th December 2012, 00:45
Vett58,

Thanks for the response. The problem end up being in how I had the LDR circuit constructed. The code was not the issue. Originally, I had the LDR in a configuration that turned on a transistor when light changed. This did not work well so I reconfigured it into a simple voltage divider fed into a comparator. This works much better especially with a potentiometer serving as a variable resistor in the divider.

Happy holidays

It is good to hear that the problem is solved .
Happy holidays to you too.