Using bluetoothapis.h

Hey everybody,

i use the bluetoothapis.h in my unreal project to recieve sensor data from my smartphone.
I include it this way in my cpp:

#include “AllowWindowsPlatformTypes.h”
#include “bluetoothapis.h”
#include “HideWindowsPlatformTypes.h”

but i still get this error:

BluetoothConnector.cpp.obj : error LNK2019: Verweis auf nicht aufgeführtes externes Symbol “BluetoothFindFirstDevice” in Funktion ““public: virtual unsigned int __cdecl BluetoothConnector::Run(void)” (?Run@BluetoothConnector@@UEAAIXZ)”.
E:\Workspaces\GameDev\Binaries\Win64\UE4Editor-CaveUniverse.dll : fatal error LNK1120: 1 nicht aufgeführtes Externe

Anyone got a solution??

Greetings
Kosren

You need to link library in build script for UBT

Keep in mind that UE4 use VS only for complier, it has it’s own build system called UnrealBuildTool and it ignores VS configuration

And the award goes to you!! Thank you verry much!

Hi Kosren - I’m working on a college project to bring in heart rate data as a game variable.
I presume you coded a UE4 blueprint to integrate bluetooth using c++ ?
Were there many lines of code involved and did it take long to figure out ?
Is there any latency in reading the bluetooth data ?
Any help or advice would be great.
Joey

Hi joeycompbell, i coded a pure c++ class which read from a bluetooth socket. I used the windwos sockets. The class got round about 60 lines of codes, but many of them are just thread handling. I dont got any latency problems while reading the datas. I used a queue to process them. I used this thread tutorial as an entry point Maintenance - Unreal Engine. After that I fight me through the mircosoft win_socket documentation. I hope that helps you.
Happy Coding
Kosren

Hi Kosren - would you consider packaging your bluetooth script as a plugin and selling it on the Unreal Market place ?

Hi joey, i will post the code of the handler in a new answer - Kosren

If someone need it too, here is my code!

BluetoothConnector.h

#pragma once

#include "CaveUniversePlayerController.h"
#include "AllowWindowsPlatformTypes.h"
#include "bluetoothapis.h"
#include <WinSock2.h>
#include <ws2bth.h>
#include "HideWindowsPlatformTypes.h"

/**
 * A thread which get data from bluetooth dongle
 */
class CAVEUNIVERSE_API BluetoothConnector : public FRunnable
{

	//Contstructor	
	public:
		BluetoothConnector(); 
		virtual ~BluetoothConnector();

	//Private attributes
	private:
		SOCKET bluetoothSocket;						//The socket which listen to the bluetooth device
		SOCKET connected;							//The socket which is connected to the smartphone via bluetooth
		FThreadSafeCounter stopTaskCounter;			//stop the thread with this counter
		static BluetoothConnector* connector;		//A static singleton to access the thread
		FRunnableThread* thread;					//The running thread

	//Public methods from FRunnable
	public:
		virtual bool Init();
		virtual uint32 Run();
		virtual void Stop();

	//Public methods
	public:
		void EnsureCompletion();										//Proper shutdown
		static void joyInit();	                                                                                //A static method to initialize the thread
		static void shutdownThread();									//A static method to kill the thread

};

BluetoothConnector.cpp

#include "CaveUniverse.h"
#include "BluetoothConnector.h"
#include <string>

BluetoothConnector* BluetoothConnector::connector = NULL;

BluetoothConnector::BluetoothConnector()  {

	thread = FRunnableThread::Create(this, TEXT("BluetoothConnector"), 0, TPri_BelowNormal);

}

BluetoothConnector::~BluetoothConnector() {
	
	delete thread;
	thread = NULL;

}

//Initialize the thread
bool BluetoothConnector::Init() {

	return true;

}

