Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 49 of 49

Thread: Button Press detector

  1. #26
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,382
    Looks like that one used SPI_MODE0 where I guessed SPI_MODE3 in the other one.
    MSBFIRST/LSBFIRST tells SPI the order of the bits, that is if I output an 0x01 are the bits output: 0 0 0 0 0 0 0 1 or is it 1 0 0 0 0 0 0 0
    (Most Significant Bit first) or (Least Significant bit first)

    I believe you can just do something like joysitck.button(13, joyBtnState);

  2. #27
    Thank you.


    Reading on SPI's, is 1000Hz vs 4000MHz going to make a difference to the functions?

    Is windows Power Management more liekly to step in an power off the device if there's a slwoer rate?
    Last edited by RobinNoGood; 01-16-2023 at 07:56 PM.

  3. #28
    Code:
    /* Byte 1
     * 7 - 1
     * 6 - 0
     * 5 - 0
     * 4 - 0
     * 3 - 0
     * 2 - 1
     * 1 - 0
     * 0 - Button 6
     * 
     * Byte 2
     * 7 - Button 2
     * 6 - Button 5
     * 5 - Button 9
     * 4 - 1 = HatPush?
     * 3 - Button 7
     * 2 - Button 13
     * 1 - Button 8
     * 0 - 1 = HatPush?               
     * 
     * Byte 3
     * 7 - Button 3
     * 6 - Button 10
     * 5 - HatLeft
     * 4 - HatUp
     * 3 - HatRight
     * 2 - HatDown
     * 1 - Button 4
     * 0 - Button 1
    */
    
    #include <SPI.h>
    #include <Joystick.h>
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00};
    bool btnState, joyBtnState, prevJoyBtnState;
    int bit2btn[] = {-1,-1,-1,-1,-1,-1,-1,8,  -1,2,1,-1,5,7,6,5,  4,0,11,9,12,10,3,-1};                 //number the buttons - Needs editing? New doesn't match original
    
    void setup() {
    //input from wheel
      Serial.begin(9600);
      SPI.beginTransaction(SPISettings());
      SPI.begin();                     
      pinMode(slaveSelectPin, OUTPUT);
    //output to joystick
      Joystick.begin();
    }
    
    void loop() {
    // tell the wheel, that we are ready to read the data now
      digitalWrite(slaveSelectPin, LOW);
      
    //read the next 4 bytes (get 2's compliment) - Why read 4 bytes? Only 3 are being sent
      for(int i=0; i<4; i++) 
        currBytes[i] = ~SPI.transfer(0x00);
      
    //deal with the buttons first - Basically, this whole section until //release the wheel looks a bit unfinished.
      for(int i=0; i<3; i++)                                                                            //process the three bytes
        for(int b=0; b<8; b++)                                                                          //one bit at a time
          if((btnState=currBytes[i] & pos[b])!=(prevBytes[i] & pos[b]))
          Joystick.begin(); - ALready did this in void setup, necessary?
            Joystick.button(13, joyBtnState);                                                           //if the bit has changed send the update     
      
      joyBtnState = (currBytes[3] & pos[0]) && !(currBytes[2] & 0x3c);  
        if(joyBtnState != prevJoyBtnState)
          Joystick.button(13, joyBtnState);
      
      for(int i=0;i<3;i++)
        prevBytes[i] = currBytes[i];                                                                    //finally update the just read input to the the previous input for the next cycle
          prevJoyBtnState = joyBtnState;
    
    //release the wheel
      digitalWrite(slaveSelectPin, HIGH);
      }
    I get ZERO output from htis.

    Compiles nicely, uploads nicely. Is readable via usbviewer, recognised as a windows device...
    Doesn't do anything else. No button presses registered.
    Last edited by RobinNoGood; 01-16-2023 at 11:13 PM.

  4. #29
    There are 2 versions of this original sketch, both of which contain

    Code:
    #include <SPI.h>
    #include <Joystick.h>
    
    Joystick_ Joystick(
      JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 14, 0,
      false, false, false, false, false, false,
      false, false, false, false, false); 
      
    const int slaveSelectPin = 7;
    Is this necessary? Can it be replicated TeensyLC?

  5. #30
    Googled 'arduino, bit2btn' ... just turned up a goldmine:

    once again using:

    "
    Joystick_ Joystick(
    JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 21, 1, // 21 buttons, 1 hatswitch
    false, false, false, false, false, false,
    false, false, false, false, false);
    "

    Code:
    /*
     * Code by Insert Coin
     * V1.01 February 2022
     * Code is an enhanced version of Noel McCullagh's code (see https://www.noelmccullagh.com)
     * which he based on Taras' code at http://rr-m.org
     * So thank you both :-)
     * Enhancements: 
     *  - supports hot swapping of Thrustmaster R383, F1 and Ferrari 599xx wheels
     *  - all buttons are working
     *  - button numbering is the same as when the wheels are on a Thrustmaster base
     *    (paddles are always buttons 1 and 2 for example)
     *    
     * V1.01 October 2022: tiny bug fixed, 'button pressed' was sent continuously over USB as long as
     * a button was pressed (telling 'button pressed' once is enough)
    */
    
    /*
    * On Arduino Pro Micro side it must be connected as follows:
     *          ----___----
     *        / 6   [ ]   5 \
     *       |      [_]      |   (as seen from the female front of the connector)
     *       | 4           3 |
     *        \___       ___/
     *            |2   1|
     *            \_____/
     *            
     * 1              -> not used (or can be connected to arduino MOSI pin 16)
     * 2 Green - GND  -> Arduino Pro Micro GND pin
     * 3 White - MISO -> Arduino Pro Micro pin 14
     * 4 Yellow - SS  -> Arduino Pro Micro pin 7
     * 5 Black - SCK  -> Arduino Pro Micro pin 15
     * 6 Red - +VCC   -> Arduino +5V pin (or RAW if USB current is +5V already)
     * 
     * Wheels and official Thrustmaster button numbers:
     * 
     * R383 wheel                     F1 wheel                       Ferrari 599xx
     * ----------------------------   ----------------------------   --------------------------------
     * Byte 1                         Byte 1                         Byte 1
     * 7 - constant 0                 7 - DRS (5)    (yes, odd)      7 - constant 1
     * 6 - constant 0                 6 - constant 0                 6 - constant 0
     * 5 - constant 1                 5 - constant 1                 5 - constant 1
     * 4 - constant 1                 4 - constant 1                 4 - left paddle (1)
     * 3 - constant 0                 3 - left paddle (1)            3 - right paddle (2)
     * 2 - constant 1                 2 - right paddle (2)           2 - PIT (blue upper left) (3)
     * 1 - constant 0                 1 - N (3)                      1 - WASH (blue down left) (4)
     * 0 - bottom right yellow (6)    0 - PIT (4)                    0 - RADIO (blue upper right) (5)
     * 
     * Byte 2                         Byte 2                         Byte 2
     * 7 - right paddle (2)           7 - START (13)                 7 - black down left (6)
     * 6 - top right black (5)        6 - 10+ (6)                    6 - MAIN left (7)
     * 5 - top right red (9)          5 - B0 (7)                     5 - MAIN right (8)
     * 4 - constant 0                 4 - WET (8)                    4 - SCROLL (red upper right) (9)
     * 3 - bottom left red (7)        3 - PL (9)                     3 - FLASH (red upper left) (10)
     * 2 - bottom right white (13)    2 - K (10)                     2 - constant 0
     * 1 - bottom right red (8)       1 - PUMP (11)                  1 - constant -
     * 0 - constant 0                 0 - 1- (12)                    0 - MAIN pushed in (13)
     * 
     * Byte 3                         Byte 3                         Byte 3
     * 7 - bottom left yellow (3)     7 - right Dpad up (18)         7 - Dpad down
     * 6 - top left red (10)          6 - left Dpad down             6 - Dpad right
     * 5 - Dpad left                  5 - left Dpad right            5 - Dpad left
     * 4 - Dpad up                    4 - left Dpad left             4 - Dpad up
     * 3 - Dpad right                 3 - left Dpad up               3 - constant 0
     * 2 - Dpad down                  2 - right Dpad down (19)       2 - constant 0
     * 1 - bottom left yellow (4)     1 - right Dpad right (20)      1 - constant 0
     * 0 - left paddle                0 - right Dpad left (21)       0 - constant 0
     * 
     * Byte 4                         Byte 4
     * 7 - 1 when Dpad pressed        7 - 
     * 6 - 1 when Dpad pressed        6 - CHRG down (16)
     * 5 - 1 when Dpad pressed        5 - DIF IN up (14)
     * 4 - 1 when Dpad pressed        4 - DIF IN down (15)
     * 3 - 1 when Dpad pressed        3 - CHRG up (17)
     * 2 - 1 when Dpad pressed        2 - 
     * 1 - 1 when Dpad pressed        1 - 
     * 0 - 1 when Dpad pressed        0 -
    */
    
    #include <SPI.h>
    #include <Joystick.h>
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00, 0x00, 0x00};
    int wheelbyte, fourthbyte, fifthbyte, wheelID;
    bool btnState, joyBtnState, prevJoyBtnState, buttonsreset, wheelIdentified;
    const bool debugging = false; // Set to true to see wheel bits debug messages on the com port
    int bit2btn[] = {-1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1}; // working array of buttons
    int F599Btn[] = {-1,-1,-1,0,1,2,3,4,  5,6,7,8,9,-1,-1,12,  33,32,34,31,-1,-1,-1,-1,  -1,-1,-1,-1,-1,-1,-1,-1}; // button numbers 599xx wheel
    int R383Btn[] = {-1,-1,-1,-1,-1,-1,-1,5,  1,4,8,-1,6,12,7,-1,  2,9,34,31,32,33,3,0,  -1,-1,-1,-1,-1,-1,-1,-1}; // button numbers R383 wheel
    int F1Btn[] = {4,-1,-1,-1,0,1,2,3,  12,5,6,7,8,9,10,11,  17,33,32,34,31,18,19,20,  -1,15,13,14,16,-1,-1,-1}; // button numbers F1 wheel
    
    void setup() {
      //input from wheel
      Serial.begin(9600);
      SPCR |= _BV(CPHA);
      SPCR |= _BV(CPOL);
      SPI.beginTransaction(SPISettings(40000, MSBFIRST, SPI_MODE0));
      SPI.begin();                     
      pinMode(slaveSelectPin, OUTPUT);
    
      //output to joystick
      Joystick.begin();
    }
    
    // print byte as binary, zero padded if needed 
    // "127" -> "01111111"
    void printBinary(byte data) {
     for(int i=7; i>0; i--) {
       if (data >> i == 0) {
         Serial.print("0");
       } else {
         break;
       }
     }
     Serial.print(data,BIN);
     Serial.print(" ");
    }
    
    void loop() {
      // tell the wheel, that we are ready to read the data now
      digitalWrite(slaveSelectPin, LOW);
      // the chips in the wheel need some time to wake up
      delayMicroseconds(40);
      
      //read the wheel's 5 bytes
      for(int i=0; i<5; i++) {
        currBytes[i] = ~SPI.transfer(0x00);
        delayMicroseconds(40);
      }
    
      // release the wheel
      digitalWrite(slaveSelectPin, HIGH);
      delayMicroseconds(40);
      
      if (debugging) {
        for(int i=0; i<5; i++) {
          printBinary(currBytes[i]);
          Serial.print("\t");
        }
        Serial.println();
      }
    
      // Check for sane input: is the wheel plugged in?
      // Unplugged: first byte has all bits set or unset
      // When plugged in F1 and Ferrari 599xx wheel has bits 7, 6, 5 set as 101 (160 dec)
      // Sparco R383 has bits 7, 6, 5 set as 001 (32 dec)
      wheelbyte = currBytes[0] & B11100000;
      fourthbyte = currBytes[3] & B00100000;
      fifthbyte = currBytes[4] & B00001111;
      buttonsreset = false;
      
      while ((wheelbyte != 192) and (wheelbyte != 160) and (wheelbyte != 32)) {  // unknown wheel or wheel unplugged
    
         wheelIdentified = false;
            
         // Reset all buttons to avoid stuck buttons when unplugged
         if (buttonsreset == false) {
            for(int b=0; b<21; b++)        // one button at a time
            buttonsreset = true;           // do it just once
         }
         
         if (debugging) Serial.println("Wheel not plugged in, waiting...");
    
         // tell the wheel, that we are ready to read the data now
         digitalWrite(slaveSelectPin, LOW);
         // the chips in the wheel need some time to wake up
         delayMicroseconds(40); 
         
         // read the wheel's 5 bytes
         for(int i=0; i<5; i++) {
           currBytes[i] = ~SPI.transfer(0x00);
           delayMicroseconds(40);
         }
    
         // release the wheel
         digitalWrite(slaveSelectPin, HIGH);
         delayMicroseconds(40);
    
         if (debugging) for(int i=0; i<5; i++) {
           printBinary(currBytes[i]);
           Serial.print("\t");
         }
         if (debugging) Serial.println();
    
         wheelbyte = currBytes[0] & B11100000;  // same as above, for identifying the wheel below
         fourthbyte = currBytes[3] & B00100000;
         fifthbyte = currBytes[4] & B00001111;
         
         // Still no sane input? Wait...
         if ((wheelbyte != 192) and (wheelbyte != 160) and (wheelbyte != 32)) {
           delay(1000);
         }
      }
    
      if (wheelIdentified == false) {
        if ((wheelbyte == 160) and (fifthbyte == 0)) {
        wheelID = 2;                                           // Ferrari 599xx wheel
        memcpy(bit2btn,F599Btn,sizeof(F599Btn));               // button numbers 599xx wheel to working array
        wheelIdentified = true;
        } else if (wheelbyte == 32) {
                 if (((fourthbyte == 0) and (fifthbyte == 0)) or ((currBytes[3] == 255) and (currBytes[4] == 255))) {
                    wheelID = 3;                               // Sparco R383 connected
                    memcpy(bit2btn,R383Btn,sizeof(R383Btn));   // button numbers R383 wheel to working array
                    wheelIdentified = true;
                 } else if ((wheelbyte == 32) and (fifthbyte == 15)) {      // F1 wheel sets last four bits of byte 5 as 1, 599xx wheel sets byte 5 as zero
                          wheelID = 1;                          // F1 wheel connected
                          memcpy(bit2btn,F1Btn,sizeof(F1Btn));  // button numbers F1 wheel to working array
                          wheelIdentified = true;
                        }
               }
      }
    
      if (debugging) { 
        Serial.print(wheelbyte);
        Serial.print("\t");
        Serial.println(wheelID);
      }
      
      // deal with the buttons first
      if (wheelIdentified) 
        for(int i=0; i<4; i++)      //process the four bytes
          for(int b=0; b<8; b++)     //one bit at a time
            if((currBytes[i] & pos[b])!=(prevBytes[i] & pos[b])) {  // if the buttonstate has changed
              btnState=currBytes[i] & pos[b];        
              if ((bit2btn[(i*8)+b] >= 31) and (bit2btn[(i*8)+b] <= 34)) {   // hatswitch (Dpad) pressed?
                if (btnState == 0)               // button released?
                  Joystick.button(13, joyBtnState);      // send the update     
          
          }
    
      if ((wheelIdentified) and (wheelID == 3)) {                         // only for R383 wheel
        joyBtnState = (currBytes[3] & pos[0]) && !(currBytes[2] & 0x3c);  // if hatswitch is pressed in the middle
        if (joyBtnState != prevJoyBtnState)
          Joystick.button(13, joyBtnState);                            // press button 14
      }
      
      for(int i=0;i<5;i++)
        prevBytes[i] = currBytes[i];   // finally update the just read input to the the previous input for the next cycle
    
      prevJoyBtnState = joyBtnState;
            }}
    It shows my wheel outputs 4 bytes, and the hat-swith 'push' is in that 4th byte, and which also fixes the 'int bit2btn[]' discrepancy.

    There's obviously a ton of other stuff in here too, but 1 step at a time.
    Last edited by RobinNoGood; 01-17-2023 at 12:14 AM.

  6. #31
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,714
    Good job on searching. Have fun.

  7. #32
    I can't get past bit2btn.

    That above post I found is literally the only relevant google return.
    Nothing in the Arduino reference.

    and "Joystick_ Joystick..."... what is that even doing?

  8. #33
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,382
    Quote Originally Posted by RobinNoGood View Post
    I can't get past bit2btn.

    That above post I found is literally the only relevant google return.
    Nothing in the Arduino reference.

    and "Joystick_ Joystick..."... what is that even doing?
    From your post #30 it is just an integer array: int bit2btn[] = {-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1}; // working array of buttons
    Note there is code in there that overwrites this array, I am guessing depending on which wheel or the like you are using...

    My strong guess is that you have 4 bytes of data being returned. Each bit may correspond to a button, and this should do the mapping.

    I would think something like one of these loops, should process the data, note for my own here I added in {} that the code above did not to make it clearer at least to me
    Code:
        for(int i=0; i<4; i++)  {    //process the four bytes
          for(int b=0; b<8; b++) {    //one bit at a time
            if((currBytes[i] & pos[b])!=(prevBytes[i] & pos[b])) {  // if the buttonstate has changed
              btnState=currBytes[i] & pos[b]; 
              int b2bindex = i * 8 + b;
              if (bit2bnt[b2bindex] != -1) {
                joystick.button(bit2bnt[b2bindex], btnState);
              }
            }
          }
        }
    Note typed on the fly so probably issues!

    Note some of the code you posted makes no sense, like places that have, the iterations above, plus initial ifs...
    Code:
              if ((bit2btn[(i*8)+b] >= 31) and (bit2btn[(i*8)+b] <= 34)) {   // hatswitch (Dpad) pressed?
                if (btnState == 0)               // button released?
                  Joystick.button(13, joyBtnState);      // send the update
    That is i goes from 0-3 and b goes 0-7, so the largest index is 3*8+7 or 31 so it could be only the last bit, but hat switch.
    usually is 4 bits or an an angle. And the Joystick code wants an angle:
    Joystick.hat(angle); // "angle" is 0,45,90,135,180,225,270,315,-1

    So you will need to understand which bits (or is it a different byte?) correspond to UP/DOWN/LEFT/RIGHT and compute the angle to pass in or -1 to be centered.

    More information on USB Joystick up at: https://www.pjrc.com/teensy/td_joystick.html

  9. #34
    Thank you Kurt.

    So, [int bit2btn] isn't saying 'these are the buttons and their current values', it's just 'here are some buttons?

    Could I just use this from the Joystick Tutorial to set individual Byte/bit combos as a Joystick.button?

    Code:
      Joystick.button(1, digitalRead(1));
      Joystick.button(2, digitalRead(1));
    Maybe something like:
    Code:
    const int slaveSelectPin = 10;
    Joystick.button(1, [byte/bitRead = x) ] ); //bearing i mind I don't know how this would really look... 'CurrByte & pos [b]' maybe?
    Joystick.button(2, [byte/bitRead = y) ] );
    
    void setup() {
    //input from wheel
       Serial.begin(9600);
       SPI.beginTransaction(SPISettings());
       SPI.begin();
       pinMode(slaveSelectPin, OUTPUT);
    
    //output to joystick
       Joystick.begin();
    }
    
    void loop() {
    //tell the wheel, that we are ready to read the data now
       digitalWrite(slaveSelectPin, LOW);
    }
    
    //read the wheel's 5 bytes
       for (int i = 0; i < 5; i++) {
          currBytes[i] = ~SPI.transfer(0x00);
    
          if (joyBtnState != prevJoyBtnState)
             Joystick.button(13, joyBtnState);
    
    
    //release the wheel
       digitalWrite(slaveSelectPin, HIGH);

  10. #35
    I'm parsing #30 down to what seems like the bare bones.

    I've commented out the "Joystick_ Joystick" stuff, because that looks like it's trying to draw on a a DynamicHID/PluggableUSB resource from the author's modded library... whih doesn't work on the TLC

    Code:
    #include <SPI.h>
    #include <Joystick.h>
    
    //Joystick_ Joystick(
    //JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 21, 1,    // 21 buttons, 1 hatswitch
    //false, false, false, false, false, false,
    //false, false, false, false, false);
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00, 0x00, 0x00};
    int wheelID;
    bool btnState, joyBtnState, prevJoyBtnState, buttonsreset, wheelIdentified;
    const bool debugging = false; // Set to true to see wheel bits debug messages on the com port
    int bit2btn[] = { -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1}; // working array of buttons
    
    void setup() {
    //input from wheel
    Serial.begin(9600);
    SPCR |= _BV(CPHA);
    SPCR |= _BV(CPOL);
    SPI.beginTransaction(SPISettings(40000, MSBFIRST, SPI_MODE0));
    SPI.begin();
    pinMode(slaveSelectPin, OUTPUT);
    
    //output to joystick
    Joystick.begin();
    }
    
    void loop() {
    // tell the wheel, that we are ready to read the data now
    digitalWrite(slaveSelectPin, LOW);
    // the chips in the wheel need some time to wake up
    delayMicroseconds(40);
    
    //read the wheel
    for (int i = 0; i < 4; i++) {
    currBytes[i] = ~SPI.transfer(0x00);
    delayMicroseconds(40);
    }
    
    // release the wheel
    digitalWrite(slaveSelectPin, HIGH);
    delayMicroseconds(40);
    
    // tell the wheel, that we are ready to read the data now
    digitalWrite(slaveSelectPin, LOW);
    // the chips in the wheel need some time to wake up
    delayMicroseconds(40);
    
    // read the wheel
    for (int i = 0; i < 4; i++) {
    currBytes[i] = ~SPI.transfer(0x00);
    delayMicroseconds(40);
    }
    
    // release the wheel
    digitalWrite(slaveSelectPin, HIGH);
    delayMicroseconds(40);
    
    // deal with the buttons first
    
    for (int i = 0; i < 4; i++) //process the four bytes
    for (int b = 0; b < 8; b++) //one bit at a time
    if ((currBytes[i] & pos[b]) != (prevBytes[i] & pos[b])) { // if the buttonstate has changed
    btnState = currBytes[i] & pos[b];
    if ((bit2btn[(i * 8) + b] >= 31) and (bit2btn[(i * 8) + b] <= 34)) { // hatswitch (Dpad) pressed?
    if (btnState == 0)               // button released?
    Joystick.button(i, LOW); // release hatswitch
    else Joystick.button(i, (bit2btn[(i * 8) + b] - 31) * 90); // direction in 0, 90, 180, 270 degrees
    } else Joystick.button(bit2btn[(i * 8) + b], btnState);  // send the update
    
    }
    
    joyBtnState = (currBytes[3] & pos[0]) && !(currBytes[2] & 0x3c);  // if hatswitch is pressed in the middle
    if (joyBtnState != prevJoyBtnState)
    Joystick.button(14, 1);                            // press button 14
    
    for (int i = 0; i < 4; i++)
    prevBytes[i] = currBytes[i];   // finally update the just read input to the the previous input for the next cycle
    
    prevJoyBtnState = joyBtnState;
    
    }
    In #26 Kurt wrote "I believe you can just do something like joystick.button(13, joyBtnState);"

    I thought 13 was an Arduino operation code... but that was just an example button number, right?

    I'm having trouble understanding what's happening with the 'button - press loop'.
    Is Joystick.button(i, ...) a thing? I want it to do the thing it needs to do, rather than explicitly telling it to [do this].

    " if ((bit2btn[(i * 8) + b] >= 31) and (bit2btn[(i * 8) + b] <= 34)) { // hatswitch (Dpad) pressed?"
    31 through 34... are these the numeric values of Byte 4?

    Do I need to change that? My Byte 4 reads 00000000 when pressed... so a numeric value of 0?
    Since all my buttons read 0 when pressed: HatUp, HatDown, HatLeft, HatRight... will also all read 0?

    All my buttons will read 0?

    e.g. in Blue above, $currBytes3 & pos 0 && currBytes2 & 0x3c

    does that add up to 0 to press the Hat?

    Further on the Hat
    Code:
    else Joystick.button(0, (bit2btn[(i * 8) + b] - 31) * 90); // direction in 0, 90, 180, 270 degrees
    } else Joystick.button(bit2btn[(i * 8) + b], btnState);  // send the update
    The hat angle code is in there at 90 deg increments. That switch is not a high quality item and is really finniky to use. I think all TM wheels have that switch set to a 4+Push rather than an actual Hat. The HatPush is in Byte 4. All of Byte 4.. and every Hatpress is combo with it.

    11000101 11111111 11111111 11111111 - Nothing
    11000101 11111111 11111111 00000000 - HatPush
    11000101 11111111 11101111 00000000 - HatUp, no push
    11000101 11111111 11011111 00000000 - HatLeftt, no push
    11000101 11111111 11110111 00000000 - HatRight, no push
    11000101 11111111 11111011 00000000 - HatDown, no push

    I think it would be easier to forget this is a HatSwitch/D-Pad and treat it like 5 separate buttons if the way it's setup will allow?
    Last edited by RobinNoGood; 01-17-2023 at 09:11 PM.

  11. #36
    ....

    all of which leaves me with this:
    Code:
    /*
       Byte 1                         Byte 2                        Byte 3                        Byte 4
       7 - constant 1                 7 - right paddle (2)          7 - bottom left yellow (3)    7 - 0 when Dpad pressed
       6 - constant 1                 6 - top right black (5)       6 - top left red (10)         6 - 0 when Dpad pressed
       5 - constant 0                 5 - top right red (9)         5 - Dpad left                 5 - 0 when Dpad pressed
       4 - constant 0                 4 - constant 1                4 - Dpad up                   4 - 0 when Dpad pressed
       3 - constant 0                 3 - bottom left red (7)       3 - Dpad right                3 - 0 when Dpad pressed
       2 - constant 1                 2 - bottom right white (13)   2 - Dpad down                 2 - 0 when Dpad pressed
       1 - constant 0                 1 - bottom right red (8)      1 - bottom left yellow (4)    1 - 0 when Dpad pressed
       0 - bottom right yellow (6)    0 - constant 1                0 - left paddle               0 - 0 when Dpad pressed
    */
    
    #include <SPI.h>
    #include <Joystick.h>
    
    //Joystick_ Joystick(
    //JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 21, 1,    // 21 buttons, 1 hatswitch
    //false, false, false, false, false, false,
    //false, false, false, false, false);
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00, 0x00};
    bool btnState, joyBtnState, prevJoyBtnState, buttonsreset;
    int bit2btn[] = { -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1}; // working array of buttons
    
    void setup() {
      //input from wheel
      Serial.begin(9600);
      SPI.beginTransaction(SPISettings());
      SPI.begin();
      pinMode(slaveSelectPin, INPUT);
    
      //output to joystick
      Joystick.begin();
    }
    
    void loop() {
      // tell the wheel, that we are ready to read the data now
      digitalWrite(slaveSelectPin, HIGH);
      // the chips in the wheel need some time to wake up
      delayMicroseconds(40);
    
      // read the wheel
      for (int i = 0; i < 4; i++) {
        (currBytes[i]) = ~SPI.transfer(0x00);
        delayMicroseconds(40);
      }
    
      // release the wheel
      digitalWrite(slaveSelectPin, LOW);
      delayMicroseconds(40);
    
      // assign the buttons
    
      for (int i = 0; i < 4; i++) //process the four bytes
        for (int b = 0; b < 8; b++) //one bit at a time
          if ((currBytes[i] & pos[b]) != (prevBytes[i] & pos[b])) {                    // if the buttonstate has changed
            btnState = currBytes[i] & pos[b];
            if (btnState == 0)                                                         // button released?
              Joystick.button(bit2btn[(i * 8) + b], 1);                                // press button
            if (btnState >= 1)
              Joystick.button(bit2btn[(i * 8) + b], 0);                                //release button
          }
    
      for (int i = 0; i < 4; i++)
        prevBytes[i] = currBytes[i];   // finally update the just read input to the the previous input for the next cycle
    
      prevJoyBtnState = joyBtnState;
    }
    ... and still no buttons.
    Last edited by RobinNoGood; 01-17-2023 at 10:31 PM.

  12. #37
    Last revision before bed.

    I think I'm starting to understand how the button press/release loop works,... but obviously not well enough.

    "int R383Btn[]" has gone back in to give assignable button numbers
    "memcpy" to translate (bit2btn->R383btn) is in the 'setup', might it be better after the 'read'?

    I took "joyBtnState" out. But now I'm thinking that's what TLC sends to Windows, while "btnState" is what the wheel sends to TLC?

    If any code fairies want to fix this while I'm sleeping, that'd be great cheers..

    Code:
    /*
       Byte 1                         Byte 2                        Byte 3                        Byte 4
       7 - constant 1                 7 - right paddle (2)          7 - bottom left yellow (3)    7 - 0 when Dpad pressed
       6 - constant 1                 6 - top right black (5)       6 - top left red (10)         6 - 0 when Dpad pressed
       5 - constant 0                 5 - top right red (9)         5 - Dpad left                 5 - 0 when Dpad pressed
       4 - constant 0                 4 - constant 1                4 - Dpad up                   4 - 0 when Dpad pressed
       3 - constant 0                 3 - bottom left red (7)       3 - Dpad right                3 - 0 when Dpad pressed
       2 - constant 1                 2 - bottom right white (13)   2 - Dpad down                 2 - 0 when Dpad pressed
       1 - constant 0                 1 - bottom right red (8)      1 - bottom left yellow (4)    1 - 0 when Dpad pressed
       0 - bottom right yellow (6)    0 - constant 1                0 - left paddle (1)           0 - 0 when Dpad pressed
    */
    
    #include <SPI.h>
    #include <Joystick.h>
    
    //Joystick_ Joystick(
    //JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 21, 1,                                                                                                // 21 buttons, 1 hatswitch
    //false, false, false, false, false, false,
    //false, false, false, false, false);
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00, 0x00};
    bool btnState, prevBtnState;
    int bit2btn[] = { -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1};      //working array of buttons
    int R383Btn[] = { -1, -1, -1, -1, -1, -1, -1, 5,  1, 4, 8, -1, 6, 12, 7, -1,  2, 9, 34, 31, 32, 33, 3, 0,  -1, -1, -1, -1, -1, -1, -1, -1};                //R383 button numbers
    //int R383Btn[] = {-1,-1,-1,-1,-1,-1,-1,6,  2,5,9,-1,7,13,8,-1,  3,10,12,13,14,15,4,1,  11,-1,-1,-1,-1,-1,-1,-1};                                          //TM R383 button numbers
    
    void setup() {
      //input from wheel
      Serial.begin(9600);
      SPI.beginTransaction(SPISettings());
      pinMode(slaveSelectPin, OUTPUT);
      SPI.begin();
      //output to joystick
      memcpy(bit2btn, R383Btn, sizeof(R383Btn));                                                                                                               // Setup or Loop? Convert bit2btn
      Joystick.begin();
    
    }
    
    void loop() {
      // tell the wheel, that we are ready to read the data now
      digitalWrite(slaveSelectPin, LOW);
      // the chips in the wheel need some time to wake up
      delayMicroseconds(40);
    
      // read the wheel
      for (int i=0; i<4; i++) {
        (currBytes[i]) = ~SPI.transfer(0x00);
        delayMicroseconds(40);
      }
    
      // release the wheel
      digitalWrite(slaveSelectPin, HIGH);
      delayMicroseconds(40);
    
      // press/release loop
    
      for (int i=0; i<4; i++)                                                                                                                                  //process the four bytes
        for (int b=0; b<8; b++)                                                                                                                                //one bit at a time
          if ((currBytes[i] & pos[b]) != (prevBytes[i] & pos[b])) {                                                                                            // if the buttonstate has changed
            btnState = currBytes[i] & pos[b];
            Joystick.button(bit2btn[(i*8) + b], btnState);                                                                                                     // press/release button
          }
    
      for (int i=0; i<4; i++)
        prevBytes[i] = currBytes[i];                                                                                                                           // finally update the just read input to the the previous input for the next cycle
      prevBtnState = btnState;
    }
    It's a shame ↓this↓ doesn't work:
    Code:
      // press/release loop
    
      for (int i=0; i<4; i++)                                                                                                                                                                         
        for (int b=0; b<8; b++)                                                                                                                                                                    
          if ((currBytes[i] & pos[b]) != (prevBytes[i] & pos[b])) {                                                                                                         
            btnState = currBytes[i] & pos[b];
            Joystick.button(bit2btn[(i*8) + b], btnState);                                                                                                                     
          }
    I like how simple it is.
    Last edited by RobinNoGood; 01-17-2023 at 11:58 PM.

  13. #38
    Code:
      if ((wheelIdentified) and (wheelID == 3)) {                         // only for R383 wheel
        joyBtnState = (currBytes[3] & pos[0]) && !(currBytes[2] & 0x3c);  // if hatswitch is pressed in the middle
        if (joyBtnState != prevJoyBtnState)
          Joystick.setButton(13, joyBtnState);                            // press button 14
      }
    It looks like joyBtnState was used only for the hatswitch.

    " Joystick.setButton(13, joyBtnState); // press button 14"

    is that jsut a typo?

  14. #39
    I've managed to get the code to the barest of bones:

    Code:
    JUST PRESS THE BUTTON!
    I know TLC can read & process buttonstate and changes to buttonstate through Serial Print/Serial Monitor..
    I've seen this in action.

    ... but I haven't seen TLC sending a buttonstate or changes to buttonstate to Windows.

    So, I thought this would be a lot easier if I could [press the button], and then move on to the nuance of pressing a specific button at a particular time.

    Code:
    #include <SPI.h>
    #include <Joystick.h>
    
    const int slaveSelectPin = 10;
    
    void setup() {
      Joystick.begin();
    }
    
    void loop() {
      Joystick.button(1, 1);
    }

  15. #40
    This should get all the button(x, 1) lit up, right?

    Click image for larger version. 

