aboutsummaryrefslogtreecommitdiffstats
path: root/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2019-02-28 17:04:22 -0500
committerClyne Sullivan <tullivan99@gmail.com>2019-02-28 17:04:22 -0500
commitd6869d1ec4bd24cd2c3eafa534f0849b25ec5607 (patch)
tree79e54ed27b39c31864895535d11399708d5a45c0 /arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm
parent614ee97bf3a2270c413527a7f35c54cbecd9e601 (diff)
added basic code
Diffstat (limited to 'arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm')
-rwxr-xr-xarduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.cpp106
-rwxr-xr-xarduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.h89
-rwxr-xr-xarduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino219
3 files changed, 414 insertions, 0 deletions
diff --git a/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.cpp b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.cpp
new file mode 100755
index 0000000..6b372bd
--- /dev/null
+++ b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.cpp
@@ -0,0 +1,106 @@
+/**************************************************************************/
+/*!
+ @file IEEE11073float.h
+*/
+/**************************************************************************/
+
+/**
+ * \file bytelib.c
+ * \brief Byte manipulation module implementation.
+ * Copyright (C) 2010 Signove Tecnologia Corporation.
+ * All rights reserved.
+ * Contact: Signove Tecnologia Corporation (contact@signove.com)
+ *
+ * $LICENSE_TEXT:BEGIN$
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation and appearing
+ * in the file LICENSE included in the packaging of this file; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * $LICENSE_TEXT:END$
+ *
+ * \author Walter Guerra, Mateus Lima
+ * \date Jun 14, 2010
+ */
+
+#include <Arduino.h>
+#include "IEEE11073float.h"
+
+uint32_t float2IEEE11073(double data, uint8_t output[4])
+{
+ uint32_t result = MDER_NaN;
+
+
+ if (isnan(data)) {
+ goto finally;
+ }/* else if (data > MDER_FLOAT_MAX) {
+ result = MDER_POSITIVE_INFINITY;
+ goto finally;
+ } else if (data < MDER_FLOAT_MIN) {
+ result = MDER_NEGATIVE_INFINITY;
+ goto finally;
+ } else if (data >= -MDER_FLOAT_EPSILON &&
+ data <= MDER_FLOAT_EPSILON) {
+ result = 0;
+ goto finally;
+ }*/
+
+ double sgn; sgn = data > 0 ? +1 : -1;
+ double mantissa; mantissa = fabs(data);
+ int32_t exponent; exponent = 0; // Note: 10**x exponent, not 2**x
+
+ // scale up if number is too big
+ while (mantissa > MDER_FLOAT_MANTISSA_MAX) {
+ mantissa /= 10.0;
+ ++exponent;
+ if (exponent > MDER_FLOAT_EXPONENT_MAX) {
+ // argh, should not happen
+ if (sgn > 0) {
+ result = MDER_POSITIVE_INFINITY;
+ } else {
+ result = MDER_NEGATIVE_INFINITY;
+ }
+ goto finally;
+ }
+ }
+
+ // scale down if number is too small
+ while (mantissa < 1) {
+ mantissa *= 10;
+ --exponent;
+ if (exponent < MDER_FLOAT_EXPONENT_MIN) {
+ // argh, should not happen
+ result = 0;
+ goto finally;
+ }
+ }
+
+ // scale down if number needs more precision
+ double smantissa; smantissa = round(mantissa * MDER_FLOAT_PRECISION);
+ double rmantissa; rmantissa = round(mantissa) * MDER_FLOAT_PRECISION;
+ double mdiff; mdiff = abs(smantissa - rmantissa);
+ while (mdiff > 0.5 && exponent > MDER_FLOAT_EXPONENT_MIN &&
+ (mantissa * 10) <= MDER_FLOAT_MANTISSA_MAX) {
+ mantissa *= 10;
+ --exponent;
+ smantissa = round(mantissa * MDER_FLOAT_PRECISION);
+ rmantissa = round(mantissa) * MDER_FLOAT_PRECISION;
+ mdiff = abs(smantissa - rmantissa);
+ }
+
+ uint32_t int_mantissa; int_mantissa = (int) round(sgn * mantissa);
+ result = (exponent << 24) | (int_mantissa & 0xFFFFFF);
+
+finally:
+ if ( output ) memcpy(output, &result, 4);
+ return result;
+}
diff --git a/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.h b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.h
new file mode 100755
index 0000000..b5dec8f
--- /dev/null
+++ b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/IEEE11073float.h
@@ -0,0 +1,89 @@
+/**************************************************************************/
+/*!
+ @file IEEE11073float.h
+*/
+/**************************************************************************/
+
+/**
+ * \file bytelib.c
+ * \brief Byte manipulation module implementation.
+ * Copyright (C) 2010 Signove Tecnologia Corporation.
+ * All rights reserved.
+ * Contact: Signove Tecnologia Corporation (contact@signove.com)
+ *
+ * $LICENSE_TEXT:BEGIN$
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation and appearing
+ * in the file LICENSE included in the packaging of this file; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * $LICENSE_TEXT:END$
+ *
+ * \author Walter Guerra, Mateus Lima
+ * \date Jun 14, 2010
+ */
+
+#ifndef _IEEE11073FLOAT_H_
+#define _IEEE11073FLOAT_H_
+
+#include <stdint.h>
+
+typedef enum {
+ MDER_POSITIVE_INFINITY = 0x007FFFFE,
+ MDER_NaN = 0x007FFFFF,
+ MDER_NRes = 0x00800000,
+ MDER_RESERVED_VALUE = 0x00800001,
+ MDER_NEGATIVE_INFINITY = 0x00800002
+} ReservedFloatValues;
+static const int32_t FIRST_RESERVED_VALUE = MDER_POSITIVE_INFINITY;
+
+// (2 ** 23 - 3)
+#define MDER_FLOAT_MANTISSA_MAX 0x007FFFFD
+// 2 ** 7 - 1
+#define MDER_FLOAT_EXPONENT_MAX 127
+#define MDER_FLOAT_EXPONENT_MIN -128
+// (2 ** 23 - 3) * 10 ** 127
+#define MDER_FLOAT_MAX 8.388604999999999e+133
+// -(2 ** 23 - 3) * 10 ** 127
+#define MDER_FLOAT_MIN (-MDER_FLOAT_MAX)
+// 10 ** -128
+#define MDER_FLOAT_EPSILON 1e-128
+// 10 ** upper(23 * log(2) / log(10))
+// precision for a number 1.0000xxx
+#define MDER_FLOAT_PRECISION 10000000
+
+typedef enum {
+ MDER_S_POSITIVE_INFINITY = 0x07FE,
+ MDER_S_NaN = 0x07FF,
+ MDER_S_NRes = 0x0800,
+ MDER_S_RESERVED_VALUE = 0x0801,
+ MDER_S_NEGATIVE_INFINITY = 0x0802
+} ReservedSFloatValues;
+static const uint32_t FIRST_S_RESERVED_VALUE = MDER_S_POSITIVE_INFINITY;
+
+// (2 ** 11 - 3)
+#define MDER_SFLOAT_MANTISSA_MAX 0x07FD
+// 2 ** 3 - 1
+#define MDER_SFLOAT_EXPONENT_MAX 7
+#define MDER_SFLOAT_EXPONENT_MIN -8
+// (2 ** 11 - 3) * 10 ** 7
+#define MDER_SFLOAT_MAX 20450000000.0
+// -(2 ** 11 - 3) * 10 ** 7
+#define MDER_SFLOAT_MIN (-MDER_SFLOAT_MAX)
+// 10 ** -8
+#define MDER_SFLOAT_EPSILON 1e-8
+// 10 ** upper(11 * log(2) / log(10))
+#define MDER_SFLOAT_PRECISION 10000
+
+uint32_t float2IEEE11073(double data, uint8_t output[4]);
+
+#endif /* _IEEE11073FLOAT_H_ */
diff --git a/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino
new file mode 100755
index 0000000..ba360fc
--- /dev/null
+++ b/arduino/libraries/Bluefruit52Lib/examples/Peripheral/custom_htm/custom_htm.ino
@@ -0,0 +1,219 @@
+/*********************************************************************
+ This is an example for our nRF52 based Bluefruit LE modules
+
+ Pick one up today in the adafruit shop!
+
+ Adafruit invests time and resources providing this open source code,
+ please support Adafruit and open-source hardware by purchasing
+ products from Adafruit!
+
+ MIT license, check LICENSE for more information
+ All text above, and the splash screen below must be included in
+ any redistribution
+*********************************************************************/
+#include <bluefruit.h>
+#include "IEEE11073float.h"
+
+/* Health Thermometer Service Definitions
+ * Health Thermometer Service: 0x1809
+ * Temperature Measurement Char: 0x2A1C
+ */
+BLEService htms = BLEService(UUID16_SVC_HEALTH_THERMOMETER);
+BLECharacteristic htmc = BLECharacteristic(UUID16_CHR_TEMPERATURE_MEASUREMENT);
+
+BLEDis bledis; // DIS (Device Information Service) helper class instance
+
+double tempvalue = 0;
+
+// Advanced function prototypes
+void startAdv(void);
+void setupHTM(void);
+void connect_callback(uint16_t conn_handle);
+void disconnect_callback(uint16_t conn_handle, uint8_t reason);
+
+void setup()
+{
+ Serial.begin(115200);
+ while ( !Serial ) delay(10); // for nrf52840 with native usb
+
+ Serial.println("Bluefruit52 Heath Thermometer Example");
+ Serial.println("-------------------------------------\n");
+
+ // Initialise the Bluefruit module
+ Serial.println("Initialise the Bluefruit nRF52 module");
+ Bluefruit.begin();
+ Bluefruit.setName("Bluefruit52");
+
+ // Set the connect/disconnect callback handlers
+ Bluefruit.setConnectCallback(connect_callback);
+ Bluefruit.setDisconnectCallback(disconnect_callback);
+
+ // Configure and Start the Device Information Service
+ Serial.println("Configuring the Device Information Service");
+ bledis.setManufacturer("Adafruit Industries");
+ bledis.setModel("Bluefruit Feather52");
+ bledis.begin();;
+
+ // Setup the Heath Thermometer service using
+ // BLEService and BLECharacteristic classes
+ Serial.println("Configuring the Heath Thermometer Service");
+ setupHTM();
+
+ // Setup the advertising packet(s)
+ Serial.println("Setting up the advertising payload(s)");
+ startAdv();
+
+ Serial.println("Ready Player One!!!");
+ Serial.println("\nAdvertising");
+}
+
+void startAdv(void)
+{
+ // Advertising packet
+ Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
+ Bluefruit.Advertising.addTxPower();
+
+ // Include HTM Service UUID
+ Bluefruit.Advertising.addService(htms);
+
+ // Include Name
+ Bluefruit.Advertising.addName();
+
+ /* Start Advertising
+ * - Enable auto advertising if disconnected
+ * - Interval: fast mode = 20 ms, slow mode = 152.5 ms
+ * - Timeout for fast mode is 30 seconds
+ * - Start(timeout) with timeout = 0 will advertise forever (until connected)
+ *
+ * For recommended advertising interval
+ * https://developer.apple.com/library/content/qa/qa1931/_index.html
+ */
+ Bluefruit.Advertising.restartOnDisconnect(true);
+ Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
+ Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
+ Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
+}
+
+void setupHTM(void)
+{
+ // Configure the Health Thermometer service
+ // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.health_thermometer.xml
+ // Supported Characteristics:
+ // Name UUID Requirement Properties
+ // ---------------------------- ------ ----------- ----------
+ // Temperature Measurement 0x2A1C Mandatory Indicate
+ //
+ // Temperature Type 0x2A1D Optional Read <-- Not used here
+ // Intermediate Temperature 0x2A1E Optional Read, Notify <-- Not used here
+ // Measurement Interval 0x2A21 Optional Read, Write, Indicate <-- Not used here
+ htms.begin();
+
+ // Note: You must call .begin() on the BLEService before calling .begin() on
+ // any characteristic(s) within that service definition.. Calling .begin() on
+ // a BLECharacteristic will cause it to be added to the last BLEService that
+ // was 'begin()'ed!
+
+ // Configure the Temperature Measurement characteristic
+ // See:https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.temperature_measurement.xml
+ // Properties = Indicte
+ // Min Len = 6
+ // Max Len = 6
+ // B0 = UINT8 - Flag (MANDATORY)
+ // b3:7 = Reserved
+ // b2 = Temperature Type Flag (0 = Not present, 1 = Present)
+ // b1 = Timestamp Flag (0 = Not present, 1 = Present)
+ // b0 = Unit Flag (0 = Celsius, 1 = Fahrenheit)
+ // B4:1 = FLOAT - IEEE-11073 32-bit FLOAT measurement value
+ // B5 = Temperature Type
+ htmc.setProperties(CHR_PROPS_INDICATE);
+ htmc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
+ htmc.setFixedLen(6);
+ htmc.setCccdWriteCallback(cccd_callback); // Optionally capture CCCD updates
+ htmc.begin();
+ uint8_t htmdata[6] = { 0b00000101, 0, 0 ,0 ,0, 2 }; // Set the characteristic to use Fahrenheit, with type (body) but no timestamp field
+ htmc.write(htmdata, sizeof(htmdata)); // Use .write for init data
+
+ // Temperature Type Value
+ // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.temperature_type.xml
+ // B0 = UINT8 - Temperature Type
+ // 0 = Reserved
+ // 1 = Armpit
+ // 2 = Body (general)
+ // 3 = Ear (usually ear lobe)
+ // 4 = Finger
+ // 5 = Gastro-intestinal Tract
+ // 6 = Mouth
+ // 7 = Rectum
+ // 8 = Toe
+ // 9 = Tympanum (ear drum)
+ // 10:255 = Reserved
+}
+
+void connect_callback(uint16_t conn_handle)
+{
+ char central_name[32] = { 0 };
+ Bluefruit.Gap.getPeerName(conn_handle, central_name, sizeof(central_name));
+
+ Serial.print("Connected to ");
+ Serial.println(central_name);
+}
+
+/**
+ * Callback invoked when a connection is dropped
+ * @param conn_handle connection where this event happens
+ * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
+ * https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/cores/nRF5/nordic/softdevice/s140_nrf52_6.1.1_API/include/ble_hci.h
+ */
+void disconnect_callback(uint16_t conn_handle, uint8_t reason)
+{
+ (void) conn_handle;
+ (void) reason;
+
+ Serial.println("Disconnected");
+ Serial.println("Advertising!");
+}
+
+void cccd_callback(BLECharacteristic& chr, uint16_t cccd_value)
+{
+ // Display the raw request packet
+ Serial.print("CCCD Updated: ");
+ //Serial.printBuffer(request->data, request->len);
+ Serial.print(cccd_value);
+ Serial.println("");
+
+ // Check the characteristic this CCCD update is associated with in case
+ // this handler is used for multiple CCCD records.
+ if (chr.uuid == htmc.uuid) {
+ if (chr.indicateEnabled()) {
+ Serial.println("Temperature Measurement 'Indicate' enabled");
+ } else {
+ Serial.println("Temperature Measurement 'Indicate' disabled");
+ }
+ }
+}
+
+void loop()
+{
+ digitalToggle(LED_RED);
+
+ if ( Bluefruit.connected() ) {
+ uint8_t htmdata[6] = { 0b00000101, 0,0,0,0, 2 }; // Fahrenheit unit, temperature type = body (2)
+
+ float2IEEE11073(tempvalue, &htmdata[1]);
+
+ // Note: We use .indicate instead of .write!
+ // If it is connected but CCCD is not enabled
+ // The characteristic's value is still updated although notification is not sent
+ if ( htmc.indicate(htmdata, sizeof(htmdata)) ){
+ Serial.print("Temperature Measurement updated to: "); Serial.println(tempvalue);
+ }else{
+ Serial.println("ERROR: Indicate not set in the CCCD or not connected!");
+ }
+
+ tempvalue += 0.5F;
+ }
+
+ // Only send update once per second
+ delay(1000);
+}
+