//Run the thread
uint32 BluetoothConnector::Run() {

	//A char array to store the incoming data
	const int recvBufLen = 1024;
	char recvData[recvBufLen];

	//Data to initialize the winsocket
	WSADATA wsaData;

	//The socket which connects to the local device
	SOCKADDR_BTH socketAdress;
	bluetoothSocket = NULL;
	int error = SOCKET_ERROR;

	//initialize win socket
	error = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (error != NO_ERROR) {

		UE_LOG(LogTemp, Error, TEXT("Can not startup the win socket! Last Error:[%d]"), WSAGetLastError());
		WSACleanup();
		return 1;

	}

	//Create socket adress of the local socket to the bluetooth dongle
	bluetoothSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
	socketAdress.addressFamily = AF_BTH;
	socketAdress.btAddr = 0;
	socketAdress.serviceClassId = RFCOMM_PROTOCOL_UUID;
	socketAdress.port = BT_PORT_ANY;

	//Bind the socket to the local bluetooth device
	error = bind(bluetoothSocket, (SOCKADDR*)&socketAdress, sizeof(socketAdress));
	if (error == SOCKET_ERROR) {

		UE_LOG(LogTemp, Error, TEXT("Bluetooth socket can not be binded! Last Error:[%d]"), WSAGetLastError());
		closesocket(bluetoothSocket);
		WSACleanup();
		return 1;

	}

	//Listen on the bluetooth device for incoming connections
	error = listen(bluetoothSocket, 1);
	if (error == SOCKET_ERROR) {

		UE_LOG(LogTemp, Error, TEXT("Bluetooth socket listen failed! Last Error:[%d]"), WSAGetLastError());
		closesocket(bluetoothSocket);
		WSACleanup();
		return 1;

	}

	//The accepted socket to recieve data from
	UE_LOG(LogTemp, Log, TEXT("Waiting for incoming connection"));
	connected = accept(bluetoothSocket, NULL, NULL);
	UE_LOG(LogTemp, Log, TEXT("Device is connected"));

	if (connected != INVALID_SOCKET) {

		while (stopTaskCounter.GetValue() == 0) {

			//Get data from bluetooth dongle and set the rotation to the actor
			error = recv(connected, recvData, recvBufLen, 0);

			//We get data so we can use them
			if (error > 0) {

				//Do somesthing with your data

			//Connection was closed or an error appear, we shutdown the thread
			} else {

				stopTaskCounter.Increment();

			}
		} 
	}

	//Close connection to the bluetooth device
	closesocket(bluetoothSocket);
	closesocket(connected);
	WSACleanup();

	return 0;

}

//Do a joy initialize of the thread
void BluetoothConnector::joyInit() {

	if (!connector && FPlatformProcess::SupportsMultithreading()) {

		connector = new BluetoothConnector();

	}
}

//Stop the thread
void BluetoothConnector::Stop() {

	stopTaskCounter.Increment();

}

//Ensure that the thread stop
void BluetoothConnector::EnsureCompletion() {

	closesocket(bluetoothSocket);
	closesocket(connected);
	Stop();
	thread->WaitForCompletion();

}

//Shut the thread down
void BluetoothConnector::shutdownThread() {

	if(connector) {

		connector->EnsureCompletion();
		delete connector;
		connector = NULL;

	}
}
1 Like

Thanks Kosren - thats very generous of you!

Guys, I´m totally crazy with this. Iwas trying to implement this classes for read a heart rate monitor and put inside a Hud in UE4 but! I don´t know how can I do. Could you try to explain it to me like a dumb? :frowning: Thanks a lot

Hello Emilio, can you please describe your problem in detail? Like where are your troubles with including the source code in your project.

Hi I used a polar heart rate monitor connected to an arduino.
I used the ue4duino plugin and was able to bring the bpm into the main blueprint.
I passed this bpm variable in realtime into a HUD created in the UI design component within unreal (I forget the name of the UI designer).I tried several monitors with arduino but the polar was the most reliable but the user will need to be wirhin 2 metres of the arduino receiver. Hope this helps.

I don´t really know where the proble is and I don´t know how can i solve it because I was tryng to use your code but I´m a noob so I don´t really know what kind of component I need to create into my unreal to fix it.

Hi Joey,

Why do you need to conect it to an arduino hardw? Could you explain it to me? Probabilly I could try to fix with this method but if I do an arduino BLE reciever I think that I will have so many devices. Right?

Hi Emilio I used arduino because I did not know how to compile my own code to read directly from a smartphone or fitbit.

Oh man! I need it just for use in Windows with oculus! Could you help me? I can pay you for the bluprint!

Can not find Cad Universe PlayerController.h

The CaveUniversePlayerController comes from my Project where I used the Bluetooth connector, therefore this should be your own player controller.

Hi, I copied your code to vs2015 and compiled it, then call BluetoothConnector :: joyInit () on the blueprint, but “Output Log” prints only LogTemp: Waiting for incoming connection, which has not been connected successfully. It I was running, always with my phone connected to the computer Bluetooth.

Hi @Kosren, I know it’s been a couple of years since this post was active but would you be able to give me any pointers on whats causing the errors in your code? I can’t seem to get it working at all.