Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 10 of 10

Thread: Teensy 3.1 analog sticks to generate keyboard input

  1. #1
    Junior Member
    Join Date
    Feb 2016
    Location
    Germany
    Posts
    6

    Teensy 3.1 analog sticks to generate keyboard input

    Hi guys,
    at the moment im building a gameboy casemod similar to this: http://www.xodustech.com/projects/ra...gameboy-pocket .
    For the keypresses im using my teensy to act as a usb keyboard and mouse controller just as the guy on this website did it, but i want to include two psp replacement analog sticks in my project so i have better ps1 emulation control.
    I want them to behave as keyboard keys just like the other buttons so they arent actually analog because i think this is the best way to include them in the teensyduino code provided by the website (and here: https://github.com/WarriorRocker/pi-pocket), as i dont have to specify another input mode for them then.
    I did not find someone doing it that way and this is my first time using a c language instead of python.
    so i edited the code to include the analog sticks but as im on vacation i cant try it out. so my question is does the approach i chose work at all?
    (i dont want you to painstakingly look for syntax mistakes etc, but just ask you to give it a look and see if youre experienced if its complete shit or might work)
    Thanks
    Attached Files Attached Files

  2. #2
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    Keyboard.set:key4
    Should be
    Keyboard.set_key4

    But otherwise it looks okay

    EDIT -
    Oh wait no it doesn't. Take for example:
    Code:
    if (analogRead(A3) >= 400 && analogRead(A3)<= 600  && rhorival != 2){
          Keyboard.set_key3(0);
    When this stick is in the middle key3 will always be zero.

    As there is this code later on:
    Code:
    if (bB.fallingEdge()) {
          Keyboard.set_key3(KEY_L);
          Keyboard.send_now();
        }
    When bB is pressed it will pulse KEY_L for one iteration and then the top chunk of code will stop L from being held down
    Last edited by Xenoamor; 02-09-2016 at 04:02 PM.

  3. #3
    Junior Member
    Join Date
    Feb 2016
    Location
    Germany
    Posts
    6
    my idea was to set the right-horizontal-value (rhorival) to 2 so the script knows the stick is alredy in the middle and wont set this to 0 again as there are 2 requirements to execute the code and they are only met when the variable is for example 1 or 3 when the stick is moved
    Code:
        else if (analogRead(A3) >= 400 && analogRead(A3)<= 600  && rhorival != 2){
          Keyboard.set:key3(0);
          Keyboard.send_now();
          rhorival = 2;}
    and for the later part i thought as the usb protocol only can send 6 keys plus modifiers at one time i set it up that way as you dont move the right stick and press one of these buttons at the same time. you would have to really hold the controller in a weird way to do this i think
    Last edited by Mundm28; 02-10-2016 at 10:36 AM.

  4. #4
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    Yep, that'll do it!

    You may find if you're floating around the 400 value it turns it on and off rapidly. Consider looking into fuzzy logic if that happens to be the case
    Last edited by Xenoamor; 02-10-2016 at 11:07 AM.

  5. #5
    Junior Member
    Join Date
    Feb 2016
    Location
    Germany
    Posts
    6

    dude youre quick...
    yeah maybe ill implement something like this:

    Code:
    int data =0;
    for (int i=0; i<3;i++) {
        data = data + analogRead(A0);
    }
    data = data / 3;
    to make measurements more consistent and also do something to limit the times the keys are checked per second a bit so you dont really feel it but the teensy doesnt run it like crazy.

    But thanks a lot you really helped me!

  6. #6
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    Quote Originally Posted by Mundm28 View Post
    dude you're quick...
    I'm at work and I've been waiting on the hardware guys to finish a prototype for a few weeks now
    I've pretty much exhausted all I can do without it

    Smoothing can help take out any spikes but obviously at the cost of responsiveness. A running/moving average might work out better for you

    In terms of stopping it toggling you can introduce a kind of fuzzy state. More commonly known in the joystick world as a deadspace... I think

    Code:
    #define DS 50 //Deadspace
    
    if (analogRead(A3) > 600 && rhoritval != 3){
          Keyboard.set:key3(KEY_B);
          Keyboard.send_now();
          rhorival = 3;}
        else if (analogRead(A3) < 400 && rhorival != 1){
          Keyboard.set:key3(KEY_M);
          Keyboard.send_now();
          rhorival = 1;}
        else if (analogRead(A3) >= 400+DS && analogRead(A3)<= 600-DS  && rhorival != 2){
          Keyboard.set:key3(0);
          Keyboard.send_now();
          rhorival = 2;}
    This means that between 400-450 and 550-600 the state won't change and the state remains at it's previous state. This means if you move the stick to 400 and wiggle it a little it'll just set KEY_M once and won't keep toggling. This helps to keep your controller as responsive as possible.

    I guess if you put a cat in a box who moved the analogue stick to 425 the key would be both KEY_B and 0
    Last edited by Xenoamor; 02-10-2016 at 11:27 AM.

  7. #7
    Junior Member
    Join Date
    Feb 2016
    Location
    Germany
    Posts
    6
    Thanks again youre genius!

  8. #8
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    yes its called a deadzone ..its a span for the 'rest' position .... using it in combination with hysterisis is what zeno has suggested (averaging is a good idea too), and it will get you all the way home. I do hysterisis a little differently from zeno ... Here is some code (from memory, untested, no compiler) I use it for an analog slider controlling a motor... effectively loosing resolution (I have an idea to improve resolution but I don't think you need it)
    Code:
    //global
    bool zero=false;
    int currentread;
    int prevread = 512;
    
    //loop()
    currentread = analogRead(A3);
    
    if ((prevread + 3) < currentread) {prevread=currentread;}
    else if ((prevread - 3) > currentread) {prevread=currentread;}
    else currentread = prevread;
    
    if (currentread < 600 && currentread > 400) { if (zero=false) {Keyboard.set:key3(0); Keyboard.send_now(); zero = true;}}
    else if(currentread >= 600 {Keyboard.set:key3(KEY_B);
          Keyboard.send_now(); zero=false;}
    else  {Keyboard.set:key3(KEY_M);
          Keyboard.send_now(); zero=false;}
    Last edited by adrian; 02-10-2016 at 10:37 PM. Reason: woops zero is false.

  9. #9
    Senior Member adrian's Avatar
    Join Date
    Oct 2015
    Location
    Wellington, NZ
    Posts
    504
    there is the joystick usb type, which is good for analog sticks / gamepads ....

  10. #10
    Junior Member
    Join Date
    Feb 2016
    Location
    Germany
    Posts
    6

    Finally finished

    there is the joystick usb type, which is good for analog sticks / gamepads ....
    yeah for games only would be better but i want to control xmbc and cli music players and stuff with it too

    So its been a while and i finally tested everything.
    Thanks to you guys i only had to make very little changes so here is a pic of my test setup with only one stick attached (was alredy disassembling when i thought i could make a picture)
    and the final version of the code will be attached below so guys searching for similar things can get it!Click image for larger version. 

Name:	20160220010803.jpg 
Views:	56 
Size:	94.3 KB 
ID:	6423
    but beware.... there are 4 variables with non selfdocumenting names, but im to tired to change them before uploading.

    btw. is it possible or common to mark a thread as closed in this forum?
    Attached Files Attached Files

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •