PDA

View Full Version : Help with timing, parallel processes between two BS2's



Blake
03-09-2010, 10:08 AM
Hey, I am fairly inexperienced at pbasic and electrical engineering in general. I was wondering if anyone had any tips or tricks to using one basic stamp to time operations and another to execute code based on this timing. I looked briefly into using a 555 timer in astable mode, but I was unable to get the pulse period I wanted easily. I have a feeling a propeller chip would be a better option for this, but I already have two bs2's lying around.

In the following code the first stamp keeps time and sends a signal to the second stamp every X seconds. The second stamp activates a motor which spits out a coin from a machine. The machine has an optical interrupt which senses when a coin has left the machine. I put in the "counter" variable so that if the machine is unable to spit out a coin before the next pulse from the first stamp, the second stamp activates the motor until two coins are spit, etc. The "coin" variable is so that the bs2 doesn't count the same coin blocking the interrupt twice (or hundreds of times) because the stamp is cycling through its code numerous times before the coin has had a chance to leave the interrupt.

Every so often, this code fails. I think it must have to do with the timing between the stamps, the second stamp missing a pulse signal or getting the same one twice, etc.

So, is there a better way to do this?

Thanks for any help,
Blake

first stamp:



' {$STAMP BS2}
' {$PBASIC 2.5}

'first stamp, performs timing.

LOW 0 'pin to send signal to second bs2

main:
PAUSE 3505
HIGH 0
PAUSE 5
LOW 0
GOTO main




second stamp:


' {$STAMP BS2}
' {$PBASIC 2.5}

'second stamp, performs actions.

'input (blue line) from opd917BZ
INPUT 0
'input from timer bs2
INPUT 7

counter VAR Byte
coin VAR Byte

main:
counter = 0
LOW 5
GOTO start

start:
DEBUG DEC counter

IF (IN7 = 1) THEN 'if there is a signal from timer
counter = counter +1 'add one to count
GOTO motoron 'turn on motor

ELSEIF (IN0 = 0) THEN 'if coin rolls through interrupt
GOTO evalmotoroff 'decide whether to turn off motor

ELSEIF (IN0 = 1) THEN 'if there is no coin in interrupt
coin = 0 ' set coin present variable to 0

ENDIF

GOTO start



evalmotoroff:
IF (coin = 0) THEN 'if this is the first cycle since coin has been interrupted
coin = 1 'set coin present to 1. this will null future coin present cycles until interrupt is again clear.
counter = counter - 1 'subtract one from coin counter
GOTO turnoff 'begin motor turn off
ENDIF
GOTO start

turnoff:
IF (counter = 0) THEN 'if first cycle
LOW 5 'deactivate motor relay
GOTO start
ENDIF
GOTO start

motoron:
HIGH 5 'trigger motor relay
GOTO start

Post Edited (Blake) : 3/9/2010 2:16:24 AM GMT

Blake
03-09-2010, 11:00 AM
Okay, I read the above FAQ and Mike Green states (about parallel processing):


Mike Green said...

2) It can't really. There's only one processor in the Stamp, so it can only do one thing at a time. You can attach additional processors to a Stamp and you can network several Stamps together, but, if you want to do two things at the same time, you need something like the Propeller that can really do several things at the same time. It's possible to combine two programs together so two functions are interleaved and the Stamp appears to be doing several things at the same time. The BoeBot works somewhat that way in that servos require control pulses about 50 times a second. The Stamp in the BoeBot can read sensors and do some decision making in between the servo pulses since there's about 17ms left in the 20ms interval before another servo control pulse has to be generated.



But, my code does work (most of the time). I think it just needs to be refined. I think my question about a better way still has merits... I think mine needs to work in a similar way to the BoeBot.

Mike Green
03-09-2010, 12:11 PM
The reason your code doesn't work sometimes is that the 2nd Stamp is occasionally busy when it "should" be listening for a pulse from the 1st Stamp. In order for this scheme to work, you need, at the very least, a flip-flop between the 1st Stamp and the 2nd Stamp that gets set by the 1st Stamp and sensed and reset by the 2nd Stamp. This flip-flop essentially remembers that X seconds have gone by and the 1st Stamp has signalled to the 2nd Stamp that this has happened. The flip-flop will remember this until the 2nd Stamp has a chance to notice and act on the signal. Once the 2nd Stamp has noticed, it can reset the flip-flop to be ready for the next signal.