Name:	Screenshot (1039).png 
Views:	4 
Size:	62.6 KB 
ID:	30166

  16. #41
    This is what USBView is seeing
    Click image for larger version. 

Name:	Screenshot (1040).png 
Views:	3 
Size:	52.3 KB 
ID:	30167
    Code:
    [Port8]  :  USB Composite Device
    
    
    Is Port User Connectable:         yes
    Is Port Debug Capable:            no
    Companion Port Number:            0
    Companion Hub Symbolic Link Name: 
    Protocols Supported:
     USB 1.1:                         yes
     USB 2.0:                         yes
     USB 3.0:                         no
    
    Device Power State:               PowerDeviceD0
    
           ---===>Device Information<===---
    English product name: "Keyboard/Mouse/Joystick"
    
    ConnectionStatus:                  
    Current Config Value:              0x01  -> Device Bus Speed: Full (is not SuperSpeed or higher capable)
    Device Address:                    0x54
    Open Pipes:                           6
    
              ===>Device Descriptor<===
    bLength:                           0x12
    bDescriptorType:                   0x01
    bcdUSB:                          0x0110
    bDeviceClass:                      0x00  -> This is an Interface Class Defined Device
    bDeviceSubClass:                   0x00
    bDeviceProtocol:                   0x00
    bMaxPacketSize0:                   0x40 = (64) Bytes
    idVendor:                        0x16C0 = Van Ooijen Technische Informatica
    idProduct:                       0x0482
    bcdDevice:                       0x0273
    iManufacturer:                     0x01
         English (United States)  "Teensyduino"
    iProduct:                          0x02
         English (United States)  "Keyboard/Mouse/Joystick"
    iSerialNumber:                     0x03
         English (United States)  "9364450"
    bNumConfigurations:                0x01
    
              ---===>Open Pipes<===---
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x83  -> Direction: IN - EndpointID: 3
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x01
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x85  -> Direction: IN - EndpointID: 5
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x01
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0040 = 0x40 bytes
    bInterval:                         0x01
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x02  -> Direction: OUT - EndpointID: 2
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0020 = 0x20 bytes
    bInterval:                         0x02
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x84  -> Direction: IN - EndpointID: 4
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x000C = 0x0C bytes
    bInterval:                         0x02
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x86  -> Direction: IN - EndpointID: 6
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x04
    
           ---===>Full Configuration Descriptor<===---
    
              ===>Configuration Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x02
    wTotalLength:                    0x008D  -> Validated
    bNumInterfaces:                    0x05
    bConfigurationValue:               0x01
    iConfiguration:                    0x00
    bmAttributes:                      0xC0  -> Self Powered
    MaxPower:                          0x32 = 100 mA
    
              ===>Interface Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x04
    bInterfaceNumber:                  0x00
    bAlternateSetting:                 0x00
    bNumEndpoints:                     0x01
    bInterfaceClass:                   0x03  -> HID Interface Class
    bInterfaceSubClass:                0x01
    bInterfaceProtocol:                0x01
    iInterface:                        0x00
    
              ===>HID Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x21
    bcdHID:                          0x0111
    bCountryCode:                      0x00
    bNumDescriptors:                   0x01
    bDescriptorType:                   0x22 (Report Descriptor)
    wDescriptorLength:               0x003F
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x83  -> Direction: IN - EndpointID: 3
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x01
    
              ===>Interface Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x04
    bInterfaceNumber:                  0x01
    bAlternateSetting:                 0x00
    bNumEndpoints:                     0x01
    bInterfaceClass:                   0x03  -> HID Interface Class
    bInterfaceSubClass:                0x00
    bInterfaceProtocol:                0x00
    iInterface:                        0x00
    
              ===>HID Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x21
    bcdHID:                          0x0111
    bCountryCode:                      0x00
    bNumDescriptors:                   0x01
    bDescriptorType:                   0x22 (Report Descriptor)
    wDescriptorLength:               0x0054
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x85  -> Direction: IN - EndpointID: 5
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x01
    
              ===>Interface Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x04
    bInterfaceNumber:                  0x02
    bAlternateSetting:                 0x00
    bNumEndpoints:                     0x02
    bInterfaceClass:                   0x03  -> HID Interface Class
    bInterfaceSubClass:                0x00
    bInterfaceProtocol:                0x00
    iInterface:                        0x00
    
              ===>HID Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x21
    bcdHID:                          0x0111
    bCountryCode:                      0x00
    bNumDescriptors:                   0x01
    bDescriptorType:                   0x22 (Report Descriptor)
    wDescriptorLength:               0x0021
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0040 = 0x40 bytes
    bInterval:                         0x01
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x02  -> Direction: OUT - EndpointID: 2
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0020 = 0x20 bytes
    bInterval:                         0x02
    
              ===>Interface Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x04
    bInterfaceNumber:                  0x03
    bAlternateSetting:                 0x00
    bNumEndpoints:                     0x01
    bInterfaceClass:                   0x03  -> HID Interface Class
    bInterfaceSubClass:                0x00
    bInterfaceProtocol:                0x00
    iInterface:                        0x00
    
              ===>HID Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x21
    bcdHID:                          0x0111
    bCountryCode:                      0x00
    bNumDescriptors:                   0x01
    bDescriptorType:                   0x22 (Report Descriptor)
    wDescriptorLength:               0x0055
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x84  -> Direction: IN - EndpointID: 4
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x000C = 0x0C bytes
    bInterval:                         0x02
    
              ===>Interface Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x04
    bInterfaceNumber:                  0x04
    bAlternateSetting:                 0x00
    bNumEndpoints:                     0x01
    bInterfaceClass:                   0x03  -> HID Interface Class
    bInterfaceSubClass:                0x00
    bInterfaceProtocol:                0x00
    iInterface:                        0x00
    
              ===>HID Descriptor<===
    bLength:                           0x09
    bDescriptorType:                   0x21
    bcdHID:                          0x0111
    bCountryCode:                      0x00
    bNumDescriptors:                   0x01
    bDescriptorType:                   0x22 (Report Descriptor)
    wDescriptorLength:               0x0028
    
              ===>Endpoint Descriptor<===
    bLength:                           0x07
    bDescriptorType:                   0x05
    bEndpointAddress:                  0x86  -> Direction: IN - EndpointID: 6
    bmAttributes:                      0x03  -> Interrupt Transfer Type
    wMaxPacketSize:                  0x0008 = 0x08 bytes
    bInterval:                         0x04

  17. #42
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,382
    Sorry I don't really do that much with some of the different USB types...

    But for me on a Teensy 3.2 I tried simple sketch:
    Code:
    uint8_t button_index = 1;
    void setup() {
      pinMode(13, OUTPUT);
    }
    void loop() {
      digitalToggleFast(13);
      Joystick.button(button_index, 0);
      button_index = (button_index == 32)? 1 : button_index + 1;
      Joystick.button(button_index, 1);
      delay(250);
    }
    I built for usb type: keyboard, mouse, joystick...

    I brought up the Gametroller or the like on Windows 11

    And it does show it walking through the buttons...
    Click image for larger version. 

