Shop OBEX P1 Docs P2 Docs Learn Events
multiple inputs — Parallax Forums

multiple inputs

SYSY Posts: 11
edited 2006-11-20 15:07 in BASIC Stamp
Hi,

I need to create a simple circuit that can receive 6 inputs and for each one, light a load for a number of seconds and turn off.
Doing this in a linear fashion is simple. But I don't know how to keep listening to the other buttons while one is executing the "turn load on - wait - turn load off" sequence.
All inputs are controlled by one stamp but the displays are not related and need to be readily reactive unless the light is on.
Is there a listener object that can constantly monitor the inputs regardless if a load is on or not?
Can anybody suggest a way to program this?
Appreciate any help I can get.
Thanks.
SY.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-11-16 20:38
    You need to overlap the testing and the timing. Keep a count for each input indicating how many seconds or tenths of seconds or whatever that light still has to stay on. Each time through the one loop, check the inputs one at a time. If the input is on, set the corresponding count to say 50 (for 5 x 0.1 sec). Then check the counts. If a count is non-zero, turn on the load, then decrement the count by one. If the count is zero, turn off the load. After you've handled all the counts, PAUSE for 100ms (or whatever you need), then repeat.

    I think the "inPins(i)" thing will work. I don't have a current PBasic manual handy to make sure.

    maxInp con 2
    count    var byte[noparse][[/noparse]maxInp]  ' or whatever you need
    i            var byte
    inPins    pin 0
    outPins  pin 2
    
                 for i = 0 to maxInp-1
                 input i+inPins    ' initialize the inputs
                 low i+outPins    ' initialize the outputs
                 count(i) = 0      ' initialize the counts
                 next i
    theLoop for i = 0 to maxInp-1
                 if inPins(i) = 0 then skipPin
                 count(i) = 50    ' if on, set count to max
    skipPin   next i
                 for i = 0 to maxInp-1
                 if count(i) > 0 then makeOn
                 low i+outPins    ' if count zero, turn off
                 goto doNext
    makeOn high i+outPins  ' if count > 0, turn on
                 count(i) = count(i) - 1  ' and count down
    doNext   next i
                 pause 100        ' this give approx 5 seconds on
                 goto theLoop    ' do it all again
    
    
  • Tommy BotTommy Bot Posts: 60
    edited 2006-11-16 22:51
    This advice does NOTHING to attempt syntax but only explains logic flow. You need to understand that the BS2 does not multi-task, nor does it have an interrupt. This is why the Stamp does not look for the next button press until the current lighting sequence is complete. You need to “time share” and use a lot of I/O in order to perform the functions that you want, and it will require a lot of variables which won’t leave much room for anything else. If this is all you are doing then it is workable. There is probably a better way to do this, (I am still new) but here is one way to accomplish your needs.
    ·
    Use a real time clock. Buy and install an RTC
    ·
    ‘ Declare variables.
    T1
    T2
    T3
    T4
    T5
    T6
    Declare I/O
    6 inputs
    6 outputs
    ·
    ·
    Main:
    ·
    Switch 1:
    If input 1 is not active THEN Switch2
    Else read and store the RTC to switch 1s timer to variable T1····‘(This portion is skipped if the·associated input is not active)································
    Activate associated output····························································· ‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light1······························································· ‘(This portion is skipped if the·associated input is not active)
    ·
    Switch 2:
    If input 2 is not active THEN Switch3
    Else read and store the RTC to switch 2s timer variable T2······· ‘(This portion is skipped if the·associated input is not active)·································
    Activate associated output······························································‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light2································································‘(This portion is skipped if the·associated input is not active)
    ·
    Switch 3:
    If input 3 is not active THEN Switch4
    Else read and store the RTC to switch 3s timer variable T3········ ‘(This portion is skipped if the·associated input is not active)································
    Activate associated output····························································· ‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light3······························································· ‘(This portion is skipped if the·associated input is not active)
    ·
    Switch 4:
    If input 4 is not active THEN Switch5
    Else read and store the RTC to switch 4s timer variable T4·········‘(This portion is skipped if the·associated input is not active)································
    Activate associated output····························································· ‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light4······························································· ‘(This portion is skipped if the·associated input is not active)
    ·
    Switch 5:
    If input 5 is not active THEN Switch6
    Else read and store the RTC to switch 5s timer variable T5·········‘(This portion is skipped if the·associated input is not active)································
    Activate associated output······························································ ‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light5································································ ‘(This portion is skipped if the·associated input is not active)
    ·
    Switch 6:
    If input 6 is not active THEN Main
    Else read and store the RTC to switch 6s timer variable T6··········‘(This portion is skipped if the·associated input is not active)·······························
    Activate associated output······························································· ‘(This portion is skipped if the·associated input is not active)
    GOSUB subroutine Light1································································· ‘(This portion is skipped if the·associated input is not active)
    ·
    GOTO Main
    ·
    Light1:
    IF T1 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Light2:
    IF T2 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Light3:
    IF T3 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Light4:
    IF T4 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Light5:
    IF T5 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Light6:
    IF T6 + (desired on time delay) <= current RTC reading THEN de-activate associated output ·
    Return
    ·
    Note that successive inputs prior to the “timer” expiring will re-initiate the timer.
    Using this method will allow the inputs to be independent of each other.
    Look at the RTC documentation for the proper method of reading the RTC and size requirements for the variable.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    (Frequently heard from other's)

    Tommy, I know it wasn't designed to·x, but can you make it·do x·anyway?

    ·
  • Mike GreenMike Green Posts: 23,101
    edited 2006-11-17 07:02
    The example I gave checks all 6 inputs (if you set maxInp to 6), determines the state of the outputs and keeps track of how much longer the outputs need to stay on once activated. The granularity, set in the example to 100ms, is adjustable. The actual time varies somewhat since Tommy is right in that the Stamp is not multitasking and isn't superfast. The time to do all the checking isn't included in the 100ms (which is a PAUSE where the Stamp doesn't do anything else). For most applications, a granularity for checking inputs on the order of once every 100ms or 50ms or 25ms is very reasonable.
  • SYSY Posts: 11
    edited 2006-11-17 16:26
    Mike, Tommy, thanks for the code.
    I have been attempting to program Mike's code but its seems to get stuck on the first for..loop rather than go through the rest of the commands. I'm a·beginner programmer in basic so I keep getting errors such as "expects ":" or end of line" when·I keep the "i" after the NEXT. According to the manual·NEXT incerments my value and returns to the top of the loop, which explains why it gets stuck on the first loop. How can I continue to excute the code rather than go back to the top? the first thing that comes to mind is a·different·sub,·am·I right?
    Also tried using count like the example - count var byte[noparse][[/noparse]maxInp] - but got errors as well.

    I'm using the BS2 (if it makes a difference in the code).

    Hope you can help.
    Thanks.
    SY
  • Paul Sr.Paul Sr. Posts: 435
    edited 2006-11-17 17:29
    SY said...
    Mike, Tommy, thanks for the code.
    I have been attempting to program Mike's code but its seems to get stuck on the first for..loop rather than go through the rest of the commands. I'm a beginner programmer in basic so I keep getting errors such as "expects ":" or end of line" when I keep the "i" after the NEXT. According to the manual NEXT incerments my value and returns to the top of the loop, which explains why it gets stuck on the first loop. How can I continue to excute the code rather than go back to the top? the first thing that comes to mind is a different sub, am I right?

    Also tried using count like the example - count var byte[noparse][[/noparse]maxInp] - but got errors as well.



    I'm using the BS2 (if it makes a difference in the code).



    Hope you can help.

    Thanks.

    SY

    Mike is in 'Propellerland" - and doing some amazing things, I might add! No negative implication at all - it's all good!

    Here is the code in "STAMP PBasic" - it should help you get going

    
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    maxInp    CON 2
    
    CNT       VAR Byte(maxInp)  ' or whatever you need
    i         VAR Byte
    inPins    PIN 0
    outPins   PIN 2
    
              FOR i = 0 TO maxInp-1
                 INPUT i+inPins    ' initialize the inputs
                 LOW i+outPins    ' initialize the outputs
                 CNT(i) = 0      ' initialize the counts
              NEXT
    theLoop:
              FOR i = 0 TO maxInp-1
                 IF inPins(i) = 0 THEN skipPin
                 CNT(i) = 50    ' if on, set count to max
    skipPin:
              NEXT
              FOR i = 0 TO maxInp-1
                 IF CNT(i) > 0 THEN makeOn
                 LOW i+outPins    ' if count zero, turn off
                 GOTO doNext
    makeOn:
                 HIGH i+outPins  ' if count > 0, turn on
                 CNT(i) = CNT(i) - 1  ' and count down
    doNext:
              NEXT
              PAUSE 100        ' this give approx 5 seconds on
              GOTO theLoop    ' do it all again
    
    
    

    Post Edited (Paul Sr.) : 11/17/2006 5:37:55 PM GMT
  • SYSY Posts: 11
    edited 2006-11-17 18:06
    Thanks, I'll give it a try.
    Sy
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2006-11-18 02:55
    Hi Sy, there are a lot of ways to do this. The following starts the light on when the input goes from 0 --> 1, and it ignores the continued 0 or 1 state. The other examples hold the output ON so long as the input stays in the =1 state, plus 5 seconds. It depends on what you want it to do! This uses a trick with the Stamp operators ^ and & to detect a change in state of all 6 pins at once, and then decodes the effect on the counts and outputs. This assumes the inputs are connected to p0 to p5 and the outputs to p8 to p12.

    old  VAR byte  ' old state of inputs
    new VAR byte   ' new state of inputs
    changeup  VAR byte   ' change in state of inputs 0->1
    counter VAR byte(6)   ' array of 6 counters
    
    old = inL   ' initialize
    dirH = $ff   ' p8 to p15 are outputs
    
      DO
        new = inL   ' grab all six inputs
        changeup = new ^ old & new   ' detect changes
        old = new      ' update old
        FOR idx=0 to 5     ' effect on counters and outputs
          IF changeup.bit0(idx) THEN counter(idx)=50    ' index into bits of changeup
          IF counter(idx) THEN counter(idx) = counter(idx)-1   ' decrement if needed
          out8(idx) = counter(idx) MAX 1   ' set output if counter is active, note indexing into output bits
        NEXT
        pause 93   ' 93 milliseconds pause + 7 milliseconds for code (guesstimate)
      LOOP
    



    There are ways to make the time for the code more exactly predictable, and ways using external clock to sychronize to clock time.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • SYSY Posts: 11
    edited 2006-11-20 15:07
    Thanks everyone, you have been very helpful.
    Its working!
    Very grateful.
    Sharon (SY).
Sign In or Register to comment.