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

Thread: Button Press detector

  1. #1

    Button Press detector

    Hi,

    I've got a TeensyLC button box which used to output via USB as a game controller.

    And then I started tinkering before reading any manuals. It now doesn't output anything. It does work, I've been playing with example sketches to make sure I didn't completely ruin everything.

    Can I sketch (and by that I mean would you please tell me how/write it for me or point me at the right links) a button press/pin detector, (probably outputting relevant info to the Serial Monitor?) to find out which buttons are connected to which pins, so that I can start rebuilding the functionality I destroyed?

    Many Thanks.

  2. #2

  3. #3
    Thank you.

    I've been playing with 'DigitalRead'. Is there a way to monitor all pins and report their states?

    I've also used Examples>Teensy>USB-Joystick>Complete.
    In Windows Game Controller, there is no output.

  4. #4
    I got this:


    const int numButtons = 16;

    void setup() {
    Serial.begin(38400);
    for (int i=0; i<numButtons; i++)
    pinMode(i, INPUT);
    }

    void loop()
    {
    for (int i=0; i<numButtons; i++)
    if (digitalRead(i) == HIGH) {
    Serial.println("Button is not pressed...");
    } else {
    Serial.println("Button pressed!!!");
    }
    delay(2500);
    }

    Which prints as often as you want. But I only wnat it to print when there's a change, and which button/pins have changed. I take it some buttons are 'High' when unpressed? This doesn't acccount for those.

  5. #5
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,432
    It may be difficult to help much without more information.

    As I mentioned in a different thread recently. A few of us hacked up a sketch:
    Code:
    #ifdef ESP_PLATFORM
    #define digitalWriteFast digitalWrite
    #define digitalReadFast digitalRead
    #endif
    
    void setup()
    {
      Serial.begin(115200);
      while (!Serial && millis() < 4000 );
      Serial.println("Compile Time:: " __FILE__ " " __DATE__ " " __TIME__);
      Serial.printf("Num Digital Pins: %d\n", NUM_DIGITAL_PINS);
    
      testForShorts();
      
    }
    
    uint32_t cnt = 0;
    void loop() {
      cnt++;
        allPinTest( cnt );
    }
    
    uint32_t pinLast[NUM_DIGITAL_PINS];
    void allPinTest( uint32_t cnt ) {
      uint32_t ii, SET;
      Serial.print("PULLDOWN Start Vals:\n  ");
      SET = 0;
      Serial.print("PULLDOWN :: TEST to 3.3V\n  ");
      for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
        pinMode( ii, INPUT_PULLDOWN );
        delayMicroseconds( 5 );
        pinLast[ii] = digitalReadFast( ii );
        if (pinLast[ii]) {
          Serial.print("\nd#=");
          Serial.print( ii );
          Serial.print( " val=" );
        }
        Serial.print( pinLast[ii] );
        Serial.print(',');
      }
      Serial.println();
      Serial.println();
      while ( 1 ) {
        uint32_t jj, dd = 0, cc = 0, ee=4;
        cc = 0;
        for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
          jj = digitalReadFast( ii );
          if ( jj != pinLast[ii] ) {
            dd = 1;
            cc++;
            pinLast[ii] = jj;
            Serial.print("d#=");
            Serial.print( ii );
            if ( pinLast[ii] ) Serial.print( "\t" );
            Serial.print( " val=" );
            Serial.print( pinLast[ii] );
            Serial.print(',');
          }
          if ( cc > 1 && ee ) {
            Serial.println(">>> MULTI CHANGE !!");
            ee--;
          }
          if ( Serial.available() ) {
            while ( Serial.available() ) Serial.read();
            if ( 0 == SET ) {
              SET = 1;
              Serial.print("PULLUP :: TEST TO GND\n  ");
            }
            else {
              SET = 0;
              Serial.print("PULLDOWN :: TEST to 3.3V\n  ");
            }
            for ( ii = 0; ii < NUM_DIGITAL_PINS; ii++) {
              if ( 0 == SET )
                pinMode( ii, INPUT_PULLDOWN );
              else
                pinMode( ii, INPUT_PULLUP );
              delayMicroseconds( 20 );
              pinLast[ii] = digitalReadFast( ii );
              if (SET != pinLast[ii]) {
                Serial.print("d#=");
                Serial.print( ii );
                Serial.print( " val=" );
                Serial.println( pinLast[ii] );
              }
            }
          }
        }
        if ( dd ) {
          dd = 0;
          Serial.println();
          delay( 50 );
        }
      }
    }
    
    void testForShorts() {
      uint32_t ii;
      Serial.print("Quick Test for Shorts to adjacent pin");
      Serial.println("First pull pins down and see if the next one follows");
      for ( ii = 0; ii < NUM_DIGITAL_PINS-1; ii++) {
        pinMode( ii+1, INPUT_PULLDOWN );
        pinMode( ii, OUTPUT);
        digitalWrite(ii, HIGH);
        delayMicroseconds( 5 );
        if (digitalRead(ii+1)) {
          Serial.printf("%d:%d ", ii, ii+1);
        }
      }
      Serial.println("\n Now try Pull up and see if setting low follow");
      for ( ii = 0; ii < NUM_DIGITAL_PINS-1; ii++) {
        pinMode( ii+1, INPUT_PULLUP );
        pinMode( ii, OUTPUT);
        digitalWrite(ii, LOW);
        delayMicroseconds( 5 );
        if (!digitalRead(ii+1)) {
          Serial.printf("%d:%d ", ii, ii+1);
        }
      }
      Serial.println();  
    }
    Which initializes all of the IO pins to either INPUT_PULLUP or INPUT_PULLDOWN (You can change between the two by hitting enter in Serial Monitor. It then loops through all of the IO pins seeing which ones change state.
    Now assuming simple connections, like one button to one pin, you should be able to figure which. Using something like this

    If it is more complex, like using some additional hardware or something like a button matrix, or resister ladder. you will probably have to try to trace through the stuff to see what connects to what.

    But hard to say more without additional information.

  6. #6
    Thank you.

    The Teensy is part of a Thrustmaster/Sparco Steerring wheel button box.
    I bought a 'All in One' conversion kit that changes Thrustmaster 6-din output to USB, complete with approriate firmware/sketch
    I've had some USB bus issues, and thought this wheel might be a part of the problem, so things led to other things...

    There are a number of resistors and chips in place on the Steering Wheel's board.
    But if I'm only trying to read what the Teensy is seeing, does that matter?

    There are a couple of guides/sketches online for a pro-micro. Also think they're using older version of the wheel, judging by the pin-out/wiring guides.

    My Teensy is wired like this:
    Click image for larger version. 

Name:	Teensy.png 
Views:	26 
Size:	78.7 KB 
ID:	30150
    Last edited by RobinNoGood; 01-16-2023 at 06:45 AM.

  7. #7
    Quote Originally Posted by RobinNoGood View Post
    I got this:


    const int numButtons = 16;

    void setup() {
    Serial.begin(38400);
    for (int i=0; i<numButtons; i++)
    pinMode(i, INPUT);
    }

    void loop()
    {
    for (int i=0; i<numButtons; i++)
    if (digitalRead(i) == HIGH) {
    Serial.println("Button is not pressed...");
    } else {
    Serial.println("Button pressed!!!");
    }
    delay(2500);
    }

    Which prints as often as you want. But I only wnat it to print when there's a change, and which button/pins have changed. I take it some buttons are 'High' when unpressed? This doesn't acccount for those.
    FWIW:

    When this is uploaded, without pressing any of the buttons, the Serial Monitor prints:

    Button is not pressed (x15)
    Button is pressed (x1)
    Click image for larger version. 

Name:	Screenshot (1035).png 
Views:	9 
Size:	4.3 KB 
ID:	30151
    Last edited by RobinNoGood; 01-16-2023 at 06:14 AM.

  8. #8
    Changing:

    if (digitalRead(i) == HIGH)

    to,

    if (digitalRead(i) == INPUT)

    reverses the Serial Monitor output.

    Click image for larger version. 

Name:	Screenshot (1036).png 
Views:	8 
Size:	5.7 KB 
ID:	30153

    When I do press buttons, nothing changes, same messages in Serial Monitor.

    What I'd like to see is something like

    Current State=
    Button1, Low
    Button2, High
    Button3, None
    etc...

    just printed once, then to only print again when there's a change.
    Last edited by RobinNoGood; 01-16-2023 at 07:32 AM.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,874
    Not seeing noted how the buttons are wired?

    Are they pulled up externally to 3.3V? In this case per p#5 the pinMode should be INPUT_PULLDOWN : pinMode(i, INPUT_PULLDOWN );

    Or if the buttons are wired to GND then using: pinMode(i, INPUT_PULLUP );

    This would hold the pin to a known state of GND or 3.3V until the button is pressed, and pressing the button would change the state only while the button was pressed.

    With pinMode(i, INPUT); the pin will not be obligated/driven to switch to a known state before or after a button is pressed.

  10. #10
    I dont know how any of this works in detail .

    I didn't want to add any more resistance to the buttons, as the buttons are on a pre-populated board running thrrugh x number of Resistors of unknown values.
    I just wanted to see what was being read by the Teensy when a button was and wasn't being pressed.
    I was expecting the rest state of various buttons to differ, some High, some Low, some 0.

    Here's the board:

    Click image for larger version. 

Name:	Buttons.jpg 
Views:	16 
Size:	71.9 KB 
ID:	30154

    I'll add the PULLUP/PULLDOWN to the sketch and see what happens.

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,874
    That is pretty well HIDDEN

    If you can get a meter across the button from GND testing for continuity it probably just closes a switch.

    Test for Ohms and it may show there is a resistor inline with the button when pressed. Test for voltage across the button and it would show 0V in both cases and then pinMode(i, INPUT_PULLUP ); should be the answer, and the button will go LOW when pressed and stay HIGH otherwise.

  12. #12
    With:

    Code:
    const int numButtons = 16;
    
    void setup() {
    Serial.begin(38400);
    for (int i=0; i<numButtons; i++)
    pinMode(i, INPUT_PULLDOWN);
    }
    
    void loop()
    {
    for (int i=0; i<numButtons; i++)
    if (digitalRead(i) == INPUT) {
    Serial.println("Button is not pressed");
    } else {
    Serial.println("Button pressed");
    }
    delay(2500);
    }
    Serial Monitor reports:
    Code:
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    Button pressed
    Button is not pressed
    Button is not pressed
    Button is not pressed
    With PULLUP, I get:

    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed
    Button pressed

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,874
    Does one of those present the expected readings of the buttons? Perhaps the first where one is noted as pressed?

    This line is not clear: if (digitalRead(i) == INPUT) {

    For working PULLUP it should read: if (digitalRead(i) == LOW) {

    For working PULLDOWN it should read: if (digitalRead(i) == HIGH) {

    Is there a DVM/DMM meter there that allows testing the button properties to the pin (and GND) as noted in p#11?

    Is there a picture of how the pins get connected to the board image shown in p#10? Is there a common GND to the board with the buttons?

  14. #14
    Is there a DVM/DMM meter there that allows testing the button properties to the pin (and GND) as noted in p#11?

    I think this is what I wanted to use Teensy for.

    At least before I start trying to map functional outputs to them.

    But, no. All buttons are currently unpressed so neither of the above variants report correctly.
    I want to read whatever the buttons are sending right now, and relay that to the monitor. Ideally in a "buttonNumber, buttonState [i.e Low, High etc]" format.

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,874
    Try this - maybe as is - it was not compiled:
    Code:
    const int numButtons = 16;
    bool bLast[numButtons];
    
    void setup() {
    	Serial.begin(38400);
    	for (int i = 0; i < numButtons; i++)
    		pinMode(i, INPUT_PULLUP);  // IF CHANGED TO PULLDOWN, TEST for LOW below NOT HIGH
    	for (int i = 0; i < numButtons; i++)
    		bLast[i] = digitalRead(i);
    }
    
    void loop()
    {
    	bool bRead;
    	for (int i = 0; i < numButtons; i++) {
    		bRead = digitalRead(i);
    		if (bRead != bLast[i]) {
    			if ( digitalRead(i) == HIGH ) {
    				Serial.println("Button is not pressed");
    			} else {
    				Serial.println("Button pressed");
    			}
    			bLast[i] = bRead;
    		}
    	}
    	delay(100);
    }

  16. #16
    Thank you. It compiles, but gives no output.

    I modified mine above a little bit
    Code:
    const int numButtons = 16;
    
    void setup() {
    Serial.begin(38400);
    for (int i=0; i<numButtons; i++)
    pinMode(i, INPUT);
    }
    
    void loop()
    {
    for (int i=0; i<numButtons; i++)
    if (digitalRead(i) == HIGH) {
    Serial.println("Button is High");
      }else{
        if (digitalRead(i) == LOW) {
        Serial.println("Button is Low");
        }
    delay(2500);
      }}
    This gives the current HIGH/LOW state of each button.

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    16,874
    Quote Originally Posted by RobinNoGood View Post
    Thank you. It compiles, but gives no output.

    I modified mine above a little bit
    ...
    This gives the current HIGH/LOW state of each button.
    That p#15 code should only print anything on button change.

    Though the delay(100) could be better handled and only delay when there was a change detected. As written any button held over 100+ milliseconds should be detected?

    Not sure what is being tested there ... the pinmode is still just INPUT. Maybe he switches are internally driven HIGH and LOW on press or release? Change to pinMode should allow seeing how the switches behave.

    It could print the state as stored in bLast in setup() - but that seemed like extra work.

    This code will scan continuously and only print when a button is changed (press or release) - and it will delay 100 ms then to avoid button bounce doing print spasms.
    Code:
    const int numButtons = 16;
    bool bLast[numButtons];
    
    void setup() {
    	Serial.begin(38400);
    	for (int i = 0; i < numButtons; i++)
    		pinMode(i, INPUT_PULLUP);  // IF CHANGED TO PULLDOWN, TEST for LOW below NOT HIGH
    	for (int i = 0; i < numButtons; i++)
    		bLast[i] = digitalRead(i);
    }
    
    void loop()
    {
    	bool bRead;
    	bool bChange = false;
    	for (int i = 0; i < numButtons; i++) {
    		bRead = digitalRead(i);
    		if (bRead != bLast[i]) {
                            bChange = true;
    			if ( digitalRead(i) == HIGH ) {
    				Serial.println("Button is not pressed");
    			} else {
    				Serial.println("Button pressed");
    			}
    			bLast[i] = bRead;
    		}
    	}
    	if (bChange) delay(100);
    }

  18. #18
    Again, no change is being registered with that.

    Maybe my buttons are fried?
    I just did this:

    Code:
    const int numButtons = 16;
    int lastButtonState;
    
    void setup() {
      Serial.begin(9600);
      for (int i=0; i<numButtons; i++)
      lastButtonState = digitalRead(INPUT);
    }
    
    void loop() {
      // read the value of the button
      int buttonState = digitalRead(INPUT);
    
      if (lastButtonState != buttonState) // state changed
        delay(50); // debounce time
    
        if (buttonState != lastButtonState)
          Serial.println("Go");
          else
          Serial.println("Waiting");
          delay(1000);
         }
    Serial Monitor shows the state as Waiting. Nothing changes on a button press.

    How do I enumerate each button?
    "Button 1, waiting"
    etc...

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,432
    Note: my original post, was with only the information that you were using a "TeensyLC button box" And the example program was to see if potentially the buttons were
    connected simply, with a one button to a pin connection... And I mentioned, this is only one of the possible ways that they may be connected up. Again, as I mentioned, throwing darts.

    With your subsequent post of being a Thrustmaster... Then maybe your best bet is to do some only queries to see if more information is available for your specific setup.
    Something like: google thrustmaster to usb using teensy lc
    And look through the different hits. You may try to refine the search to your specific model of Thrustmaster. For example, one of the hits I saw from a YouTube video found by the
    above search showed: https://pit.uriba.org/uriba/standalo...ar-tqs-part-i/

    And in that case, the buttons were arranged in a matrix. So that would be very different!

    But more interesting is your diagram showing what is connected up to the Teensy LC.

    Quote Originally Posted by RobinNoGood View Post
    Thank you.


    The Teensy is part of a Thrustmaster/Sparco Steerring wheel button box.
    I bought a 'All in One' conversion kit that changes Thrustmaster 6-din output to USB, complete with approriate firmware/sketch
    I've had some USB bus issues, and thought this wheel might be a part of the problem, so things led to other things...

    There are a number of resistors and chips in place on the Steering Wheel's board.
    But if I'm only trying to read what the Teensy is seeing, does that matter?

    There are a couple of guides/sketches online for a pro-micro. Also think they're using older version of the wheel, judging by the pin-out/wiring guides.
    My Teensy is wired like this:
    Click image for larger version. 

Name:	Teensy.png 
Views:	26 
Size:	78.7 KB 
ID:	30150
    So no, understanding how the buttons and/or pots are connected, may not help much.

    The pins you show that are hooked up include:
    a) USB connection, probably goes to another USB connector...
    b) Power: +5v and 2 GND pins
    c) Program pin
    d) Pins 10, 12, 13. So probably SPI. Not sure if master or slave. But as pin 11 (MOSI) not hooked up, I might guess slave.

    I have not done much with the Slave code, but you might try looking at some of the libraries out there for this, like:
    https://github.com/tonton81/TSPISlave

    And guessing maybe the device sends out packets of data over SPI about the current state or changes... Hopefully you can find a site that someone has documented their protocol.

    Good luck
    Kurt

  20. #20
    Thaks Kurt.

    The pro-micro sketches I mentioned are from a 'Thrustmaster Conversion' search.
    Further along in that I also got a SPI sketch that prints 3 bytes of data.

    Code:
    Free free to modify and use for your needs.
    This sketch and the documentation above provided "AS IS" under the BSD New license.
    http://opensource.org/licenses/BSD-3-Clause
    (c) Taras Ivaniukovich (blog@rr-m.org) April 2015
    
    #include <SPI.h>
    
    const int slaveSelectPin = 7;
    
    void setup() {
      Serial.begin(9600);
      SPCR |= _BV(CPHA);
      SPCR |= _BV(CPOL);
      SPI.begin();
      pinMode(slaveSelectPin, OUTPUT);
    }
    
    void loop() {
      // tell the wheel, that we gonna read the data now (capture shift registers state to start reading)
      digitalWrite(slaveSelectPin, LOW);
      
      // read 3 bytes and output them to Arduino Serial monitor as binaries 11000001 11111111 11111111
      // For TXRW 458 Italia wheel last 17 bits are buttons. 1 - released, 0 - pressed.
      for(int i=1; i<=3; i++) {
        printBinary(SPI.transfer(0x00));
      }
      Serial.println();
      
      // release the wheel
      digitalWrite(slaveSelectPin, HIGH);
     
     // wait 1 second, then read data from wheel again
      delay(1000);
    }
    
    // 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(" ");
    }
    which prints:

    11111111 11111111 11111111

    But, that is "slaveSelectPin 7", which isn't connected on my board, so probably not a correct output.
    Would I modify this to 'program pin' for mine?
    Last edited by RobinNoGood; 01-16-2023 at 03:04 PM.

  21. #21
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,432
    Yes change the 7 to 10 and see what it gives you.

  22. #22
    Insert Homer Drooling

    mmmm functions!
    Click image for larger version. 

