Analog joystick values

Hello, and good afternoon. I'm about to wrap up the conversion of all my game pads and flightsticks to Bluetooth after solving many of my own issues I am on one last problem.

My problem is the joystick readings for them all. everything is wired and hooked up correctly as in Arduino IDE I can watch the values go up and down from 0 to 941 for both X and Y in the serial monitor but when I go over to Windows test panel and move the joystick in the up position slowly the number value goes all the way up to 127 then atad further is -127 bringing the joystick marker to the bottom of the test plane and if I continue to move the joystick up it goes all the way up from -127 and past 0 then 127 again. It does this in every single direction and all my sensors (hall effect/analog sticks)

Few things to know My old projects used Promicros (ATmega32U4)
For Bluetooth and ease of installing. I got boards that are the same size with the same pin out but use the nRF52840 ProMicro nrf52840's.

Video Of Issue here

CODE

#include <Adafruit_TinyUSB.h>

/*********************************************************************
     Single Handed Gamepad, 15 Buttons, 1 Joystick
 ********************************************************************/


#include <bluefruit.h>



BLEDis bledis;
BLEHidGamepad blegamepad;

// define each function and its input pin number comments describe physical switches
#define X_PIN A2    //JOY x
#define Y_PIN A1    //JOY y

int8_t x = X_PIN;
int8_t y = Y_PIN;

hid_gamepad_report_t gp;

void setup()
{

// LOW POWER MODE!
  // Pins default to INPUT mode. To save power, turn them all to OUTPUT
  // initially, so only those being used will be turn on. See:
  // http://www.pjrc.com/teensy/low_power.html

  Serial.begin(115200);



#if CFG_DEBUG
  // Blocking wait for connection when debug mode is enabled via IDE
  while ( !Serial ) delay(10);
#endif

  Serial.println("ChazronBLE");
  Serial.println("------------------------------------\n");
  Serial.println("FileName: Chazron.ino");
  Serial.println();
  Serial.println("Go to your devices's Bluetooth settings to pair your device");
  Serial.println("then open an application that accepts gamepad input");

  Bluefruit.begin();
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
  Bluefruit.setName("Chazron");
  // Configure and Start Device Information Service
  bledis.setManufacturer("InMyRoom Productions");
  bledis.setModel("Chucke Ergo - nRF52840");
  bledis.begin();

  /* Start BLE HID
   * Note: Apple requires BLE device must have min connection interval >= 20m
   * ( The smaller the connection interval the faster we could send data).
   * However for HID and MIDI device, Apple could accept min connection interval 
   * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
   * connection interval to 11.25  ms and 15 ms respectively for best performance.
   */
  blegamepad.begin();

  /* Set connection interval (min, max) to your perferred value.
   * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
   * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
   */
  /* Bluefruit.Periph.setConnInterval(9, 12); */

  // Set up and start advertising
  startAdv();

}

void startAdv(void)
{
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_GAMEPAD);

  // Include BLE HID service
  Bluefruit.Advertising.addService(blegamepad);

  // There is enough room for the dev name in the advertising packet
  Bluefruit.Advertising.addName();

  /* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   *
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html
   */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds
}

void loop()
{
  // nothing to do if not connected or
  if ( !Bluefruit.connected() ) return;

    int val = analogRead(A2); 
    int val2 = analogRead(A1);
  
    
 
    gp.x = analogRead(x);
    gp.y = analogRead(y); 


 
    Serial.print("X: ");
    Serial.println(val);
    Serial.print("Y: ");
    Serial.println(val2);
    //delay(500);
       blegamepad.report(&gp);
}


I think the problem is in data type of gp.x and gp.y

2 Likes

The range of possible values for int8_t variables is -128 to 127.

Use int16_t (two bytes) for values in the range -32768 to 32767.

2 Likes

I had thought that originally but yields the same results.

I did some reading about mapping the values.

map(value, fromLow, fromHigh, toLow, toHigh)

Using the serial monitor to get actual values and using those values to get the values that I actually want but when I input it in my code the joystick no longer reads anything at all. I will include code with map added maybe im just putting it in wrong.


