Keyboard Low Pass Filter

Hi there,
I'm working on a game that uses my own custom controller. Actually I have been for over a year and I think I'm getting close...

Essentially I'm using the Keyboard input as a "serial-like" 3-bit decimal input (sorry if I'm butchering that jargon). I have ten keys setup for the "one's place," ten setup for the "ten's place" and ten setup for the "one's place." When a combination of all 3 is pressed, viola, my game receives a number between 0 and 999. If it matters, the number coming from and Arduino reading an encoder position.

This is working great, I'm sure hexadecimal will work even better. But I think I need a better low pass filter on the GameSalad end.

It's just a little too glitchy. Every once in a while it the number will pop way high or low and disrupt the gameplay.

What's weird is when I program the Arduino to continuously send keypresses, I never get any problems. But this is not ideal because I don't want to accidentally overwhelm other applications with jibberish. So it only sends them when the the number changes.

Any ideas? I think an efficient low pass filter is the answer...

Comments

  • SummationSummation Member, PRO Posts: 476

    Have you tried making a Rule that will only "listen" for key presses after a specified time period, like 0.25 seconds?

  • jaredcrogersjaredcrogers Member Posts: 10

    Sort of. Right now I'm using interpolate rather than constrain, and increasing the time (.1 to .15) for any movements +/- 90.

    It's helping a little, but I really want it working perfectly if possible.

  • SummationSummation Member, PRO Posts: 476

    So you said that when you program it to continuously send keypresses you never get any problems, right? How often is "continuously" and, is the continuous 'rate of fire' faster or slower than if you press the keys manually?

  • jaredcrogersjaredcrogers Member Posts: 10

    Continuously means almost never releasing the keys, even if the number is static.

    The refresh rate on the Arduino sketch is around ~25ms (.025 in GS terms).

  • SummationSummation Member, PRO Posts: 476

    @jaredcrogers said:
    Continuously means almost never releasing the keys, even if the number is static.

    The refresh rate on the Arduino sketch is around ~25ms (.025 in GS terms).

    So gamesalad is able to process inputs very rapidly... maybe the problem is the length of time that the combination of keys are pressed (by a user)?

    I'm guessing that if the keys are held down for too long during a manual press combination, the system thinks they were pressed more than once?

    Have you tried adjusting the length of time that keys are pressed on your Arduino to compare the results?

  • jaredcrogersjaredcrogers Member Posts: 10

    Yeah, I guess that's the next path to try. The problem is so intermittent, it's difficult to assess which techniques are working.

    So far, increasing the time the keys are pressed and held may have helped, but I don't want to add too much artificial lag if I don't have to.

    Thanks, this discussion is definitely helping me think differently about it...

  • SummationSummation Member, PRO Posts: 476

    @jaredcrogers said:
    Yeah, I guess that's the next path to try. The problem is so intermittent, it's difficult to assess which techniques are working.

    So far, increasing the time the keys are pressed and held may have helped, but I don't want to add too much artificial lag if I don't have to.

    Thanks, this discussion is definitely helping me think differently about it...

    My pleasure!
    Here's another idea...
    3 attributes as integers, right?

    keyset_A
    keyset_B
    keyset_C

    Have each set of ten keys change their respective attributes.
    So like the key set that controls the "one's" position can change keyset_A from 0 to 9.
    The key set that controls the "ten's" position can change keyset_B from 0 to 9.
    The key set that controls the (I'm assuming) "hundreds" position can change keyset_C from 0 to 9.

    This way you can concatenate your value into a number from 000 to 999.

  • jaredcrogersjaredcrogers Member Posts: 10

    Thanks @Summation. That's the technique I am using. 3 keys pressed change their respective attributes (one's, ten's, hund's).

    The sum of all three gives me the number.

    Maybe if I rewrite for hexadecimal and keep tweaking the delays I'll find the sweet spot...

  • SummationSummation Member, PRO Posts: 476

    @jaredcrogers said:
    Thanks Summation. That's the technique I am using. 3 keys pressed change their respective attributes (one's, ten's, hund's).

    The sum of all three gives me the number.

    Maybe if I rewrite for hexadecimal and keep tweaking the delays I'll find the sweet spot...

    You said in your original post that a combination of all 3 key sets need to be pressed in order to get your value, right?

    How about making a rule that requires all 3 buttons (one from each set) to be held down in order to validate the input. So perhaps a few boolean attributes:

    set_A_pressed
    set_B_pressed
    set_C_pressed

    Then a Rule: when all of the following are happening:
    if set_A_pressed = 1
    if set_B_pressed = 1
    if set_C_pressed = 1
    do:
    set input_valid to 1

    input_valud = 1 assumes that one key from each set is being held down at the same time. You need some code for that. You may also need to tell the system to ignore any additional keypresses made in that set while the first key pressed is being held down.
    So basically the system should only pay attention to the first key in each keyset pressed until A, B, and C have made input_valid = 1

    Then, when input_valid = 1, you can make another rule that says when any key being held down is released, to figure out the value of the concatenation of A, B, and C, then set input_valid to 0, then to make set_A_pressed, set_B_pressed, and set_C_pressed all back to 0, then reset keyset_A, keyset_B, and keyset_C if necessary.

  • jaredcrogersjaredcrogers Member Posts: 10

    That's a good thought @Summation. I have played with that a little. Rather, I originally had the "one's" key pressing slightly later than the other two. I told GS to "listen" for that last key press, and only update once pressed, since there shouldn't have been any instance where "set C" is down without set's A and B also down.

    In fact, I nested the entire update process under the rule:

    Actor receives event --> Any --> Keys 0 is down, Key 1 is down...through Key 9 is down.

    My impression was that if it helped, checking through the extra rule was counteracting any speed/accuracy benefit.

    I like the idea of waiting until everything is released.

    I'll try it using boolean variables as you suggest. Will concentrating all this into the actor of interest be most efficient?

    Or should there be an invisible "Update" actor whose sole purpose is to receive and filter the input into a global variable?

  • SummationSummation Member, PRO Posts: 476

    I would create that invisible update actor you mentioned just to be able to further isolate any problems/performance issues. Then, if that works, you can experiment with moving the update code elsewhere, if that's what you want to do. I hope it works! :)

Sign In or Register to comment.