Bluetooth HID gamepad with Arduino leonardo an RN 42 HID module

Hi,

I’m a newbie in Arduino IDE and i would like to make a bluetooth gamepad :smiley: lucky me i found a

library (BPlib) that was very helpfull. But i’m facing some problems the principal

is that all the button codes (button’s combination) in my sketch act like D-PAD.And none of them

simulate the 4 right buttons, button start or the triggers. Any idea on how to resolve this? Also i

wanna know if it was possible with this library to create a gamepad with 2 joystick which act like the

ones on mainstream controllers of a ps3 or xbox 360.

Here is my sketch:

#include <BPLib.h>

const int buttonPin1 = 2;    // the number of the pushbutton pin
const int buttonPin2 = 3; 
const int buttonPin3 = 4; 
const int buttonPin4 = 5; 
BPLib BPMod;
void setup(){
  pinMode(buttonPin1, INPUT);
  digitalWrite(buttonPin1, HIGH);
  pinMode(buttonPin2, INPUT);
 digitalWrite(buttonPin2, HIGH);
  pinMode(buttonPin3, INPUT);
  digitalWrite(buttonPin3, HIGH);
  pinMode(buttonPin4, INPUT);
  digitalWrite(buttonPin4, HIGH);
  
  BPMod.begin(BP_MODE_HID,BP_HID_GAMEPAD);
  delay(1000);
}
void loop(){
    // Check for button press
  int button1 = digitalRead(buttonPin1);
  int button2 = digitalRead(buttonPin2);
  int button3 = digitalRead(buttonPin3);
  int button4 = digitalRead(buttonPin4);
  
    // Check Button Press on Joystick
 
  if (button1 == LOW){
    BPMod.gameJoyPress(BP_GAMEJOY_ND_NOBTN,BP_GAMEJOY_ND_BTN6);

    // slight delay to avoid flooding RN42.
    delay(50);

    // "lift" the key
   BPMod.gameJoyReleaseAll();
      } 
  
 if (button2 == LOW){
   BPMod.gameJoyPress(BP_GAMEJOY_ND_NOBTN,BP_GAMEJOY_ND_BTN7);

    // slight delay to avoid flooding RN42. 
    delay(50);

   
  BPMod.gameJoyReleaseAll();
     } 
   if (button3 == LOW){
   BPMod.gameJoyPress(BP_GAMEJOY_ST_BTN6,BP_GAMEJOY_ST_NOBTN);

    // slight delay to avoid flooding RN42. 
    delay(50);

    // "lift" the key
    BPMod.gameJoyReleaseAll();
      } 
 if (button4 == LOW){
    BPMod.gameJoyPress(BP_GAMEJOY_ST_BTN7,BP_GAMEJOY_ST_NOBTN);

    // slight delay to avoid flooding RN42. 
    delay(50);

    // "lift" the key
    BPMod.gameJoyReleaseAll();
    } 
 }

And the library

/*
  BPLib.cpp - Library for communication with RN-42 HID Bluetooth module
  Created by Basel Al-Rudainy, 6 april 2013.
  
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
*/
#include "Arduino.h"
#include "BPLib.h"

BPLib::BPLib(){
pinMode(7,INPUT);
digitalWrite(7,LOW);
}

byte BPLib::begin(char BP_Mode[], char BP_Type[])
{
Serial1.begin(115200);
Serial1.print(BP_MODE_COMMAND);
  if (get(BP_STAT_CMD, (byte)5)!=1) {
    return (byte)0;
  }//if
  
  Serial1.print(BP_Mode);
  if (get(BP_STAT_ACK, (byte)5)!=1) {
    return (byte)0;
  }//if
  if(strcmp(BP_Type,BP_SPP_SPP)>0){
  Serial1.print(BP_Type);
  if (get(BP_STAT_ACK, (byte)5)!=1) {
    return (byte)0;
  }//if
  }
  Serial1.print(BP_REBOOT);
  if (get(BP_STAT_REBOOT, (byte)9)!=1) {
    return (byte)0;
  }//if
  delay(1000); //Delay (Bluetooth boot-up)

return (byte)1;
}

