Building a Remote BLE Interface: Access BLE devices from Any Location
November 5, 2024This article will discuss about accessing a Bluetooth Low Energy (BLE) device—specifically the BleuIO BLE USB dongle—from a cloud-based computer. This setup is invaluable for developers, researchers, and organizations that need to control or monitor BLE devices located in remote or hard-to-reach locations. We will explain how to set up both local and cloud servers, and how to establish a secure connection between them, allowing you to send commands and receive data from a remote BLE device with ease.
Why Do We Need Remote Access to BLE Devices?
Remote access to BLE devices opens up new possibilities in IoT, distributed applications, and various remote monitoring and management scenarios. Here are a few key use cases where this approach can be especially beneficial:
Remote Device Monitoring: In scenarios where BLE devices like sensors or trackers are deployed in different physical locations—such as environmental monitoring stations, healthcare devices in hospitals, or industrial sensors in manufacturing facilities—remote access allows centralized monitoring and control. For example, an environmental monitoring company could deploy BLE sensors in different regions and access data from all devices from a single central hub.
Distributed Development and Testing: Developers and QA engineers can use remote access for testing and debugging BLE applications from any location, without needing to be physically near the BLE devices. This is particularly useful for teams working on IoT applications who want to test BLE functionality across different device types or networks. For instance, a developer could work on BLE application features from home, while the test device is connected to a machine in the office.
Centralized Management of BLE Devices: Organizations that manage multiple BLE devices across various locations, such as in retail stores, hospitals, or warehouses, can benefit from a centralized server setup to communicate with and manage all devices remotely. A central server could send updates, retrieve data, or manage configurations for multiple BLE devices, providing an efficient and scalable solution for distributed IoT applications.
Remote Troubleshooting and Maintenance: For businesses that deploy BLE devices at customer sites or in field locations, remote access allows technical support teams to troubleshoot issues without requiring on-site visits. This can reduce downtime and improve customer satisfaction. For example, a support technician could diagnose issues with a BLE-enabled device at a remote client site, identifying and resolving problems directly from the company’s central office.
By using BleuIO with AT commands, we make BLE application development much simpler and more accessible. The BleuIO dongle is compatible with Windows, macOS, and Linux, allowing consistent development across platforms.
Project Structure and Components
In this project, we’ll use the following components to remotely access and control BLE devices:
- Device with BleuIO Connected (Local Device): This is the device with the BleuIO dongle physically attached, acting as the local interface for sending and receiving BLE commands. It will run a small server to manage communication with the BLE dongle over a serial connection.
- Remote Access Server (Cloud Server): This is the server that provides remote access to the local device. By connecting to the local server, it enables us to send commands and receive data from the BLE dongle remotely.
- LocalTunnel: We’ll use LocalTunnel to generate a secure public URL, allowing the cloud server to communicate with the local device without needing complex router configurations. This URL acts as a bridge, making the local device accessible from anywhere with internet access.
- Node.js: Both the local device and the cloud server will use Node.js to run simple server scripts that facilitate communication between the cloud server and the BLE dongle.
Step-by-Step Guide
Step 1: Setting Up the Local Server with BleuIO dongle connected to it
Local device is where the BleuIO dongle is physically connected. We’ll set up a Node.js server that communicates with the dongle through the serial port. This server will accept commands from the cloud server and send them to the BLE dongle, then return the response.
Install Node.js (if not already installed) on Local device.
Create a project folder and initialize a Node.js project:mkdir local_serial_server
cd local_serial_server
npm init -y
Install Dependencies:
- Install
serialport
to handle serial communication with the BLE dongle.Installsocket.io
to manage WebSocket connections.
npm install serialport socket.io
Create the Local Serial Server Script:
- Create a file named
local_serial_server.js
. This script will:- Listen for WebSocket connections from the cloud server.Accept commands, pass them to the BleuIO dongle, and send back responses.
const http = require('http');
const { SerialPort } = require('serialport');
const socketIo = require('socket.io');
const server = http.createServer();
const io = socketIo(server);
// Define the serial port path and baud rate
const portPath = 'COM592'; // Replace 'COM3' with your dongle's port
const serialPort = new SerialPort({ path: portPath, baudRate: 9600 });
// Listen for incoming connections from the cloud server
io.on('connection', (socket) => {
console.log('Connected to cloud server');
// Receive command from cloud and send to serial port
socket.on('sendCommand', (command) => {
const formattedCommand = `${command}\r\n`;
console.log(`Sending command to serial port: ${formattedCommand}`);
serialPort.write(formattedCommand);
});
// Send serial responses to cloud server
serialPort.on('data', (data) => {
console.log(`Data received from serial port: ${data}`);
socket.emit('serialResponse', data.toString());
});
});
// Start the server on a specified port
const LOCAL_PORT = 4000; // Choose any port, ensure firewall allows it
server.listen(LOCAL_PORT, () => {
console.log(`Local Serial Server running on http://localhost:${LOCAL_PORT}`);
});
Find and Set the Serial Port Path:
In your local_serial_server.js
, specify the correct serial port path for your BLE dongle (e.g., COM3
on Windows or /dev/ttyUSB0
on Linux).
Run the Local Serial Server:
- Start the server by running: node local_serial_server.js
At this point, the local server is ready, but it’s only accessible to itself. Next, we’ll use LocalTunnel to make it accessible to the cloud server.
Step 2: Exposing the Local Server to the Internet Using LocalTunnel
Since local device 1 and cloud device are on different networks, we’ll need to create a public URL for the local server. There are several options to make a local server accessible publicly, including tools like ngrok, Pagekite, and LocalTunnel. For this tutorial, we’ll be using LocalTunnel as it’s free and easy to set up, but feel free to explore other solutions if they better meet your needs.
- Install LocalTunnel:
- On local device, install LocalTunnel globally
npm install -g localtunnel
- On local device, install LocalTunnel globally
- Start LocalTunnel:
- Open a new terminal window on local device and run
lt --port 4000
- LocalTunnel will generate a public URL (e.g.,
https://five-sides-live.loca.lt
). This URL will allow cloud device to access the local server running on port4000
of Local device.
- Open a new terminal window on local device and run
- Save the LocalTunnel URL:
- Copy the URL provided by LocalTunnel. This URL will be used in the cloud server configuration on Cloud device.
Step 3: Setting Up the Cloud Server on Cloud device
In this setup, Cloud device will act as the cloud server that connects to local device’s LocalTunnel URL, allowing remote access to the BLE dongle. Cloud device can be any machine with Node.js installed—located anywhere, such as a remote computer in New York. You could also deploy this server on a cloud platform like Heroku, Replit, or Vercel for persistent access.
For simplicity, in this example, we’ll demonstrate how to set up the cloud server on another computer running Node.js, not connected to the same network as local device.
Create a Project Folder on cloud device and Initialize Node.js:
Open a terminal or command prompt on cloud device and create a folder for the cloud server mkdir cloud_serial_server
cd cloud_serial_server
npm init -y
Install Dependencies:
You’ll need express
to serve the front-end pages and socket.io
to manage WebSocket communication.
Install socket.io-client
to allow the cloud server to connect to the LocalTunnel URL created on Local devicenpm install express socket.io socket.io-client
Create the Cloud Server Script: In the cloud_serial_server
folder, create a file named cloud_server.js
. This script will Connect to the LocalTunnel URL (generated by Local device) and forward BLE commands to the local server.Serve the front-end pages (index.html
and page2.html
) for interacting with the BLE device remotely.
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const ioClient = require('socket.io-client'); // Client for local serial server
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
// Connect to the local serial server via WebSocket
const LOCAL_SERVER_URL = 'https://real-poets-count.loca.lt';
const localSocket = ioClient(LOCAL_SERVER_URL);
// Serve static files (frontend files for Page 1 and Page 2)
app.use(express.static('public'));
// Handle messages from Page 2 and forward to local serial server
io.on('connection', (socket) => {
console.log('Client connected to cloud server');
// Receive command from Page 2 and forward to local serial server
socket.on('sendCommand', (command) => {
console.log(`Forwarding command to local server: ${command}`);
localSocket.emit('sendCommand', command); // Send to local serial server
});
socket.on('disconnect', () => {
console.log('Client disconnected from cloud server');
});
});
// Receive data from local serial server and forward to clients
localSocket.on('serialResponse', (data) => {
console.log(`Received data from local serial server: ${data}`);
io.emit('serialResponse', data); // Broadcast to connected clients
});
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
console.log(`Cloud server is running on http://localhost:${PORT}`);
});
Update the LocalTunnel URL in Cloud Server:
Replace the LOCAL_SERVER_URL
in cloud_server.js
with the LocalTunnel URL you generated on Local device (e.g., https://five-sides-live.loca.lt
).
Run the Cloud Server:
Start the cloud server by running:bashCopy codenode cloud_server.js
This will start a server that listens for connections on Cloud device. You can open a web browser on Cloud device and go to http://localhost:3000
to access the front-end pages.
Access the Front-End Pages:
Open a browser and navigate to http://localhost:3000/index.html
(for displaying BLE responses) and http://localhost:3000/page2.html
(for sending commands).
Note: If you decide to deploy this server to a cloud platform (e.g., Heroku, Replit, or Vercel), replace localhost
with the appropriate URL provided by the platform.
With this setup, Cloud device can be anywhere in the world, allowing you to control and receive data from the BLE dongle on Local device (in Stockholm) remotely.
Source code
The source code is available here at https://github.com/smart-sensor-devices-ab/remote_bleuio.git
Output
This tutorial demonstrates the potential of combining Node.js, BLE technology, and tunneling services for remote BLE access. The BleuIO dongle’s compatibility and simplicity make it an excellent choice for developers interested in building BLE applications across various operating systems.