Name:	Screenshot.jpg 
Views:	2 
Size:	25.5 KB 
ID:	30170

  18. #43
    Nice thank you Kurt.

    I go this up and running:
    Click image for larger version. 

Name:	Screenshot (1042).png 
Views:	9 
Size:	58.0 KB 
ID:	30171

    Unfortunately I also discovered the reason it wasn't working before:

    Click image for larger version. 

Name:	IMG_20230118_151746_2.jpg 
Views:	12 
Size:	150.8 KB 
ID:	30172

    Hamfistedness is Key to understanding quite a few 'unexplained' problems I feel.
    So, I'm going to have to work through everything from the beginning I think.

  19. #44
    I dont know if these white text warnings matter, but during verify/upload, I'm ocassionally getting:

    Code:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\usb_keyboard.c: In function 'unicode_to_keycode':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\usb_keyboard.c:151:40: warning: large integer implicitly truncated to unsigned type [-Woverflow]
      if (cpoint == UNICODE_EXTRA00) return (KEYCODE_EXTRA00) & 0x3FFF;
    I was specifically running ↓this↓, but I'm getting them regulalry, though not every time I verify/upload.

    Code:
    #include <Joystick.h>
    
    void setup() {
      Joystick.begin();
    }
    void loop() {
      Joystick.button(1, 1);
    }

  20. #45
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,382
    Quote Originally Posted by RobinNoGood View Post
    I dont know if these white text warnings matter, but during verify/upload, I'm ocassionally getting:

    Code:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\usb_keyboard.c: In function 'unicode_to_keycode':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\usb_keyboard.c:151:40: warning: large integer implicitly truncated to unsigned type [-Woverflow]
      if (cpoint == UNICODE_EXTRA00) return (KEYCODE_EXTRA00) & 0x3FFF;
    I was specifically running ↓this↓, but I'm getting them regulalry, though not every time I verify/upload.

    Code:
    #include <Joystick.h>
    
    void setup() {
      Joystick.begin();
    }
    void loop() {
      Joystick.button(1, 1);
    }
    My guess is Paul and/or someone who uses international keyboards should take a look at this.

    I am assuming you are using a none US keyboard for this.

  21. #46
    Yep, UK English.

    Might it be a hardware related issue? Board currently wont run either of the [just press the button] scripts.
    My hamfistedness could well have carried over into the repairs for my previous hamfistedness.

    if (currHamfistedness >= prevHamfistedness)
    bork;

  22. #47
    Senior Member
    Join Date
    Mar 2017
    Location
    Oakland, CA, USA
    Posts
    566
    I made an experimental PR that should fix the warning: https://github.com/PaulStoffregen/cores/pull/680

    Could you see if it fixes the warnings for you?
    Last edited by shawn; 01-19-2023 at 02:31 AM.

  23. #48
    Thank you Shawn. I've applied the changes, but I'm currently resoldering my board so I wont have any tests until this evening.

  24. #49
    I am become coder

    Click image for larger version. 

