Error compiling for board ESP32 Dev Module with PS4Controller library

I am using an ESP32 microcontroller. I am attempting to use the PS4Controller library (GitHub - aed3/PS4-esp32: Use a ps4 controller with an esp32) to use a PS4 controller to provide input. I am able to run other example sketches with the ESP32 with no errors. When I try to use the example sketch titled "Ps4Connect" for the PS4Controller library, I get the error below. Any idea what is causing this and how I can fix it? Thank you!

\nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c: In function 'sppCallback':

\nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c:87:30: error: 'ESP_BT_CONNECTABLE' undeclared (first use in this function)

 esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);

                          ^

\nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c:87:30: note: each undeclared identifier is reported only once for each function it appears in

\nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c:87:50: error: 'ESP_BT_NON_DISCOVERABLE' undeclared (first use in this function)

 esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);

                                              ^

\nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c:87:5: error: too many arguments to function 'esp_bt_gap_set_scan_mode'

 esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);

 ^

In file included from \nas01.itap.purdue.edu\puhome\My Documents\Arduino\libraries\PS4-esp32-master\src\ps4_spp.c:4:0:

C:\Users\radkee\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4/tools/sdk/include/bt/esp_gap_bt_api.h:361:11: note: declared here

esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode);

       ^

exit status 1
Error compiling for board ESP32 Dev Module.

The error looks as if the library is not compatible with the ESP32. What you could try is to make sure you got the latest version of the library. If you do, downgrade a version. I'd try downgrading 2 or 3 versions. If that does not work then go to the library's author's site, open an issue, and post info about your error.

I got the same error as you did. Looks like a version compatibility issue.
To be able to compile the code to the current version some changes have to be done to the library. for program src/ps4_spp.c comment out the lines 86, 87, 88 and 90. they are just there for compatability on older versions. So you will have

//#if CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_D9CE0BB
//    esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
//#elif CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_21AF1D7
    esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE);
//#endif

After this you will encounter another error. This time for src/PS4Controller.cpp
The quick fix for this is to modify the program by adding on line 44

#define ESP_BD_ADDR_STR         "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"

In summary your program src/ps4_spp.c should be

#include "esp_bt.h"
#include "esp_bt_device.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_log.h"
#include "esp_spp_api.h"
#include "ps4.h"
#include "ps4_int.h"

#define PS4_TAG "PS4_SPP"

/********************************************************************************/
/*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
/********************************************************************************/
static void sppCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t* param);

/********************************************************************************/
/*                      P U B L I C    F U N C T I O N S                        */
/********************************************************************************/

/*******************************************************************************
**
** Function         sppInit
**
** Description      Initialise the SPP server to allow to be connected to
**
** Returns          void
**
*******************************************************************************/
void sppInit() {
  esp_err_t ret;

#ifndef ARDUINO_ARCH_ESP32
  esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
  if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bt_controller_enable(BT_MODE)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bluedroid_init()) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_bluedroid_enable()) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }
#endif

  if ((ret = esp_spp_register_callback(sppCallback)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }

  if ((ret = esp_spp_init(ESP_SPP_MODE_CB)) != ESP_OK) {
    ESP_LOGE(PS4_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
    return;
  }
}

/********************************************************************************/
/*                      L O C A L    F U N C T I O N S                          */
/********************************************************************************/

/*******************************************************************************
**
** Function         sppCallback
**
** Description      Callback for SPP events, only used for the init event to
**                  configure the SPP server
**
** Returns          void
**
*******************************************************************************/
static void sppCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t* param) {
  if (event == ESP_SPP_INIT_EVT) {
    ESP_LOGI(PS4_TAG, "ESP_SPP_INIT_EVT");
    esp_bt_dev_set_device_name("ESP Host");

//#if CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_D9CE0BB
//    esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_NON_DISCOVERABLE);
//#elif CONFIG_IDF_COMPATIBILITY >= IDF_COMPATIBILITY_MASTER_21AF1D7
    esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE);
//#endif

    esp_spp_start_srv(ESP_SPP_SEC_NONE, ESP_SPP_ROLE_SLAVE, 0, "ESP SERVER");
  }
}

