Shop OBEX P1 Docs P2 Docs Learn Events
Variable inputs? — Parallax Forums

Variable inputs?

edited 2007-02-08 17:44 in BASIC Stamp
Good days Folks!

I am trying to read each input pin individually without lots of input statements. Can i do it something like this?

i VAR Byte
DO
· AUXIO
· DIRS = %0
· FOR i = 1 TO 10
··· IF INPUT i = 1 THEN DEBUG "Yeah!!!"
··· PAUSE 500
· NEXT
LOOP

This does not work, but can some one suggest something that is similar that does?



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Freeing smoke from wire and IC captivity since 1972

Comments

  • Tom WalkerTom Walker Posts: 509
    edited 2007-02-07 20:41
    Just a clue....there are commands that allow you to read a contiguous set of input pins in a single read. Then you could check the value of any bit in the input variable. See INS, INH, INL.

    Also, pins default to input on reset, so unless you are using any of your input pins as an output, the DIRS statement in your code is not necessary.

    HTH

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-07 21:01
    Something like this could work to scan pins 1 through 10:
    mask = %10
    AUXIO
    FOR i = 1 to 10
      if INS & mask then debug "yeah!"
      pause 500
      mask = mask * 2
    NEXT
    MAINIO
    
    
  • edited 2007-02-07 21:03
    As usual, I have become one of the posters that have not given enough information.



    Tom, I am well aware of the INx function set, but then it would still require me to have several If--Then--elseif---endif statements to do what I want.



    "well, what is it that you want to do?"



    I am trying to do bitwise manipulation of another variable base upon the input from the Auxio pins.



    I am sending a control word to an LED driver that I have. It'll take a binary byte. If the ith input is high, then I would like the corresponding led to turn on and stay on until the ith input goes low, not before.

    ···· Initial state of LED driver:···· LED_Driver_Variable = 0000 0000

    ·····If an input goes high, I need to change just the·bit corresponding to that·LED. I decide to use the dcd function with an if statement.

    ········· If input 1 = 1 then LED_Driver_Variable = dcd i | LED_Driver_Variable

    This allows me to only manipulate the bit I need. Making it a "1" and turning the light on.

    Turning it off is a bit more tricky.

    ········· LED_BasicVariable = dcd i | ~LED_BasicVariable
    ········· LED_BasicVariable = ~LED_BasicVariable

    "Smokey, this is crazy talk!" Nope. Let's go through·an example.

    All of the LED's are off.

    ···· LED_BasicVariable = %0000 0000

    Input 3 goes high.

    ···· LED_BasicVariable = dcd i | LED_BasicVariable

    ···· LED_BasicVariable = %0000 1000 | %0000 0000

    ···· LED_BasicVariable = %0000 1000

    Works good so far, right?

    Let's say Input 6 goes high.

    ···· LED_BasicVariable = dcd i | LED_BasicVariable

    ···· LED_BasicVariable· = %0100 0000 | %0000 1000

    ···· LED_BasicVariable = %0100 1000

    Still works well? Yep.

    Now Lets say Input·3 goes low again. the first stage in turning it off is:

    ···· LED_BasicVariable = dcd i | ~LED_BasicVariable

    ·····LED_BasicVariable = %0000 1000 | %1011 0111

    ···· LED_BasicVariable = %1011 1111

    The second stage is simply a "NOT " call:

    ···· LED_BasicVariable = ~LED_BasicVariable

    ···· LED_BasicVariable = %0100 0000

    Yeah!!!! IT works as intended.



    Ok, so in a formal program, I would be required to write a bunch of IF-THEN statements like

    If IN1 = 1 then

    ···· LED_BasicVariable = dcd i | LED_BasicVariable

    else

    ···· LED_BasicVariable = dcd i | ~LED_BasicVariable

    ···· LED_BasicVariable = ~LED_BasicVariable

    endif

    If IN2 = 1... For all 16 inputs. I would like to not to write that cluncky code.



    Thefore, I would like to write statements like:

    if input i = 1 then...

    And have the micro read "input i" as "input 5" for a high reading on the X4 pin.



    Any ideas?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Freeing smoke from wire and IC captivity since 1972
  • Tom WalkerTom Walker Posts: 509
    edited 2007-02-07 21:11
    OK...is there any reason that LEDBasicVariable cannot just simply "follow" INx (LEDBasicVariable=INS)? Your bits would constantly carry the correct states of the pins and you could do individual tests on IN0-IN7 if they had some other function. Forgive me if I'm not seeing something obvious.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...
  • edited 2007-02-07 21:21
    Good question.

    There is a reason.

    Really, I am working with 13 I/O's. I communicate with 3 other devices with I2C protocols. I am using the input from some DIP Switches (the part of the programs which I need the inputs for) to determine if I an LED will really turn on if one of the sensors says it needs to.

    The EE I am working with, created PCA in such a way that, if DIP switch 8 is high, say, then LED 9 should be on and, if DIP switch 9 is on, then LED 11 should be on... It gets a bit more confusing from here.



    The board's design is final and I have to solve this in software.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Freeing smoke from wire and IC captivity since 1972
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-07 22:01
    Sounds like a good situation to use EEPROM tables and READ/DATA statements. You'd have a table in EEPROM (constructed with DATA statements) for each kind of bit mask / complementary bit mask / etc. needed. You'd use a regular FOR loop and do a "READ tbl1+i,var1" for each item needed and then combine them all as needed. If you need to get fancier, you can have I2C device select codes or command codes or whatever in the tables as well. As a result, most of your logic is table driven, often more straightforward and easier to construct and debug than having specific statements for each case.
  • edited 2007-02-08 16:30
    I am looking into the suggestions you have mentioned. I am not optimistic about it as (so far) it looks like the same ammount of coding as the way I do not want to do.

    I guess the answer to my question (though not directly answered) is "No. You can not do what you want to as you described in your original post."

    I really wish the answer had been different.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Freeing smoke from wire and IC captivity since 1972
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-02-08 16:41
    I guess I don't get it. You CAN read all the I/O pins in a single read (well, ok, you can read the AUXIO in one read, then the MAINIO in another read). This will not change the input/output state of the pins. Any pins configured as OUTPUT (side effect of an I2C operation, perhaps) will remain as output, you'll merely read the contents of the output latch, which is a "don't care" for you for those pins.

    You can then 'mask' off the bits of interest, with a %01 value shifted the appropriate number of bits programmatically.

    It seems to me this achieves the purpose you have specified. You could even write a subroutine like:

    BitToRead VAR NIB
    ResultBit VAR BIT
    AllBits VAR WORD

    MAIN:
    BitToRead = 1
    GOSUB CheckMainBit
    SEROUT 16, 16468, [noparse][[/noparse]"Bit ", HEX BitToRead, "Value: ", HEX ResultBit, 13]
    PAUSE 1000 ' So we don't "flood"
    GOTO MAIN

    CheckMainBit:
    MAINIO
    AllBits = INS
    ResultBit = AllBits & (%1 << BitToRead) >> BitToRead
    RETURN

    And, you could do main as:

    FOR I = 1 to 16
    BitToRead = I
    GOSUB CheckMainBit
    NEXT
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-02-08 16:48
    You could even write a 'bit shuffling' subroutine, and get all your results 'squished' into one word.

    CheckIO:
    MAINIO
    AllBits = INS
    Results = 0 ' Clear out previous results
    Results.Bit0 = AllBits.Bit0 ' zero to zero
    Results.Bit1 = AllBits.Bit3 ' Bit 1 and 2 used for I2C, for instance, so we 'don't care' about those...
    Results.Bit2 = AllBits.Bit4 '
    Results.Bit3 = AllBits.Bit7 ' Bits 5 and 6 used for SHIFTIN/SHIFTOUT
    RETURN

    This way, all your 'bit twiddling' would be in a single subroutine -- to be edited should your I/O map ever change. And in a single call and input read you get all the results you want.
  • edited 2007-02-08 17:44
    Allan,

    First post - Great! Where have you been all my life! Seriously, that's a clever subroutine. I have not used "<<" or ">>" as I thought that I have not had a need for them.

    Second Post - This will still create the problem of one line per bit. But I think I can combine the first posts cleverness with my previously posted "bit twiddling" and arrive at what I need.

    Thank you for this very cool "bit retrieval" routine. When I am finished, I'll post the code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Freeing smoke from wire and IC captivity since 1972
Sign In or Register to comment.