Name:	Screenshot (1038).png 
Views:	18 
Size:	36.2 KB 
ID:	30156

    OK, cooking on gas.

    Pin 10, provides functional repsonses.

    12 & 13 just read 0's or 1;'s with no change on button press.

    All the buttons are single momentary switches, but there is also a 5 way hat-like switch which doesn't register a 'push'. Up, Down, Left and Right all show bit changes.

    I take it this means the Push is the alternate reading I was getting from #8 and #12? Or are they compeltely seperate things?

    Now to tun this into something useful.

  23. #23
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,432
    Now wondering about:
    Code:
      Serial.begin(9600);
      SPCR |= _BV(CPHA);
      SPCR |= _BV(CPOL);
      SPI.begin();
    We have some stuff in place to try to emulate the AVR register SPCR, but not to say it works overly well.

    CPHA - Clock Phase.
    CPOL - Clock Polarity

    And I don't think we ever implemented it in the T4 port.

    Wondering what would happen if you changed this code to:

    Code:
      SPI.begin(); // start up SPI
      SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE3));
    (AND REMOVE THOSE TWO LINES IN RED)
    And see if it gives you anything different.
    Note: this sets up for 4mhz transfer which I think is sort of default on AVR, MSBFIRST (maybe LSBFIRST)
    MODE3 is with those two bits on I think...

  24. #24
    That works as well.

    I've no idea what AVR, MSBFirst/LSBFirst are though ¯\_(ツ)_/¯

    If the CPHA/CPOL arent necessary then good riddance.

    I'm just working through one of those pro-micro sketches to see what I can modify/bring in here.
    Might also need to do some soldering, the poor board has taken a pounding.

  25. #25
    Here's the Pro-Micro sketch I'm working through.

    Having changed the 'slaveSelectPin', and deleted '#include <Joystick.h>'
    there's only a 'setButton' that comes back as an error.

    Code:
    /*
     * sketch heavily based on code provided at:
     * April 2015 © blog@rr-m.org 
    */
    
    /*
    Also see comments from Ignacio Hernandez-Ros & mispeaced under https://www.youtube.com/watch?v=CJjLUAgAFnQ
    * On Arduino Pro Micro side it must be connected as follows:
     * 
     * Green -> not used (or can be connected to arduino MOSI pin 16)
     * Blue - GND -> arduino uno GND pin
     * White - MISO -> arduino uno pin 14
     * Orange – SS -> arduino uno pin 7
     * Red – SCK -> arduino uno pin 15
     * Black +VCC -> arduino +5V pin (or RAW if USB current is +5V already)
     * 
    * 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 = Hat-Push?
     * 3 - Button 7
     * 2 - Button 13
     * 1 - Button 8
     * 0 - 1 = Hat-Push?       
     * 
     * Byte 3
     * 7 - Button 3
     * 6 - Button 10
     * 5 - Hat-Left
     * 4 - Hat-Up
     * 3 - Hat-Right
     * 2 - Hat-Down
     * 1 - Button 4
     * 0 - Button 1
    */
    
    #include <SPI.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};              //numbers the buttons from top left to bottom right (main is D,U,press)
    
    void setup() {
      //input from wheel
      Serial.begin(9600);
      SPI.beginTransaction(SPISettings(1000, 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);
      
      //read the next 4 bytes (get 2's compliment)
      for(int i=0; i<4; i++) 
        currBytes[i] = ~SPI.transfer(0x00);
      
      //deal with the buttons first
      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.setButton(bit2btn[(i*8)+b], btnState);      //if the bit has changed send the update     
      
      joyBtnState = (currBytes[3] & pos[0]) && !(currBytes[2] & 0x3c);  
      
      if(joyBtnState != prevJoyBtnState)
        Joystick.setButton(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);
    }
    This is the error returned:

    Code:
    sparco: In function 'void loop()':
    sparco:81: error: 'class usb_joystick_class' has no member named 'setButton'
             Joystick.setButton(bit2btn[(i*8)+b], btnState);      //if the bit has changed send the update     
                      ^
    sparco:86: error: 'class usb_joystick_class' has no member named 'setButton'
         Joystick.setButton(13, joyBtnState);
                  ^
    'class usb_joystick_class' has no member named 'setButton'
    Last edited by RobinNoGood; 01-16-2023 at 06:17 PM.

Posting Permissions

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