and program src/PS4Controller.cpp should be

#include "PS4Controller.h"

#include <esp_bt_defs.h>
#include <esp_bt_main.h>

extern "C" {
#include "ps4.h"
}

#define ESP_BD_ADDR_HEX_PTR(addr) \
  (uint8_t*)addr + 0, (uint8_t*)addr + 1, (uint8_t*)addr + 2, \
  (uint8_t*)addr + 3, (uint8_t*)addr + 4, (uint8_t*)addr + 5

PS4Controller::PS4Controller() {}

bool PS4Controller::begin() {
  ps4SetEventObjectCallback(this, &PS4Controller::_event_callback);
  ps4SetConnectionObjectCallback(this, &PS4Controller::_connection_callback);

  if (!btStarted() && !btStart()) {
    log_e("btStart failed");
    return false;
  }

  esp_bluedroid_status_t btState = esp_bluedroid_get_status();
  if (btState == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
    if (esp_bluedroid_init()) {
      log_e("esp_bluedroid_init failed");
      return false;
    }
  }

  if (btState != ESP_BLUEDROID_STATUS_ENABLED) {
    if (esp_bluedroid_enable()) {
      log_e("esp_bluedroid_enable failed");
      return false;
    }
  }

  ps4Init();
  return true;
}

#define ESP_BD_ADDR_STR         "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
bool PS4Controller::begin(const char* mac) {
  esp_bd_addr_t addr;
    
  if (sscanf(mac, ESP_BD_ADDR_STR, ESP_BD_ADDR_HEX_PTR(addr)) != ESP_BD_ADDR_LEN) {
    log_e("Could not convert %s\n to a MAC address", mac);
    return false;
  }

  ps4SetBluetoothMacAddress(addr);

  return begin();
}

void PS4Controller::end() {}

bool PS4Controller::isConnected() { return ps4IsConnected(); }

void PS4Controller::setLed(uint8_t r, uint8_t g, uint8_t b) {
  output.r = r;
  output.g = g;
  output.b = b;
}

void PS4Controller::setRumble(uint8_t small, uint8_t large) {
  output.smallRumble = small;
  output.largeRumble = large;
}

void PS4Controller::setFlashRate(uint8_t onTime, uint8_t offTime) {
  output.flashOn = onTime / 10;
  output.flashOff = offTime / 10;
}

void PS4Controller::sendToController() { ps4SetOutput(output); }

void PS4Controller::attach(callback_t callback) { _callback_event = callback; }

void PS4Controller::attachOnConnect(callback_t callback) {
  _callback_connect = callback;
}

void PS4Controller::attachOnDisconnect(callback_t callback) {
  _callback_disconnect = callback;
}

void PS4Controller::_event_callback(
  void* object, ps4_t data, ps4_event_t event) {
  PS4Controller* This = (PS4Controller*)object;

  memcpy(&This->data, &data, sizeof(ps4_t));
  memcpy(&This->event, &event, sizeof(ps4_event_t));

  if (This->_callback_event) {
    This->_callback_event();
  }
}

void PS4Controller::_connection_callback(void* object, uint8_t isConnected) {
  PS4Controller* This = (PS4Controller*)object;

  if (isConnected) {
    delay(250);  // ToDo: figure out how to know when the channel is free again
                 // so this delay can be removed

    if (This->_callback_connect) {
      This->_callback_connect();
    }
  }
  else {
    if (This->_callback_disconnect) {
      This->_callback_disconnect();
    }
  }
}

#if !defined(NO_GLOBAL_INSTANCES)
PS4Controller PS4;
#endif

This worked! Thank you!

1 Like

Mr. gerivega

Thank you so much for your information,
i have followed your suggestion to change the src/ps4_spp.c, and it is work.

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