Shop OBEX P1 Docs P2 Docs Learn Events
Simple math help (spin) — Parallax Forums

Simple math help (spin)

Hello all,

I could be getting burned out, but I cant for the life of me how to figure this out.

The project I am working on that can have up to 125, 8 channel touch chips(1000 inputs total). The chips have one register each with the touch flags, 1-bit for each input. I am trying to figure a way to know what input was touched. for example---- say I touch sensor number 20, the prop would scan through the first 2 chips, and not see a touch. But when it got to the third chip it would see input number 4 was flagged. The prop would then know that sensor number 20 was touched.

currently, the touch chips are on a parallel buss. I am using a 74HC138, 3 to 8 decoder. I am only doing 8 chips right now, as proof of concept. Then it will start getting bigger.

Is there an easy way to figure what sensor input was touched from knowing what the <byte> sized address is, and what the <byte> sized register value is?

Thanks
TC

Comments

  • kwinnkwinn Posts: 8,697
    edited 2016-09-21 03:17
    You take the value going to the chip select decoder (0 - 7, 2 in this case) multiply it by 8 (or shift left 3), then use a loop to count how many shifts it takes to put the input register bit in the lsb position, and add that count (in this case 3) to the value.
  • TC wrote: »
    Is there an easy way to figure what sensor input was touched from knowing what the <byte> sized address is, and what the <byte> sized register value is?

    I'd think you could use something like this;
      activeRegiterBit :=  (>| register) - 1 ' get the active bit
      buttonId := (8 * address) + activeRegiterBit
    

    This only checks for a single button press but it wouldn't be hard to detect multiple buttons.

  • If it's possible more than one bit could be set high in a register, you could process the same register multiple times until all the high bits were found.

    Here's an example.
    CON
    
      MAX_ADDRESS = 124
      MIN_ADDRESS = 0
      
    VAR
    
      long buttonId
    
    PUB Main | registerValue, address
    
      address := MIN_ADDRESS
    
      repeat
        if address > MAX_ADDRESS
          address := MIN_ADDRESS
        registerValue := GetSingleChipRegister(address++)
        registerValue &= $FF ' make sure only lowest 8-bits are set
        repeat while registerValue
          registerValue := FindNextButton(address, registerValue)
          ' do something with buttonId
        address++
          
    PUB FindNextButton(address, registerValue)
    
      buttonId := (>|registerValue) - 1
      result := |< buttonId
      buttonId += 8 * address
      result := registerValue & !result
    
    PUB GetSingleChipRegister(address)
    
      ' Read register from chip and assign this value to the "result" variable.
    

    I made "buttonId" a global value since the method "FindNextButton" was returning the value of "registerValue" but with the highest set bit cleared.
  • Here's a bit of math that works
      repeat device from 0 to 124
        scan := scan_device(device)                                 ' select and read device
        if (scan > %00000000)                                       ' anything active?
          scan ><= 32                                               ' flip for >|
          sensor := (device << 3) + (32 - >|scan)                   ' calculate sensor #
          quit
    

    The scan_device() method takes care of the chip selects and then reading the device.
  • TCTC Posts: 1,019
    edited 2016-09-21 11:51
    OK... I am blown away... I posted this before I went to bed, expecting maybe one person would have an idea, but not 3 different ideas. You guys are great.

    I have to get this done by tomorrow(friend wants to show the "tech" working this weekend) and I am behind because of issues like this. Stupid issues, that I don't want to ask for help, until I try to figure it out my self. I don't feel it is right to ask people "how do you do A + B = C" when I can spend some time with the prop manual, the forum search bar, and google to figure out the answer. I need to decide, when is it a good time to quit wasting time trying to figure it out, and ask for help.

    I do apologize if I start asking questions with out doing the research. I would not be doing it if I had more time
    kwinn wrote: »
    You take the value going to the chip select decoder (0 - 7, 2 in this case) multiply it by 8 (or shift left 3), then use a loop to count how many shifts it takes to put the input register bit in the lsb position, and add that count (in this case 3) to the value.

    That is one option I was somewhat thinking of. But I just could not rap my head around the order I needed. But now I do. Thanks

    Duane Degn wrote: »

    I'd think you could use something like this;
      activeRegiterBit :=  (>| register) - 1 ' get the active bit
      buttonId := (8 * address) + activeRegiterBit
    

    This only checks for a single button press but it wouldn't be hard to detect multiple buttons.

    Right now I am only worried about single touch, but later on I am thinking of doing multi-touch for a hidden random Easter egg. I thought it would be a fun idea to get the people playing with the project.
    If it's possible more than one bit could be set high in a register, you could process the same register multiple times until all the high bits were found.


    I made "buttonId" a global value since the method "FindNextButton" was returning the value of "registerValue" but with the highest set bit cleared.

    I will save your idea for when I do the multi-touch. Thanks

    JonnyMac wrote: »
    Here's a bit of math that works
      repeat device from 0 to 124
        scan := scan_device(device)                                 ' select and read device
        if (scan > %00000000)                                       ' anything active?
          scan ><= 32                                               ' flip for >|
          sensor := (device << 3) + (32 - >|scan)                   ' calculate sensor #
          quit
    

    The scan_device() method takes care of the chip selects and then reading the device.

    I dont know how you do it Jon. You can post code that "to me" looks like it would not work. Then I try it, and works exactly the way it should. Then I have to open the manual, and dissect whats going on.

    I just cant take someone else code, and not try to figure out what is going on. That my main downside when I'm in a hurry, I can try and figure out what is going on in the code.

    Thanks for everything
    TC
  • I don't know how you do it Jon. You can post code that "to me" looks like it would not work. Then I try it, and works exactly the way it should.
    I have any number of Propeller boards on my desk at any time. I grab one, whip up a bit of code, then give it a go -- testing before posting helps prevent me from looking foolish. I spoofed scan_device() like this:
    pub scan_device(d)
    
      if (d == 2)
        return %0000_0001
    
    I changed the target for d and the bits returned a couple times until I was satisfied the above code was okay to post.
    Then I have to open the manual, and dissect whats going on.
    The more you do that, the easier dissecting becomes. We all get stuck sometimes. For a long time I simply shrugged my shoulders at the "fast" SPI routines (PASM code, using both counters) that were obvious to others. Last week I looked again and that code finally made sense. The good news is that "Aha!" moments like this tend to lead to more of them, and the duration between gets shorter.

    I'm glad I could help -- which, by the way, helps me get better. On more than one occasion I have suggested to my N&V readers that helping others here in the forums is a great way to improve. Those of us helping you don't have the stress of the project weighing on us, hence may see things a little more clearly. Stress sucks!
Sign In or Register to comment.