Shop OBEX P1 Docs P2 Docs Learn Events
Reading PINS in a loop? — Parallax Forums

Reading PINS in a loop?

Vern GranerVern Graner Posts: 337
edited 2006-07-07 16:00 in BASIC Stamp
Ok, in one of my hare-brained schemes, I'm trying to read a sequence of pins and then act on the values. My original code had big repeating chunks such as this:

IF PIN1 = 1 THEN
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 1, TurnOn]
ELSE
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 1, TurnOff]
ENDIF

IF PIN2 = 1 THEN
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 2, TurnOn]
ELSE
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 2, TurnOff]
ENDIF

IF PIN3 = 1 THEN
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 3, TurnOn]
ELSE
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 3, TurnOff]
ENDIF

IF PIN3 = 1 THEN
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 4, TurnOn]
ELSE
  SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", 4, TurnOff]
ENDIF



So, I envisioned saving memspace and being more efficient by putting this inside a FOR/NEXT loop like this:

FOR cntI = 1 to 4
  IF PIN cntI = 1 THEN
          SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", cntI, TurnOn]
  ELSE
          SEROUT DC16, DC16Baud, [noparse][[/noparse]"!DC16", DC16Addr, "P", cntI, TurnOff]
  ENDIF
NEXT



However, (and maybe I'm a victim of cerebral flatulence here) I can't find a way to use a variable for a pin number! (the above was my first test and it didn't work) sad.gif Can someone give me a kick in the shins in the right direction? TIA! [noparse]:)[/noparse]

Vern

PS:

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Vern Graner CNE/CNA/SSE    | "If the network is down, then you're
Senior Systems Engineer    | obviously incompetent so why are we
Texas Information Services | paying you? Of course,if the network
http://www.txis.com        | is up, then we obviously don't need
Austin Office 512 328-8947 | you, so why are we paying you?" ©VLG


Post Edited (Vern) : 7/6/2006 12:16:44 AM GMT

Comments

  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-07-05 23:13
    Vern,

    ·· Can you clarify...Are you trying to make the outputs of the DC-16 match the inputs at 4 Stamp I/O pins?· If so that can be done with 1 or 2 lines of code.· You're using the P command on the DC-16 to set a pin, but you can set them all at the same time with the S command.· Likewise you can read the pins at the same time on the BASIC Stamp using the IN<register> command, such as INA.· The PIN statement only allows you to define constants, so you can't use it in a variable environment.


    BTW - Congrats on your 2nd Nuts & Volts article.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Vern GranerVern Graner Posts: 337
    edited 2006-07-06 00:15
    Chris Savage (Parallax) said...
    Can you clarify...<snip>?
    Sure. I think I may have included too much detail as it lost the focus of the question. My bad. smile.gif So, forget the DC-16 stuff.. it was only there to illustrate and I think it side tracked. How about this:

    I originally wrote large repeating code hunks like this:

    IF PIN1 = 1 THEN
      <do some stuff>
    ENDIF
    
    IF PIN2 = 1 THEN
      <do some stuff>
    ENDIF
    
    IF PIN3 = 1 THEN
      <do some stuff>
    ENDIF
    
    IF PIN3 = 1 THEN
      <do some stuff>
    ENDIF
    
    


    So I envisioned putting it in a loop like this:

    FOR cntI = 1 to 4
      IF {pin number <a variable>} = 1 THEN
              <do some stuff>
      ENDIF
    NEXT
    
    


    I'm trying to determine how to use a pin# in a comparison, but where the pin number itself is specified in a variable...? Is this possible?
    Chris Savage (Parallax) said...
    BTW - Congrats on your 2nd Nuts & Volts article.
    Thanks! Couldn't have done it without you guys! smile.gif

    Vern

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Vern Graner CNE/CNA/SSE    | "If the network is down, then you're
    Senior Systems Engineer    | obviously incompetent so why are we
    Texas Information Services | paying you? Of course,if the network
    http://www.txis.com        | is up, then we obviously don't need
    Austin Office 512 328-8947 | you, so why are we paying you?" ©VLG
    
    
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-07-06 01:05
    Okay,

    ·· I think I see what you want, but in your condensed code you're executing the same code if any of the 4 pins are high.· If that is what you want, you can do that a much easier way...Please let me know if I am on the wrong track here...

    If your pins are P0-P3 then you could say:

    Status···· VAR···· INA

    later in your code, you could do this...

    IF Status THEN
    ·· <do stuff here>
    ENDIF

    In this case, if any pin was HIGH, then the <stuff> would get executed.· Is that what you mean?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Vern GranerVern Graner Posts: 337
    edited 2006-07-06 01:26
    Chris Savage (Parallax) said...
    Okay,

    I think I see what you want, but in your condensed code you're executing the same code if any of the 4 pins are high. <snip>

    Dang. Nope.. again, my bad. (I really suck at describing what I'm looking for!) smile.gif Lets see if this example is clearer:

    IF PIN1 = 1 THEN
      <turn on light1>
      <play sound1>
      <move servo1 to home position>
    ENDIF
    
    IF PIN2 = 1 THEN
      <turn on light2>
      <play sound2>
      <move servo2 to home position>
    ENDIF
    
    IF PIN3 = 1 THEN
      <turn on light3>
      <play sound3>
      <move servo3 to home position>
    ENDIF
    
    



    The idea is to condense the above into a FOR/NEXT loop where I use a variable to represent the pin number I'm trying to sample ie:
    FOR cntI = 1 to 3
      IF {pin number <cntI>} = 1 THEN
        <turn on light(cntI)>
        <play sound(cntI)>
        <move servo(cntI) to home position>
      ENDIF
    NEXT
    
    



    Where the command in brackets above is what I'm looking for... Any clearer? smile.gif

    Vern

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Vern Graner CNE/CNA/SSE    | "If the network is down, then you're
    Senior Systems Engineer    | obviously incompetent so why are we
    Texas Information Services | paying you? Of course,if the network
    http://www.txis.com        | is up, then we obviously don't need
    Austin Office 512 328-8947 | you, so why are we paying you?" ©VLG
    
    
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-07-06 02:01
    Vern,

    ·· I will clear my head at work tomorrow and rethink this...I think my brain just turned to mush!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Tracy AllenTracy Allen Posts: 6,658
    edited 2006-07-06 05:05
    Vern,

    You can address pins by index as follows:

    IF IN0(cntI) = 1 THEN ...

    For example IN0(5) is the same as IN5.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-07-06 14:01
    Tracy,

    ·· I was trying to think if there was a way to condense his routine so he wouldn't have to handle one event at a time.· Since 4 pins can easily read at once it seems like it would be faster, but handling the resultant routines is what I'm not getting in this case (Sorry Vern, programmers block?).· Any ideas?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • SSteveSSteve Posts: 808
    edited 2006-07-07 05:10
    You need to set up your output routines so that they can be addressed by the FOR/NEXT index. For example, if your lights are on pins 8-11 and you're using a PSC with servos on channels 5-8, you could write:

    FOR cntI = 0 TO 3
      IF IN0(cntI) = 1 THEN
        HIGH 8 + cntI
        SEROUT PSCPin, Baud+$8000,[noparse][[/noparse]"!SC", 5 + cntI, 0, 750 & $FF, 750 >> 8, CR]
      ENDIF
    NEXT
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    OS-X: because making Unix user-friendly was easier than debugging Windows

    links:
    My band's website
    Our album on the iTunes Music Store
  • Ryan ClarkeRyan Clarke Posts: 738
    edited 2006-07-07 14:04
    Treat the INS as an array, indexing off of postion 0.

    It is common to do things such as:

    v.bit0(d)

    where d is your offset- notice I used "v", because this is just some variable that can be thought of as an array of pins. The DIRS and INS can be treated the same way.
    Likewise you can use the different modifiers to just get banks/chunks (such as HIGHBYTE, LOWBYTE, LOWNIB, HIGHNIB, etc)-

    Ryan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ryan Clarke
    Parallax Tech Support

    RClarke@Parallax.com
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2006-07-07 14:17
    Vern,

    ·· Okay, I think we got a little off-track there...Since there will be different code run based on a pin, and not just some other I/O pin changed you will have to use the FOR...NEXT loop, and Tracy has shown you above how to index the I/O pins in that manner.· I guess technically it won't condense the main body of the code since you will have to spell out the code for each event.· The only way it could be condensed was if each routine did the same exact thing but affected different I/O pins.· Then you could use one piece of comon code and reference the pins from there by index as well.· Sorry for the earlier confusion.· I was trying to solve this from my own perspective.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Chris Savage
    Parallax Tech Support
    csavage@parallax.com
  • Vern GranerVern Graner Posts: 337
    edited 2006-07-07 16:00
    Eureka! idea.gif Thanks to you guys I have a working loop... here's a code snip I used to read a series of N.O. pushbutton switches with pull-up resistors on pins 11-15:

    ' ************************
    ' * Servo Pump           *
    ' *************************************************************************
    FOR cntI = 1 TO 5             
      IF IN10(cntI) = 0 THEN       'the IN10+cntI value steps from pin11 to pin 15
        IF Flag(cntI) = 0 THEN     '\
          DC16Channel= cntI        ' |
          DC16State=TurnOn         ' |
           GOSUB UpdateDC16        ' |
          PSCposition = PumpStart  ' |
          PSCchannel = cntI-1      ' | Code runs when button pressed
          PSCrate = 0              ' | 
           GOSUB MoveServos        ' |
          Flag(cntI)=1             ' |
        ENDIF                      '/
      ELSE
        IF Flag(cntI) = 1 THEN     '\
          DC16Channel= cntI        ' |
          DC16State=TurnOff        ' |
           GOSUB UpdateDC16        ' |
          PSCposition = PumpStop   ' |
          PSCchannel = cntI-1      ' |
          PSCrate = 0              ' | Code runs when button released
           GOSUB MoveServos        ' |
          PaintShots=PaintShots-1  ' |
           GOSUB UpdateLED         ' |
          Flag(cntI)=0             ' |
        ENDIF                      '/
      ENDIF
    NEXT
    
    
    



    This code allows me to use the cntI variable to 1) read the pushbutton 2) send a command to the Parallax Serial Servo Controller (PSC) and 3) send a command to the DC-16. Since the DC-16 starts its channels at "1" and the PSC starts its channels at "0" I had to do a "cntI-1" to get the channels to line up, but this seems to work fine. I use the Flag (cntI) to make sure that the command is executed only one time per button press and one timer per button release (there's probably a more efficient way to do this, but I'm just hammering out test code right now, so opionions welcome!).

    So, I can now hit and hold any of the buttons to get lights and servos to react in response to input! Thanks again guys!! I love these forums. Keeps me from beating my head against the wall too much.. lol.gif

    Vern

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Vern Graner CNE/CNA/SSE    | "If the network is down, then you're
    Senior Systems Engineer    | obviously incompetent so why are we
    Texas Information Services | paying you? Of course,if the network
    http://www.txis.com        | is up, then we obviously don't need
    Austin Office 512 328-8947 | you, so why are we paying you?" ©VLG
    
    
Sign In or Register to comment.