#include <Adafruit_TinyUSB.h>

/*********************************************************************
    Single Handed Gamepad, 15 Buttons, 1 Joystick
********************************************************************/


#include <bluefruit.h>



BLEDis bledis;
BLEHidGamepad blegamepad;

// define each function and its input pin number comments describe physical switches
#define X_PIN A2    //JOY Y
#define Y_PIN A1      //JOY X

int16_t x = X_PIN;
int16_t y = Y_PIN;

hid_gamepad_report_t gp;

void setup()
{

// LOW POWER MODE!
 // Pins default to INPUT mode. To save power, turn them all to OUTPUT
 // initially, so only those being used will be turn on. See:
 // http://www.pjrc.com/teensy/low_power.html

 Serial.begin(115200);



#if CFG_DEBUG
 // Blocking wait for connection when debug mode is enabled via IDE
 while ( !Serial ) delay(10);
#endif

 Serial.println("ChazronBLE");
 Serial.println("------------------------------------\n");
 Serial.println("FileName: Chazron.ino");
 Serial.println();
 Serial.println("Go to your devices's Bluetooth settings to pair your device");
 Serial.println("then open an application that accepts gamepad input");

 Bluefruit.begin();
 Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
 Bluefruit.setName("Chazron");
 // Configure and Start Device Information Service
 bledis.setManufacturer("InMyRoom Productions");
 bledis.setModel("Chucke Ergo - nRF52840");
 bledis.begin();

 /* Start BLE HID
  * Note: Apple requires BLE device must have min connection interval >= 20m
  * ( The smaller the connection interval the faster we could send data).
  * However for HID and MIDI device, Apple could accept min connection interval 
  * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
  * connection interval to 11.25  ms and 15 ms respectively for best performance.
  */
 blegamepad.begin();

 /* Set connection interval (min, max) to your perferred value.
  * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
  * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
  */
 /* Bluefruit.Periph.setConnInterval(9, 12); */

 // Set up and start advertising
 startAdv();

}

void startAdv(void)
{
 // Advertising packet
 Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
 Bluefruit.Advertising.addTxPower();
 Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_GAMEPAD);

 // Include BLE HID service
 Bluefruit.Advertising.addService(blegamepad);

 // There is enough room for the dev name in the advertising packet
 Bluefruit.Advertising.addName();

 /* Start Advertising
  * - Enable auto advertising if disconnected
  * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
  * - Timeout for fast mode is 30 seconds
  * - Start(timeout) with timeout = 0 will advertise forever (until connected)
  *
  * For recommended advertising interval
  * https://developer.apple.com/library/content/qa/qa1931/_index.html
  */
 Bluefruit.Advertising.restartOnDisconnect(true);
 Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
 Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
 Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds
}

void loop()
{
 // nothing to do if not connected or
 if ( !Bluefruit.connected() ) return;

   int val = analogRead(A2); 
   int val2 = analogRead(A1);
   x = map(X_PIN, 0, 1024, -32768, 32768);
   y = map(Y_PIN, 0, 1024, -32768, 32768);
   


   gp.x = analogRead(x);
   gp.y = analogRead(y); 



   Serial.print("X: ");
   Serial.println(val);
   Serial.print("Y: ");
   Serial.println(val2);
   //delay(500);
      blegamepad.report(&gp);
     
}    


I'm seeing that. Been a real headache. I'm a fool and didn't realize how different these boards really are. They may have the same size and pin out but the chips differ and I have only dealt with promicros with ATmega32u4 so this is different or I'm just so lost I don't know what I'm doing anymore.

I have 11 different 3d printed gamepads/flightsticks many are yearsss old and I've gone through many wires and boards due to wear and tear, damage, neglect, cats...... Wireless is needed haha.

figured it out using

  analogReadResolution(6);

in beginning of loop

     analogReadResolution(6);
     gp.x = analogRead(X_PIN);
     gp.y = analogRead(Y_PIN); 

for some reason no other bitrate works with this board without extreme overshooting.

thank you all for your help.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.