Tracy Allen
03-10-2010, 12:24 AM
A quick way to achieve the memory action that Mike suggests is to tie a 0.01uF capacitor from the trigger pin to ground (pin 0 on the timer Stamp, pin 7 on the listening Stamp). On the timer Stamp, the HIGH 0 instruction charges the capacitor, but instead of LOW 0, do INPUT 0. The 5 volt charge will be stored on the capacitor, a dynamic memory, for many seconds, provided the circuit has no significant external leakage. On the listening Stamp, PBASIC at its leisure sees the capacitor charged high, executes its subroutine, and then does a LOW 7 : INPUT 7 sequence. That resets the cycle.

Another way to do it is to make the high pulse on the timer Stamp much longer, but use code on the listening Stamp to detect the 0-->1 transition instead of just the high level. If it detects just the IN7=1, there is danger that it will execute the code more than once for one trigger, as you have already observed. The transition code requires a couple of bit variables to detect the change:


oldTrig VAR bit
newTrig VAR bit
upTrig VAR bit
oldTrig = IN7
' ...
start:
' ...
newTrig = IN7
upTrig=newTrig ^ oldTrig & newTrig ' 1 on 0-->1 transition, otherwise 0
oldTrig=newTrig
IF uptrig THEN ' .... do the stuff

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com (http://www.emesystems.com)

Post Edited (Tracy Allen) : 3/9/2010 4:29:21 PM GMT

erco
03-10-2010, 01:13 AM
Tracy: Your cap idea is wonderful, simple, almost free, and bookmark-worthy.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"If you build it, they will come."

Blake
03-10-2010, 10:40 AM
Thanks for the help! Tracy's post was really helpful and I ended up implementing the capacitor switch idea. I agree with erco, really simple and a great idea. One problem I've run into, unrelated, is that sometimes my machine spits out two coins at once before the stamp can turn off the motor, which ends up causing the counter variable to go negative. This causes the machine to never stop because a negative number is greater than zero. I have solved this with a "if counter = 0 OR counter > 25 THEN counter = 0" (because it will never get higher than 25 and to "reset" the variable).

Here's my updated code (again thanks everyone, especially Tracy):

Timing Stamp:



' {$STAMP BS2}
' {$PBASIC 2.5}
'first stamp, performs timing.

LOW 0 'pin to send signal to second bs2

main:
PAUSE 3500
HIGH 0
INPUT 0
GOTO main




Listening/Acting Stamp:



' {$STAMP BS2}
' {$PBASIC 2.5}

'second stamp, listens, performs actions.

'input (blue line) from opd917BZ
INPUT 0
'input from timer bs2
INPUT 7

counter VAR Byte
coin VAR Byte

main:
counter = 0
LOW 5
GOTO start

start:
DEBUG DEC counter

IF (IN7 = 1) THEN 'if there is a signal from timer
LOW 7
INPUT 7
counter = counter +1 'add one to count
HIGH 5 'trigger motor relay
GOTO start 'turn on motor

ELSEIF (IN0 = 0) THEN 'if coin rolls through interrupt
GOTO evalmotoroff 'decide whether to turn off motor

ELSEIF (IN0 = 1) THEN 'if there is no coin in interrupt
coin = 0 ' set coin present variable to 0

ENDIF
GOTO start

evalmotoroff:
IF (coin = 0) THEN 'if this is the first cycle since coin has been interrupted
coin = 1 'set coin present to 1. this will null future coin present cycles until interrupt is again clear.
counter = counter - 1 ' subtract 1 from counter
GOTO decideoff
ENDIF
GOTO start

decideoff:
IF (counter = 0 OR counter > 25) THEN 'if counter is zero or negative
counter = 0 'make sure counter is zeroed
LOW 5 'turn off motor
GOTO start
ENDIF
GOTO start

Tracy Allen
03-10-2010, 12:27 PM
I'm glad you liked the capacitor trick. I've used that often to latch the occurrence of short lived events until the Stamp could get around to seeing them. I dry weather and with clean wiring, its amazing how long a capacitor can hold a pin at one level or the other. Nevertheless, I can't claim to have invented memory as charge stored on a capacitor!

Blake, another way to deal with the negative issue is to nip it in the bud in the counter instruction:
counter = counter - 1 ' subtract 1 from counter
counter = counter MIN 1 - 1 ' subtract 1 from counter, but never go negative.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com (http://www.emesystems.com)