This is sample code for interfacing ROHM's SENSORSHLD1-EVK-101 with Nordic Semiconductor's nRF51-DK Development Kit Host BTLE Board

Dependencies:   BLE_API mbed nRF51822

Fork of Nordic_UART_TEMPLATE_ROHM by ROHMUSDC

Code Example for ROHM Mutli-Sensor Shield on the Nordic Semiconductor nRF51-DK

This code was written to be used with the Nordic Semiconductor nRF51-DK.

This is the basic example code for interfacing ROHM's Multi-sensor Shield Board onto this board.

Additional information about the ROHM MultiSensor Shield Board can be found at the following link: https://github.com/ROHMUSDC/ROHM_SensorPlatform_Multi-Sensor-Shield

For code example for the ROHM SENSORSHLD0-EVK-101, please see the following link: https://developer.mbed.org/teams/ROHMUSDC/code/Nordic_UART_TEMPLATE_ROHM/

Operation

Ultimately, this code will initialize all the sensors on the Multi-sensor shield board and then poll the sensors. The sensor data will then be returned to the BTLE COM port link and will be view-able on any BTLE enabled phone that can connect to the Nordic UART Application.

Supported ROHM Sensor Devices

  • BDE0600G Temperature Sensor
  • BM1383GLV Pressure Sensor
  • BU52014 Hall Sensor
  • ML8511 UV Sensor
  • RPR-0521 ALS/PROX Sensor
  • BH1745NUC Color Sensor
  • KMX62 Accel/Mag Sensor
  • KX122 Accel Sensor
  • BM1422 MI Magnetometer Sensor
  • KXG03 Gyro/Accel Sensor

Updates from SHLD0 to SHLD1

  • Pressure Sensor Changes: Fixed Register Map Changes for BM1383AGLV, See Pressure Sensor Datasheet for more details - TEMP and PRES output switched
  • Added new #ifdef section for Magnetometer
  • Changed Gyro Device Address (7bit addr now 0x4F, not 0x4E)

Sensor Applicable Code Sections

  • Added a Section in "Main" to act as initialization
  • Added to the "Periodic Callback" to read sensor data and return to Phone/Host

Questions/Feedback

Please feel free to let us know any questions/feedback/comments/concerns on the ROHM shield implementation by contacting the following e-mail:

Committer:
Daniel Veilleux
Date:
Mon Dec 15 21:05:18 2014 -0800
Revision:
0:442c7a6f1978
Child:
1:2c0ab5cd1a7f
Initial commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Daniel Veilleux 0:442c7a6f1978 1 /* mbed Microcontroller Library
Daniel Veilleux 0:442c7a6f1978 2 * Copyright (c) 2006-2013 ARM Limited
Daniel Veilleux 0:442c7a6f1978 3 *
Daniel Veilleux 0:442c7a6f1978 4 * Licensed under the Apache License, Version 2.0 (the "License");
Daniel Veilleux 0:442c7a6f1978 5 * you may not use this file except in compliance with the License.
Daniel Veilleux 0:442c7a6f1978 6 * You may obtain a copy of the License at
Daniel Veilleux 0:442c7a6f1978 7 *
Daniel Veilleux 0:442c7a6f1978 8 * http://www.apache.org/licenses/LICENSE-2.0
Daniel Veilleux 0:442c7a6f1978 9 *
Daniel Veilleux 0:442c7a6f1978 10 * Unless required by applicable law or agreed to in writing, software
Daniel Veilleux 0:442c7a6f1978 11 * distributed under the License is distributed on an "AS IS" BASIS,
Daniel Veilleux 0:442c7a6f1978 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Daniel Veilleux 0:442c7a6f1978 13 * See the License for the specific language governing permissions and
Daniel Veilleux 0:442c7a6f1978 14 * limitations under the License.
Daniel Veilleux 0:442c7a6f1978 15 */
Daniel Veilleux 0:442c7a6f1978 16
Daniel Veilleux 0:442c7a6f1978 17 #include "mbed.h"
Daniel Veilleux 0:442c7a6f1978 18 #include "BLEDevice.h"
Daniel Veilleux 0:442c7a6f1978 19 #include "UARTService.h"
Daniel Veilleux 0:442c7a6f1978 20 #include "nrf_temp.h"
Daniel Veilleux 0:442c7a6f1978 21
Daniel Veilleux 0:442c7a6f1978 22 #define MAX_REPLY_LEN (UARTService::BLE_UART_SERVICE_MAX_DATA_LEN)
Daniel Veilleux 0:442c7a6f1978 23 #define SENSOR_READ_INTERVAL_S (0.5F)
Daniel Veilleux 0:442c7a6f1978 24 #define ADV_INTERVAL_MS (1000UL)
Daniel Veilleux 0:442c7a6f1978 25 #define UART_BAUD_RATE (19200UL)
Daniel Veilleux 0:442c7a6f1978 26 #define DEVICE_NAME ("DEMO SENSOR") // This can be read AFTER connecting to the device.
Daniel Veilleux 0:442c7a6f1978 27 #define SHORT_NAME ("HACKDEMO") // Keep this short: max 8 chars if a 128bit UUID is also advertised.
Daniel Veilleux 0:442c7a6f1978 28
Daniel Veilleux 0:442c7a6f1978 29 #define DEBUG(...) { m_serial_port.printf(__VA_ARGS__); }
Daniel Veilleux 0:442c7a6f1978 30
Daniel Veilleux 0:442c7a6f1978 31
Daniel Veilleux 0:442c7a6f1978 32 BLEDevice m_ble;
Daniel Veilleux 0:442c7a6f1978 33 Serial m_serial_port(p9, p11); // TX pin, RX pin
Daniel Veilleux 0:442c7a6f1978 34 DigitalOut m_cmd_led(LED1);
Daniel Veilleux 0:442c7a6f1978 35 DigitalOut m_error_led(LED2);
Daniel Veilleux 0:442c7a6f1978 36 AnalogIn m_analog_in(p1);
Daniel Veilleux 0:442c7a6f1978 37 uint16_t m_analog_in_value;
Daniel Veilleux 0:442c7a6f1978 38 UARTService *m_uart_service_ptr;
Daniel Veilleux 0:442c7a6f1978 39
Daniel Veilleux 0:442c7a6f1978 40
Daniel Veilleux 0:442c7a6f1978 41 /**
Daniel Veilleux 0:442c7a6f1978 42 * This callback is used whenever a disconnection occurs.
Daniel Veilleux 0:442c7a6f1978 43 */
Daniel Veilleux 0:442c7a6f1978 44 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
Daniel Veilleux 0:442c7a6f1978 45 {
Daniel Veilleux 0:442c7a6f1978 46 switch (reason) {
Daniel Veilleux 0:442c7a6f1978 47 case Gap::REMOTE_USER_TERMINATED_CONNECTION:
Daniel Veilleux 0:442c7a6f1978 48 DEBUG("Disconnected (REMOTE_USER_TERMINATED_CONNECTION)\n\r");
Daniel Veilleux 0:442c7a6f1978 49 break;
Daniel Veilleux 0:442c7a6f1978 50 case Gap::LOCAL_HOST_TERMINATED_CONNECTION:
Daniel Veilleux 0:442c7a6f1978 51 DEBUG("Disconnected (LOCAL_HOST_TERMINATED_CONNECTION)\n\r");
Daniel Veilleux 0:442c7a6f1978 52 break;
Daniel Veilleux 0:442c7a6f1978 53 case Gap::CONN_INTERVAL_UNACCEPTABLE:
Daniel Veilleux 0:442c7a6f1978 54 DEBUG("Disconnected (CONN_INTERVAL_UNACCEPTABLE)\n\r");
Daniel Veilleux 0:442c7a6f1978 55 break;
Daniel Veilleux 0:442c7a6f1978 56 }
Daniel Veilleux 0:442c7a6f1978 57
Daniel Veilleux 0:442c7a6f1978 58 DEBUG("Restarting the advertising process\n\r");
Daniel Veilleux 0:442c7a6f1978 59 m_ble.startAdvertising();
Daniel Veilleux 0:442c7a6f1978 60 }
Daniel Veilleux 0:442c7a6f1978 61
Daniel Veilleux 0:442c7a6f1978 62
Daniel Veilleux 0:442c7a6f1978 63 /**
Daniel Veilleux 0:442c7a6f1978 64 * This callback is used whenever the host writes data to one of our GATT characteristics.
Daniel Veilleux 0:442c7a6f1978 65 */
Daniel Veilleux 0:442c7a6f1978 66 void dataWrittenCallback(const GattCharacteristicWriteCBParams *params)
Daniel Veilleux 0:442c7a6f1978 67 {
Daniel Veilleux 0:442c7a6f1978 68 // Ensure that initialization is finished and the host has written to the TX characteristic.
Daniel Veilleux 0:442c7a6f1978 69 if ((m_uart_service_ptr != NULL) && (params->charHandle == m_uart_service_ptr->getTXCharacteristicHandle())) {
Daniel Veilleux 0:442c7a6f1978 70 uint8_t buf[MAX_REPLY_LEN];
Daniel Veilleux 0:442c7a6f1978 71 uint32_t len = 0;
Daniel Veilleux 0:442c7a6f1978 72
Daniel Veilleux 0:442c7a6f1978 73 if (1 == params->len) {
Daniel Veilleux 0:442c7a6f1978 74 switch (params->data[0]) {
Daniel Veilleux 0:442c7a6f1978 75 case '0':
Daniel Veilleux 0:442c7a6f1978 76 m_cmd_led = 0;
Daniel Veilleux 0:442c7a6f1978 77 len = snprintf((char*) buf, MAX_REPLY_LEN, "OK");
Daniel Veilleux 0:442c7a6f1978 78 break;
Daniel Veilleux 0:442c7a6f1978 79 case '1':
Daniel Veilleux 0:442c7a6f1978 80 m_cmd_led = 1;
Daniel Veilleux 0:442c7a6f1978 81 len = snprintf((char*) buf, MAX_REPLY_LEN, "OK");
Daniel Veilleux 0:442c7a6f1978 82 break;
Daniel Veilleux 0:442c7a6f1978 83 case 'a':
Daniel Veilleux 0:442c7a6f1978 84 len = snprintf((char*) buf, MAX_REPLY_LEN, "%d", m_analog_in_value);
Daniel Veilleux 0:442c7a6f1978 85 break;
Daniel Veilleux 0:442c7a6f1978 86 default:
Daniel Veilleux 0:442c7a6f1978 87 len = snprintf((char*) buf, MAX_REPLY_LEN, "ERROR: Unknown char");
Daniel Veilleux 0:442c7a6f1978 88 break;
Daniel Veilleux 0:442c7a6f1978 89 }
Daniel Veilleux 0:442c7a6f1978 90 }
Daniel Veilleux 0:442c7a6f1978 91 else
Daniel Veilleux 0:442c7a6f1978 92 {
Daniel Veilleux 0:442c7a6f1978 93 len = snprintf((char*) buf, MAX_REPLY_LEN, "ERROR: Invalid len");
Daniel Veilleux 0:442c7a6f1978 94 }
Daniel Veilleux 0:442c7a6f1978 95
Daniel Veilleux 0:442c7a6f1978 96 m_ble.updateCharacteristicValue(m_uart_service_ptr->getRXCharacteristicHandle(), buf, len);
Daniel Veilleux 0:442c7a6f1978 97
Daniel Veilleux 0:442c7a6f1978 98 DEBUG("%d bytes received from host\n\r", params->len);
Daniel Veilleux 0:442c7a6f1978 99 }
Daniel Veilleux 0:442c7a6f1978 100 }
Daniel Veilleux 0:442c7a6f1978 101
Daniel Veilleux 0:442c7a6f1978 102
Daniel Veilleux 0:442c7a6f1978 103 /**
Daniel Veilleux 0:442c7a6f1978 104 * This callback is used whenever a write to a GATT characteristic causes data to be sent to the host.
Daniel Veilleux 0:442c7a6f1978 105 */
Daniel Veilleux 0:442c7a6f1978 106 void dataSentCallback(unsigned count)
Daniel Veilleux 0:442c7a6f1978 107 {
Daniel Veilleux 0:442c7a6f1978 108 // NOTE: The count always seems to be 1 regardless of data.
Daniel Veilleux 0:442c7a6f1978 109 DEBUG("%d bytes sent to host\n\r", count);
Daniel Veilleux 0:442c7a6f1978 110 }
Daniel Veilleux 0:442c7a6f1978 111
Daniel Veilleux 0:442c7a6f1978 112
Daniel Veilleux 0:442c7a6f1978 113 /**
Daniel Veilleux 0:442c7a6f1978 114 * This callback is scheduled to be called periodically via a low-priority interrupt.
Daniel Veilleux 0:442c7a6f1978 115 */
Daniel Veilleux 0:442c7a6f1978 116 void periodicCallback(void)
Daniel Veilleux 0:442c7a6f1978 117 {
Daniel Veilleux 0:442c7a6f1978 118 m_analog_in_value = m_analog_in.read_u16();
Daniel Veilleux 0:442c7a6f1978 119 }
Daniel Veilleux 0:442c7a6f1978 120
Daniel Veilleux 0:442c7a6f1978 121
Daniel Veilleux 0:442c7a6f1978 122 void error(ble_error_t err, uint32_t line)
Daniel Veilleux 0:442c7a6f1978 123 {
Daniel Veilleux 0:442c7a6f1978 124 m_error_led = 1;
Daniel Veilleux 0:442c7a6f1978 125 DEBUG("Error %d on line number %d\n\r", err, line);
Daniel Veilleux 0:442c7a6f1978 126 }
Daniel Veilleux 0:442c7a6f1978 127
Daniel Veilleux 0:442c7a6f1978 128
Daniel Veilleux 0:442c7a6f1978 129 int main(void)
Daniel Veilleux 0:442c7a6f1978 130 {
Daniel Veilleux 0:442c7a6f1978 131 ble_error_t err;
Daniel Veilleux 0:442c7a6f1978 132 Ticker ticker;
Daniel Veilleux 0:442c7a6f1978 133
Daniel Veilleux 0:442c7a6f1978 134 m_serial_port.baud(UART_BAUD_RATE);
Daniel Veilleux 0:442c7a6f1978 135
Daniel Veilleux 0:442c7a6f1978 136 DEBUG("Initialising\n\r");
Daniel Veilleux 0:442c7a6f1978 137
Daniel Veilleux 0:442c7a6f1978 138 m_cmd_led = 0;
Daniel Veilleux 0:442c7a6f1978 139 m_error_led = 0;
Daniel Veilleux 0:442c7a6f1978 140 m_analog_in_value = 0;
Daniel Veilleux 0:442c7a6f1978 141
Daniel Veilleux 0:442c7a6f1978 142 ticker.attach(periodicCallback, SENSOR_READ_INTERVAL_S);
Daniel Veilleux 0:442c7a6f1978 143
Daniel Veilleux 0:442c7a6f1978 144 m_ble.init();
Daniel Veilleux 0:442c7a6f1978 145 m_ble.onDisconnection(disconnectionCallback);
Daniel Veilleux 0:442c7a6f1978 146 m_ble.onDataWritten(dataWrittenCallback);
Daniel Veilleux 0:442c7a6f1978 147 m_ble.onDataSent(dataSentCallback);
Daniel Veilleux 0:442c7a6f1978 148
Daniel Veilleux 0:442c7a6f1978 149 // Set the TX power in dBm units.
Daniel Veilleux 0:442c7a6f1978 150 // Possible values (in decreasing order): 4, 0, -4, -8, -12, -16, -20.
Daniel Veilleux 0:442c7a6f1978 151 err = m_ble.setTxPower(4);
Daniel Veilleux 0:442c7a6f1978 152 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 153 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 154 }
Daniel Veilleux 0:442c7a6f1978 155
Daniel Veilleux 0:442c7a6f1978 156 // Setup advertising (GAP stuff).
Daniel Veilleux 0:442c7a6f1978 157 err = m_ble.setDeviceName(DEVICE_NAME);
Daniel Veilleux 0:442c7a6f1978 158 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 159 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 160 }
Daniel Veilleux 0:442c7a6f1978 161
Daniel Veilleux 0:442c7a6f1978 162 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
Daniel Veilleux 0:442c7a6f1978 163 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 164 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 165 }
Daniel Veilleux 0:442c7a6f1978 166
Daniel Veilleux 0:442c7a6f1978 167 m_ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
Daniel Veilleux 0:442c7a6f1978 168
Daniel Veilleux 0:442c7a6f1978 169 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
Daniel Veilleux 0:442c7a6f1978 170 (const uint8_t *)SHORT_NAME,
Daniel Veilleux 0:442c7a6f1978 171 (sizeof(SHORT_NAME) - 1));
Daniel Veilleux 0:442c7a6f1978 172 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 173 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 174 }
Daniel Veilleux 0:442c7a6f1978 175
Daniel Veilleux 0:442c7a6f1978 176 err = m_ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
Daniel Veilleux 0:442c7a6f1978 177 (const uint8_t *)UARTServiceUUID_reversed,
Daniel Veilleux 0:442c7a6f1978 178 sizeof(UARTServiceUUID_reversed));
Daniel Veilleux 0:442c7a6f1978 179 if (BLE_ERROR_NONE != err) {
Daniel Veilleux 0:442c7a6f1978 180 error(err, __LINE__);
Daniel Veilleux 0:442c7a6f1978 181 }
Daniel Veilleux 0:442c7a6f1978 182
Daniel Veilleux 0:442c7a6f1978 183 m_ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(ADV_INTERVAL_MS));
Daniel Veilleux 0:442c7a6f1978 184 m_ble.startAdvertising();
Daniel Veilleux 0:442c7a6f1978 185
Daniel Veilleux 0:442c7a6f1978 186 // Create a UARTService object (GATT stuff).
Daniel Veilleux 0:442c7a6f1978 187 UARTService uartService(m_ble);
Daniel Veilleux 0:442c7a6f1978 188 m_uart_service_ptr = &uartService;
Daniel Veilleux 0:442c7a6f1978 189
Daniel Veilleux 0:442c7a6f1978 190 while (true) {
Daniel Veilleux 0:442c7a6f1978 191 m_ble.waitForEvent();
Daniel Veilleux 0:442c7a6f1978 192 }
Daniel Veilleux 0:442c7a6f1978 193 }