---
title: "BLE to Ethernet Thin Gateway"
url: "https://maker.wiznet.io/eric_g/projects/BLE-to-Ethernet-Thin-Gateway/"
markdown_url: "https://maker.wiznet.io/eric_g/projects/BLE-to-Ethernet-Thin-Gateway/md"
type: "UCC: User Created Content"
author: "eric_g"
author_url: "https://maker.wiznet.io/eric_g/"
original_author: "eric_g"
original_url: "https://www.hackster.io/kaizen8501/ble-to-ethernet-thin-gateway-9d5c1e"
published: "2022-05-01"
language: "en"
hardware: ["WIZnet W5500", "BLE s110/s120"]
likes: 0
views: 212
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# BLE to Ethernet Thin Gateway

> BLE to Ethernet Thin Gateway

Original author: eric_g (source: https://www.hackster.io/kaizen8501/ble-to-ethernet-thin-gateway-9d5c1e)

## Components

- **WIZnet W5500** x 1
- **BLE s110/s120** x 1
- Software: **Github**

## Article

## BLE to Ethernet Thin Gateway

BLE to Ethernet Thin Gateway is the data collector to transmit the BLE (Bluetooth Low Energy) data to a cloud server through Ethernet.

[**Intermediate](https://www.hackster.io/projects?difficulty=intermediate)**Full instructions provided**3,187

![BLE to Ethernet Thin Gateway](https://hackster.imgix.net/uploads/cover_image/file/127973/ble_gateway-1.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

### **Things used in this project

Story

Project Description

BLE to Ethernet Thin Gateway is the data collector to transmit the BLE(Bluetooth Low Energy) data to a cloud server through Ethernet.

**System Configuration**

The whole system is composed of Data Sender, Data Collector and Cloud Server. Data Sender measures the heart rate and transmits to Data Collector. For software of Data Sender, we use the ble_app_hrs_s110 example code provided by Nordic. We will use virtual data for heart rate and battery level.

Data Collector collects the data transmitted by Data Sender, and transmits the collected data to the cloud service. (In this posting, we will use the “dweet.io” service). For the software of Data Collector, we combines Nordic’s ble_app_hrs_c_s120 examples and W5500 io libraries.

![](https://hackster.imgix.net/uploads/image/file/127953/ble_gateway-1.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

**Hardware**

- Data Sender :?[nRF51 DK](https://www.nordicsemi.com/eng/Products/nRF51-DK)x 1

- Data Collector :?[nRF51 DK](https://www.nordicsemi.com/eng/Products/nRF51-DK)x 1 /?[WIZ550io](http://www.wiznet.co.kr/product-item/wiz550io/)?x 1 /?[xbee USB adapter](http://www.dfrobot.com/index.php?route=product/product&product_id=588#.VpNyzvmLRmU)

In order to check the debugging log and Ethernet function, connect the UART to USB module and WIZ550io as below.

![](https://hackster.imgix.net/uploads/image/file/127954/ble_gateway-2.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

1 / 2

**Software**

Download nRF51 SDK by clicking below link

<https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v10.x.x/>

You can get the Eclipse Project and source code from?[Github Repository](https://github.com/kaizen8501/nRF51_SDK_10.0.0_Example). After downloading the files from Github, save them in the below path.

```
ble_app_hrs : /examples/ble_peripheral
ble_app_hrs_c_with_W5500 : /examples/ble_central
```

**Data Sender**

(1) Development Environment

Import Existing Project

- [import]-[Existing Projects into Workspace]

- Select root directory

```
/examples/ble_peripheral/ble_app_hrs/pca10028/s110/armgcc
```

(2)Upload SoftDevice

![](https://hackster.imgix.net/uploads/image/file/127956/ble_gateway-4.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

(3)Upload Application

![](https://hackster.imgix.net/uploads/image/file/127957/ble_gateway-5.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

**Data Collector**

(1) Development Environment

Import Existing Project

- [import]-[Existing Projects into Workspace]

- Select root directory

```
/examples/ble_central/ble_app_hrs_c_with_W5500/pca10028/s120/armgcc
```

(2) Upload Software

![](https://hackster.imgix.net/uploads/image/file/127958/ble_gateway-6.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

(3) Upload Application

![](https://hackster.imgix.net/uploads/image/file/127959/ble_gateway_7.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

```
APP_TIMER_DEF(m_publish_data_timer_id);
int main(void)
{
????bool erase_bonds;
????uint32_t err_code;
????// Initialize.
????APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
????buttons_leds_init(&erase_bonds);
????uart_init();
????printf("Heart rate collector examplern");
????spi0_master_init();
????user_ethernet_init();
????app_mailbox_create(&hr_data_mailbox);
????app_mailbox_create(&bas_data_mailbox);
????ble_stack_init();
????device_manager_init(erase_bonds);
????db_discovery_init();
????hrs_c_init();
????bas_c_init();
????// Start scanning for peripherals and initiate connection
????// with devices that advertise Heart Rate UUID.
????scan_start();
????err_code = app_timer_create(&m_publish_data_timer_id, APP_TIMER_MODE_REPEATED, publish_data_handler);
????APP_ERROR_CHECK(err_code);
????err_code = app_timer_start(m_publish_data_timer_id,PUBLISH_INTERVAL,NULL);
????APP_ERROR_CHECK(err_code);
????for (;; )
????{
????	power_manage();
????}
}
```

- 1~2 : Set Timer Interval (300ms) to publish to cloud service & Initialize

- 16 : Initialize the SPI Interface to control WIZ550io

- 17 : Initialize the Ethernet (IP address and network configuration)

- 19 ~ 20 : Initialize the mail box (If the HR event and BAS event occurs, the values are saved into a mailbox)

- 22 ~ 24 : Initialize BLE Central Stack.

- 26 ~ 27 : Initialize HR(Heart Rate) and BAS(Battery) collector

- 32 : BLE Peripheral Scan and Connection Scan

- 34 ~ 37 : Create Publish Timer and Start

```
#define HR_EVT_MAILBOX_QUEUE_SIZE???? 10
#define BAS_EVT_MAILBOX_QUEUE_SIZE????10
typedef struct
{
????uint16_t evt_data;
????uint16_t dummy_data;
}hrs_c_evt_data;
typedef struct
{
????uint16_t battery_level;
????uint16_t dummy_data;
}bas_c_evt_data;
APP_MAILBOX_DEF(hr_data_mailbox, HR_EVT_MAILBOX_QUEUE_SIZE, sizeof(hrs_c_evt_data));
APP_MAILBOX_DEF(bas_data_mailbox, BAS_EVT_MAILBOX_QUEUE_SIZE, sizeof(bas_c_evt_data));
static any_port = 50000;
uint8_t dweet_io_ip[4] = {54,172,56,193};
uint16_t dest_port = 80;
#define THING???????? "Ble2Eth"
#define HEART_RATE???? "heart_rate"
#define BATTERY???? "battery"
```

- 1 ~ 2 : Set Mailbox QUEUE SIZE

- 4 ~ 14 : Initialize Hear rate and Batter level data format

- 16 ~ 17 : Initialize Mailbox

- 19 ~ 24 : Information to send the Data to dweet.io

```
static void publish_data_handler(void * p_context)
{
????UNUSED_PARAMETER(p_context);
????uint8_t sn = 0;
????uint32_t ret;
????uint8_t eth_data[512];
????hrs_c_evt_data hr_data;
????bas_c_evt_data batt_data;
????// Connect to server
????if(app_mailbox_length_get(&hr_data_mailbox) || app_mailbox_length_get(&bas_data_mailbox))
????{
????????if(getSn_SR(sn) != SOCK_CLOSED)
????????{
????????????close(sn);
????????????disconnect(sn);
????????}
????????while(getSn_SR(sn) != SOCK_CLOSED);
????????if( ret = socket(sn, Sn_MR_TCP, any_port++, 0x00) != sn )
????????{
????????????APPL_LOG("[PUBLISH]: Socket open failed, reason %drn", ret);
????????????return;
????????}
????????if( ret = connect(sn, dweet_io_ip, dest_port) != SOCK_OK )
????????{
????????????APPL_LOG("[PUBLISH]: Socket Connection failed, reason %drn", ret);
????????????return;
????????}
????}
????else????return;
????// Publish collected data
????while( app_mailbox_length_get(&hr_data_mailbox) != 0)
????{
????????app_mailbox_get(&hr_data_mailbox,&hr_data);
????????sprintf(eth_data,"GET /dweet/for/%s?%s=%d HTTP/1.1rnHost: dweet. iornrn",THING,HEART_RATE,hr_data.evt_data);
????????send(sn,eth_data,strlen((uint8_t*)eth_data));
????}
????while( app_mailbox_length_get(&bas_data_mailbox) != 0)
????{
????????app_mailbox_get(&bas_data_mailbox,&batt_data);
????????sprintf(eth_data,"GET /dweet/for/%s?%s=%d HTTP/1.1rnHost: dweet. iornrn",THING,BATTERY,batt_data.battery_level);
????????send(sn,eth_data,strlen((uint8_t*)eth_data));
????}
????close(sn);
????disconnect(sn);
}
```

- publish_data_handler’ is performed every 300ms to establish TCP connection with dweet.io and transmits the batter data and heart rate data.

- When ‘publish_data_hander’ is performed, mailbox data is transmitted via Ethernet

```
/**@brief Heart Rate Collector Handler.
*/
static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt)
{
????uint32_t err_code;
????uint32_t test;
????hrs_c_evt_data hrs_c_data;
????switch (p_hrs_c_evt->evt_type)
????{
????????case BLE_HRS_C_EVT_DISCOVERY_COMPLETE:
????????????// Heart rate service discovered. Enable notification of Heart Rate Measurement.
????????????err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c);
????????????APP_ERROR_CHECK(err_code);
????????????printf("Heart rate service discovered rn");
????????????break;
????????case BLE_HRS_C_EVT_HRM_NOTIFICATION:
????????{
????????????APPL_LOG("[APPL]: HR Measurement received %d rn", p_hrs_c_evt->params.hrm.hr_value);
????????????hrs_c_data.evt_data = p_hrs_c_evt->params.hrm.hr_value;
????????????app_mailbox_put(&hr_data_mailbox,&hrs_c_data);
????????????break;
????????}
????????default:
????????????break;
????}
}
/**@brief Battery levelCollector Handler.
*/
static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
{
????uint32_t err_code;
????bas_c_evt_data bas_data;
????switch (p_bas_c_evt->evt_type)
????{
????????case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
????????????// Batttery service discovered. Enable notification of Battery Level.
????????????APPL_LOG("[APPL]: Battery Service discovered. rn");
????????????APPL_LOG("[APPL]: Reading battery level. rn");
????????????err_code = ble_bas_c_bl_read(p_bas_c);
????????????APP_ERROR_CHECK(err_code);
????????????APPL_LOG("[APPL]: Enabling Battery Level Notification. rn");
????????????err_code = ble_bas_c_bl_notif_enable(p_bas_c);
????????????APP_ERROR_CHECK(err_code);
????????????break;
????????case BLE_BAS_C_EVT_BATT_NOTIFICATION:
????????{
????????????APPL_LOG("[APPL]: Battery Level received %d %%rn", p_bas_c_evt->params.battery_level);
????????????bas_data.battery_level = p_bas_c_evt->params.battery_level;
????????????app_mailbox_put(&bas_data_mailbox,&bas_data);
????????????break;
????????}
????????case BLE_BAS_C_EVT_BATT_READ_RESP:
????????{
????????????APPL_LOG("[APPL]: Battery Level Read as %d %%rn", p_bas_c_evt->params.battery_level);
????????????break;
????????}
????????default:
????????????break;
????}
}
```

- 20 ~ 26 : When the heart rate notification event occurs, data is saved in the mailbox

- 59 ~ 65 : When the battery notification event occurs, data is saved in the mailbox

- The data in the mailbox is transmitted viz Ethernet when ‘publish_data_handler’ is performed

**To Check the Data at the Cloud Service (dweet.io)**

In the free version service of dweet.io, the data is not saved in the database. Therefore, you can check the data on the web browser without specific configuration or key. Just input the URL as like ‘https://dweet.io/follow/Ble2Eth’. Just add the name of THING that defined above code at the end of ‘https://dweet.io/follow/”

![](https://hackster.imgix.net/uploads/image/file/127960/ble_gateway-8.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

In regard to use of dweet.io, you can learn it from the site ‘<https://dweet.io/>”

### **Code

- **Code snippet #1**

```
ble_app_hrs : <SDK>/examples/ble_peripheral
ble_app_hrs_c_with_W5500 : <SDK>/examples/ble_central
```

- **Code snippet #2**

&lt;SDK>/examples/ble_peripheral/ble_app_hrs/pca10028/s110/armgcc

- **Code snippet #3**

&lt;SDK>/examples/ble_central/ble_app_hrs_c_with_W5500/pca10028/s120/armgcc

- **Code snippet #4**

```
APP_TIMER_DEF(m_publish_data_timer_id);
int main(void)
{
????bool erase_bonds;
????uint32_t err_code;
????// Initialize.
????APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
????buttons_leds_init(&erase_bonds);
????uart_init();
????printf("Heart rate collector example\r\n");
????spi0_master_init();
????user_ethernet_init();
????app_mailbox_create(&hr_data_mailbox);
????app_mailbox_create(&bas_data_mailbox);
????ble_stack_init();
????device_manager_init(erase_bonds);
????db_discovery_init();
```

- **Code snippet #5**

```
#define HR_EVT_MAILBOX_QUEUE_SIZE???? 10
#define BAS_EVT_MAILBOX_QUEUE_SIZE????10
typedef struct
{
????uint16_t evt_data;
????uint16_t dummy_data;
}hrs_c_evt_data;
typedef struct
{
????uint16_t battery_level;
????uint16_t dummy_data;
}bas_c_evt_data;
APP_MAILBOX_DEF(hr_data_mailbox, HR_EVT_MAILBOX_QUEUE_SIZE, sizeof(hrs_c_evt_data));
APP_MAILBOX_DEF(bas_data_mailbox, BAS_EVT_MAILBOX_QUEUE_SIZE, sizeof(bas_c_evt_data));
static any_port = 50000;
uint8_t dweet_io_ip[4] = {54,172,56,193};
uint16_t dest_port = 80;
#define THING???????? "Ble2Eth"
#define HEART_RATE???? "heart_rate"
#define BATTERY???? "battery"
```

- **Code snippet #6**

```
static void publish_data_handler(void * p_context)
{
????UNUSED_PARAMETER(p_context);
????uint8_t sn = 0;
????uint32_t ret;
????uint8_t eth_data[512];
????hrs_c_evt_data hr_data;
????bas_c_evt_data batt_data;
????// Connect to server
????if(app_mailbox_length_get(&hr_data_mailbox) || app_mailbox_length_get(&bas_data_mailbox))
????{
????????if(getSn_SR(sn) != SOCK_CLOSED)
????????{
????????????close(sn);
????????????disconnect(sn);
????????}
????????while(getSn_SR(sn) != SOCK_CLOSED);
????????if( ret = socket(sn, Sn_MR_TCP, any_port++, 0x00) != sn )
????????{
????????????APPL_LOG("[PUBLISH]: Socket open failed, reason %d\r\n", ret);
????????????return;
????????}
????????if( ret = connect(sn, dweet_io_ip, dest_port) != SOCK_OK )
????????{
????????????APPL_LOG("[PUBLISH]: Socket Connection failed, reason %d\r\n", ret);
????????????return;
????????}
????}
????else????return;
????// Publish collected data
????while( app_mailbox_length_get(&hr_data_mailbox) != 0)
????{
????????app_mailbox_get(&hr_data_mailbox,&hr_data);
????????sprintf(eth_data,"GET /dweet/for/%s?%s=%d HTTP/1.1\r\nHost: dweet. io\r\n\r\n",THING,HEART_RATE,hr_data.evt_data);
????????send(sn,eth_data,strlen((uint8_t*)eth_data));
????}
????while( app_mailbox_length_get(&bas_data_mailbox) != 0)
????{
????????app_mailbox_get(&bas_data_mailbox,&batt_data);
????????sprintf(eth_data,"GET /dweet/for/%s?%s=%d HTTP/1.1\r\nHost: dweet. io\r\n\r\n",THING,BATTERY,batt_data.battery_level);
????????send(sn,eth_data,strlen((uint8_t*)eth_data));
????}
????close(sn);
????disconnect(sn);
}
```

- **Code snippet #7**

```
/**@brief Heart Rate Collector Handler.
 */
static void hrs_c_evt_handler(ble_hrs_c_t * p_hrs_c, ble_hrs_c_evt_t * p_hrs_c_evt)
{
????uint32_t err_code;
????uint32_t test;
????hrs_c_evt_data hrs_c_data;
 
????switch (p_hrs_c_evt->evt_type)
????{
????????case BLE_HRS_C_EVT_DISCOVERY_COMPLETE:
 
????????????// Heart rate service discovered. Enable notification of Heart Rate Measurement.
????????????err_code = ble_hrs_c_hrm_notif_enable(p_hrs_c);
????????????APP_ERROR_CHECK(err_code);
 
????????????printf("Heart rate service discovered \r\n");
????????????break;
 
????????case BLE_HRS_C_EVT_HRM_NOTIFICATION:
????????{
????????????APPL_LOG("[APPL]: HR Measurement received %d \r\n", p_hrs_c_evt->params.hrm.hr_value);
????????????hrs_c_data.evt_data = p_hrs_c_evt->params.hrm.hr_value;
????????????app_mailbox_put(&hr_data_mailbox,&hrs_c_data);
????????????break;
????????}
 
????????default:
????????????break;
????}
}
 
 
/**@brief Battery levelCollector Handler.
 */
static void bas_c_evt_handler(ble_bas_c_t * p_bas_c, ble_bas_c_evt_t * p_bas_c_evt)
{
????uint32_t err_code;
????bas_c_evt_data bas_data;
 
????switch (p_bas_c_evt->evt_type)
????{
????????case BLE_BAS_C_EVT_DISCOVERY_COMPLETE:
????????????// Batttery service discovered. Enable notification of Battery Level.
????????????APPL_LOG("[APPL]: Battery Service discovered. \r\n");
 
????????????APPL_LOG("[APPL]: Reading battery level. \r\n");
 
????????????err_code = ble_bas_c_bl_read(p_bas_c);
????????????APP_ERROR_CHECK(err_code);
 
 
????????????APPL_LOG("[APPL]: Enabling Battery Level Notification. \r\n");
????????????err_code = ble_bas_c_bl_notif_enable(p_bas_c);
????????????APP_ERROR_CHECK(err_code);
 
????????????break;
 
????????case BLE_BAS_C_EVT_BATT_NOTIFICATION:
????????{
????????????APPL_LOG("[APPL]: Battery Level received %d %%\r\n", p_bas_c_evt->params.battery_level);
????????????bas_data.battery_level = p_bas_c_evt->params.battery_level;
????????????app_mailbox_put(&bas_data_mailbox,&bas_data);
????????????break;
????????}
 
????????case BLE_BAS_C_EVT_BATT_READ_RESP:
????????{
????????????APPL_LOG("[APPL]: Battery Level Read as %d %%\r\n", p_bas_c_evt->params.battery_level);
????????????break;
????????}
 
????????default:
????????????break;
????}
}
```

#### Github

https://github.com/kaizen8501/nRF51_SDK_10.0.0_Example

---

Source: https://maker.wiznet.io/eric_g/projects/BLE-to-Ethernet-Thin-Gateway/