Name:	Screenshot (1043).jpg 
Views:	11 
Size:	106.5 KB 
ID:	30177

    Code:
    /*
       Byte 1                         Byte 2                        Byte 3                        Byte 4
       7 - constant 1                 7 - right paddle (2)          7 - bottom left yellow (3)    7 - 0 when Dpad pressed
       6 - constant 1                 6 - top right black (5)       6 - top left red (10)         6 - 0 when Dpad pressed
       5 - constant 0                 5 - top right red (9)         5 - Dpad left                 5 - 0 when Dpad pressed
       4 - constant 0                 4 - constant 1                4 - Dpad up                   4 - 0 when Dpad pressed
       3 - constant 0                 3 - bottom left red (7)       3 - Dpad right                3 - 0 when Dpad pressed
       2 - constant 1                 2 - bottom right white (13)   2 - Dpad down                 2 - 0 when Dpad pressed
       1 - constant 0                 1 - bottom right red (8)      1 - bottom left yellow (4)    1 - 0 when Dpad pressed
       0 - bottom right yellow (6)    0 - constant 1                0 - left paddle               0 - 0 when Dpad pressed
    */
    
    #include <SPI.h>
    #include <Joystick.h>
    
    //Joystick_ Joystick(
    //JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 21, 1,                                                                                                // 21 buttons, 1 hatswitch
    //false, false, false, false, false, false,
    //false, false, false, false, false);
    
    const int slaveSelectPin = 10;
    byte pos[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    byte currBytes[] = {0x00, 0x00, 0x00, 0x00};
    byte prevBytes[] = {0x00, 0x00, 0x00, 0x00};
    bool btnState, prevBtnState, joyBtnState, prevJoyBtnState;
    int bit2btn[] = { -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1,  -1, -1, -1, -1, -1, -1, -1, -1 } ;      //working array of buttons
    int R383Btn[] = { -1, -1, -1, -1, -1, -1, -1, 8,  2, 11, 10, -1, 5, 7, 6, -1,  4, 9, 15, 12, 13, 14, 3, 1,  16, 16, 16, 16, 16, 16, 16, 16};                //R383 button numbers
    
    void setup() {
      //input from wheel
      SPI.begin();
      SPI.beginTransaction(SPISettings());
      pinMode(slaveSelectPin, OUTPUT);
    
      //output to joystick
      Joystick.begin();
    }
    
    void loop() {
      // tell the wheel, that we are ready to read the data now
      digitalWrite(slaveSelectPin, LOW);
      // the chips in the wheel need some time to wake up
      delayMicroseconds(40);
    
      // read the wheel's 4 bytes
      for (int i = 0; i < 4; i++) {
        currBytes[i] = ~SPI.transfer(0x00);
        delayMicroseconds(40);
      }
    
      // release the wheel
      digitalWrite(slaveSelectPin, HIGH);
      delayMicroseconds(40); {
    
        memcpy(bit2btn, R383Btn, sizeof(R383Btn)); // button numbers R383 wheel to working array
    
        // deal with the buttons first
        for (int i = 0; i < 4; i++) //process the four bytes
          for (int b = 0; b < 8; b++) //one bit at a time
            if ((currBytes[i] & pos[b]) != (prevBytes[i] & pos[b])) { // if the buttonstate has changed
              btnState = currBytes[i] & pos[b];
              Joystick.button(bit2btn[(i * 8) + b], btnState);  // send the update
            }
            
        for (int i = 0; i < 4; i++)
          prevBytes[i] = currBytes[i];   // finally update the just read input to the the previous input for the next cycle
    
        prevJoyBtnState = joyBtnState;
      }
    }

    This is basically what I had in #37, I think. The hardware issues I've been having which caused the original look into this wheel might have been cropping up and I think I'm tracing those to my USB powered soundcard.
    They've been messing, I htink, with the entire USB bus, and hoipefully moving that to a separate PCIe bus will solve the issues.

    I have still to separate hatpress from hatpush, but Kurt, defrag and Shawn... thank you.

Posting Permissions

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