byte BPLib::sendCmd(char BP_CMD[])
{
  Serial1.print(BP_MODE_COMMAND);
  if (get(BP_STAT_CMD, (byte)5)!=1) {
    return (byte)0;
  }//if
  Serial1.print(BP_CMD);
  if (get(BP_STAT_ACK, (byte)5)!=1) {
    return (byte)0;
  }//if
  Serial1.print(BP_MODE_EXITCOMMAND);
  if (get(BP_STAT_END, (byte)5)!=1) {
    return (byte)0;
  }//if
  return (byte)1;
}

byte BPLib::readRaw(){
return Serial1.read();
}
int BPLib::available(){
return Serial1.available();
}

byte BPLib::get(char BP_STAT[],byte strlen)
{
char buffer[strlen + 1];
  while (Serial1.available() <= (strlen-1)) {};
    int count = 0;
    while (Serial1.available() > 0) {
      buffer[count]=(char)Serial1.read();
      count++;
    }//while
  buffer[strlen]=0;
    //Serial.print(buffer);//DEBUG
    if (strcmp(buffer,BP_STAT)==0) {
      return (byte)1;
    }//if
    else {
      return (byte)0;
    }//else
}//get


}









byte BPLib::changeName(char BP_NAME[]){
 Serial1.print(BP_MODE_COMMAND);
  if (get(BP_STAT_CMD, (byte)5)!=1) {
    return (byte)0;
  }//if
  Serial1.print(BP_CHANGE_NAME);
  Serial1.print(BP_NAME);
  Serial1.print(F("\r\n"));
  if (get(BP_STAT_ACK, (byte)5)!=1) {
    return (byte)0;
  }//if
  Serial1.print(BP_MODE_EXITCOMMAND);
  if (get(BP_STAT_END, (byte)5)!=1) {
    return (byte)0;
  }//if
  return (byte)1;

}


void BPLib::sendByte(byte rawData){
Serial1.print(rawData);
}
void BPLib::sendChar(char rawData){
Serial1.print(rawData);
}
void BPLib::sendInt(int rawData){
Serial1.print(rawData);
}
void BPLib::sendFloat(float rawData){
Serial1.print(rawData);
}
void BPLib::sendLong(long rawData){
Serial1.print(rawData);
}
void BPLib::sendString(char rawData[]){
Serial1.print(rawData);
}

void BPLib::gameJoyPress(byte BP_ST_BTN, byte BP_ND_BTN){
Serial1.write((byte)0xFD); //Start HID Report
Serial1.write((byte)0x6); //Length byte
Serial1.write((byte)BP_ST_BTN); //First Button byte
Serial1.write((byte)BP_ND_BTN); //Second Button byte
for(byte i = 0;i<4;i++){ //Send four zero bytes
Serial1.write((byte)0x00);
}
}
void BPLib::gameJoyMove(signed int BP_X1,signed int BP_Y1,signed int BP_X2,signed int BP_Y2){
Serial1.write((byte)0xFD); //Start HID Report
Serial1.write((byte)0x6); //Length byte
Serial1.write((byte)BP_GAMEJOY_ST_NOBTN); //First Button byte
Serial1.write((byte)BP_GAMEJOY_ND_NOBTN); //Second Button byte
Serial1.write(BP_X1 & 0xFF); //First X coordinate
Serial1.write(BP_Y1 & 0xFF); //First Y coordinate
Serial1.write(BP_X2 & 0xFF); //Second X coordinate
Serial1.write(BP_Y2 & 0xFF); //Second Y coordinate
}
void BPLib::gameJoyReleaseAll(){
gameJoyPress(BP_GAMEJOY_ST_NOBTN, BP_GAMEJOY_ND_NOBTN);
}

byte BPLib::connected(){
return digitalRead(7);
}
/*
#ifndef BPLib_h
#define BPLib_h

#include "Arduino.h"

//Bluetooth Modes
#define BP_MODE_COMMAND     "$$"
#define BP_MODE_EXITCOMMAND   "---\r\n"
#define BP_MODE_SPP   "S~,0\r\n"
#define BP_MODE_HID   "S~,6\r\n"
#define BP_MODE_AUTOCONNECT   "SM,6\r\n"
#define BP_MODE_MANUCONNECT   "SM,4\r\n"
#define BP_MODE_STATUS "SO,/#\r\n"

//Bluetooth status messages
#define BP_STAT_CMD   "CMD\r\n"
#define BP_STAT_END   "END\r\n"
#define BP_STAT_ACK   "AOK\r\n"
#define BP_STAT_REBOOT   "Reboot!\r\n"
//Bluetooth GET commands
#define BP_GET_HID   "GH\n"

//Bluetooth system commands
#define BP_REBOOT   "R,1\r\n"
#define BP_RECONNECT   "C\r\n"
#define BP_CHANGE_NAME "SN,"
//Bluetooth protocol types
#define BP_SPP_SPP "AW\r\n"
#define BP_HID_KEYBOARD   "SH,0200\r\n"
#define BP_HID_MOUSE   "SH,0220\r\n"
#define BP_HID_GAMEPAD   "SH,0210\r\n"
#define BP_HID_JOYSTICK   "SH,0240\r\n"
#define BP_HID_COMBO   "SH,0230\r\n"


//GAMEPAD/JOYSTICK BUTTON CODES
//ST == First button combination (BTN0 to BTN7)
#define BP_GAMEJOY_ST_BTN0 (1<<0)
#define BP_GAMEJOY_ST_BTN1 (1<<1)
#define BP_GAMEJOY_ST_BTN2 (1<<2)
#define BP_GAMEJOY_ST_BTN3 (1<<3)
#define BP_GAMEJOY_ST_BTN4 (1<<4)
#define BP_GAMEJOY_ST_BTN5 (1<<5)
#define BP_GAMEJOY_ST_BTN6 (1<<6)
#define BP_GAMEJOY_ST_BTN7 (1<<7)
#define BP_GAMEJOY_ST_NOBTN 0x00

//ND = Second button combination (BTN0 to BTN7)
#define BP_GAMEJOY_ND_BTN0 (1<<0)
#define BP_GAMEJOY_ND_BTN1 (1<<1)
#define BP_GAMEJOY_ND_BTN2 (1<<2)
#define BP_GAMEJOY_ND_BTN3 (1<<3)
#define BP_GAMEJOY_ND_BTN4 (1<<4)
#define BP_GAMEJOY_ND_BTN5 (1<<5)
#define BP_GAMEJOY_ND_BTN6 (1<<6)
#define BP_GAMEJOY_ND_BTN7 (1<<7)
#define BP_GAMEJOY_ND_NOBTN 0x00

class BPLib
{
public:
BPLib();
byte begin(char BP_Mode[], char BP_Type[]);
byte sendCmd(char BP_CMD[]);
void sendByte(byte rawData);
void sendChar(char rawData);
void sendInt(int rawData);
void sendFloat(float rawData);
void sendLong(long rawData);
void sendString(char rawData[]);
byte readRaw();
int available();
void gameJoyPress(byte BP_ST_BTN, byte BP_ND_BTN);
void gameJoyMove(signed int BP_X1,signed int BP_Y1,signed int BP_X2,signed int BP_Y2);
void gameJoyReleaseAll();
byte connected();
byte changeName(char BP_NAME[]);
private:
byte get(char BP_STAT[], byte strlen);
};
#endif

Thank you for your help

Any idea? Please i really need some help

You can try into your setup:

BPMod.begin(BP_MODE_HID,BP_HID_COMBO);