From eea868ab5ffb925eadca66b25ff96cdaae5b0111 Mon Sep 17 00:00:00 2001 From: Nedim Hadzic Date: Thu, 30 Jan 2014 23:04:20 +0100 Subject: Heart Listener example added Bluetooth Low Energy example for connecting and receiving measurements from the heart belt. Documentation added too. [ChangeLog][QtBluetooth] Heart Listener Bluetooth Low Energy heart belt example has been added Change-Id: I1b690827af85411c962eb09aa87936f1fb7d9246 Reviewed-by: Alex Blasche --- examples/bluetooth/bluetooth.pro | 3 +- examples/bluetooth/heartlistener/assets/Button.qml | 77 ++++ examples/bluetooth/heartlistener/assets/Point.qml | 51 +++ .../bluetooth/heartlistener/assets/blue_heart.png | Bin 0 -> 7283 bytes .../heartlistener/assets/blue_heart_small.png | Bin 0 -> 250 bytes .../bluetooth/heartlistener/assets/busy_dark.png | Bin 0 -> 1130 bytes examples/bluetooth/heartlistener/assets/dialog.qml | 61 ++++ examples/bluetooth/heartlistener/assets/draw.js | 74 ++++ examples/bluetooth/heartlistener/assets/home.qml | 186 ++++++++++ examples/bluetooth/heartlistener/assets/main.qml | 84 +++++ .../bluetooth/heartlistener/assets/monitor.qml | 154 ++++++++ .../bluetooth/heartlistener/assets/results.qml | 290 +++++++++++++++ examples/bluetooth/heartlistener/assets/star.png | Bin 0 -> 262 bytes examples/bluetooth/heartlistener/deviceinfo.cpp | 57 +++ examples/bluetooth/heartlistener/deviceinfo.h | 68 ++++ .../heartlistener/doc/images/hearratemonitor.png | Bin 0 -> 46437 bytes .../heartlistener/doc/images/hearrateresults.png | Bin 0 -> 38983 bytes .../heartlistener/doc/images/hearrateresults1.png | Bin 0 -> 42472 bytes .../heartlistener/doc/images/heartrateintro.png | Bin 0 -> 21538 bytes .../heartlistener/doc/src/heartlistener.qdoc | 82 +++++ examples/bluetooth/heartlistener/heartlistener.pro | 20 ++ examples/bluetooth/heartlistener/heartrate.cpp | 397 +++++++++++++++++++++ examples/bluetooth/heartlistener/heartrate.h | 144 ++++++++ examples/bluetooth/heartlistener/main.cpp | 58 +++ examples/bluetooth/heartlistener/resources.qrc | 16 + src/bluetooth/doc/src/bluetooth-index.qdoc | 1 + src/bluetooth/doc/src/examples.qdoc | 4 + 27 files changed, 1826 insertions(+), 1 deletion(-) create mode 100644 examples/bluetooth/heartlistener/assets/Button.qml create mode 100644 examples/bluetooth/heartlistener/assets/Point.qml create mode 100644 examples/bluetooth/heartlistener/assets/blue_heart.png create mode 100644 examples/bluetooth/heartlistener/assets/blue_heart_small.png create mode 100644 examples/bluetooth/heartlistener/assets/busy_dark.png create mode 100644 examples/bluetooth/heartlistener/assets/dialog.qml create mode 100644 examples/bluetooth/heartlistener/assets/draw.js create mode 100644 examples/bluetooth/heartlistener/assets/home.qml create mode 100644 examples/bluetooth/heartlistener/assets/main.qml create mode 100644 examples/bluetooth/heartlistener/assets/monitor.qml create mode 100644 examples/bluetooth/heartlistener/assets/results.qml create mode 100644 examples/bluetooth/heartlistener/assets/star.png create mode 100644 examples/bluetooth/heartlistener/deviceinfo.cpp create mode 100644 examples/bluetooth/heartlistener/deviceinfo.h create mode 100644 examples/bluetooth/heartlistener/doc/images/hearratemonitor.png create mode 100644 examples/bluetooth/heartlistener/doc/images/hearrateresults.png create mode 100644 examples/bluetooth/heartlistener/doc/images/hearrateresults1.png create mode 100644 examples/bluetooth/heartlistener/doc/images/heartrateintro.png create mode 100644 examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc create mode 100644 examples/bluetooth/heartlistener/heartlistener.pro create mode 100644 examples/bluetooth/heartlistener/heartrate.cpp create mode 100644 examples/bluetooth/heartlistener/heartrate.h create mode 100644 examples/bluetooth/heartlistener/main.cpp create mode 100644 examples/bluetooth/heartlistener/resources.qrc diff --git a/examples/bluetooth/bluetooth.pro b/examples/bluetooth/bluetooth.pro index 78ba1fc1..f7fe9d20 100644 --- a/examples/bluetooth/bluetooth.pro +++ b/examples/bluetooth/bluetooth.pro @@ -8,4 +8,5 @@ qtHaveModule(widgets) { qtHaveModule(quick): SUBDIRS += scanner \ picturetransfer \ - lowenergyscanner + lowenergyscanner \ + heartlistener diff --git a/examples/bluetooth/heartlistener/assets/Button.qml b/examples/bluetooth/heartlistener/assets/Button.qml new file mode 100644 index 00000000..40e98875 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/Button.qml @@ -0,0 +1,77 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id:button + //color: "#3870BA" + + property real buttonWidth: 300 + property real buttonHeight: 80 + property string text: "Button" + + signal buttonClick() + width: click.pressed ? (buttonWidth - 15) : buttonWidth + height: click.pressed ? (buttonHeight - 15) :buttonHeight + + color: click.pressed ? "#3265A7" : "#3870BA" + + border.color: "#F0EBED" + border.width: 5 + radius: 10 + + Text { + id: label + font.pixelSize: 30; font.bold: true + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + anchors.fill: parent + elide: Text.ElideMiddle + color: "#F0EBED" + text: button.text + } + + MouseArea { + id: click + anchors.fill: parent + onClicked: buttonClick() + } +} diff --git a/examples/bluetooth/heartlistener/assets/Point.qml b/examples/bluetooth/heartlistener/assets/Point.qml new file mode 100644 index 00000000..2ed94a4d --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/Point.qml @@ -0,0 +1,51 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: point + + Image { + width: 10; height: 7 + smooth: true + source: "blue_heart_small.png" + } +} diff --git a/examples/bluetooth/heartlistener/assets/blue_heart.png b/examples/bluetooth/heartlistener/assets/blue_heart.png new file mode 100644 index 00000000..997ee699 Binary files /dev/null and b/examples/bluetooth/heartlistener/assets/blue_heart.png differ diff --git a/examples/bluetooth/heartlistener/assets/blue_heart_small.png b/examples/bluetooth/heartlistener/assets/blue_heart_small.png new file mode 100644 index 00000000..7bd1f981 Binary files /dev/null and b/examples/bluetooth/heartlistener/assets/blue_heart_small.png differ diff --git a/examples/bluetooth/heartlistener/assets/busy_dark.png b/examples/bluetooth/heartlistener/assets/busy_dark.png new file mode 100644 index 00000000..3a105953 Binary files /dev/null and b/examples/bluetooth/heartlistener/assets/busy_dark.png differ diff --git a/examples/bluetooth/heartlistener/assets/dialog.qml b/examples/bluetooth/heartlistener/assets/dialog.qml new file mode 100644 index 00000000..45b64cf3 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/dialog.qml @@ -0,0 +1,61 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: root + opacity: 0.8 + color: "#E0DEDF" + anchors.horizontalCenter: parent.horizontalCenter + + property int hr: heartRate.hr + Text { + text: heartRate.message + color: "#3870BA" + + } + + onHrChanged: { + if (heartRate.hr > 0) { + root.destroy() + } + } +} diff --git a/examples/bluetooth/heartlistener/assets/draw.js b/examples/bluetooth/heartlistener/assets/draw.js new file mode 100644 index 00000000..a5de5474 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/draw.js @@ -0,0 +1,74 @@ +/*************************************************************************** +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +var component; +var size = 0; +var counter = 0; +var difference = 0; + +function start() { + size = heartRate.measurementsSize(); + difference = (plot.width-topbar.width)/size; + console.log(size +" "+ plot.width); + for (var i = 0; i< size; i++) { + var value = heartRate.measurements(i); + + drawIt(value); + counter++; + } +} + +function drawIt(value) { + if (component == null) + component = Qt.createComponent("Point.qml"); + if (component.status == Component.Ready) { + var dynamicObject = component.createObject(plot); + if (dynamicObject == null) { + console.log("error creating block"); + console.log(component.errorString()); + return false; + } + dynamicObject.x = 10+(counter*difference); + console.log(plot.height) + dynamicObject.y = plot.height -value; + + } +} + diff --git a/examples/bluetooth/heartlistener/assets/home.qml b/examples/bluetooth/heartlistener/assets/home.qml new file mode 100644 index 00000000..2c5e9485 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/home.qml @@ -0,0 +1,186 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: screen + color: "#F0EBED" + property string message: heartRate.message + onMessageChanged: { + if (heartRate.message != "Scanning for devices..." && heartRate.message != "Low Energy device found. Scanning for more...") { + background.visible = false; + demoMode.visible = true; + } + else { + demoMode.visible = false; + background.visible = true; + } + } + + Rectangle { + id:select + width: parent.width + anchors.top: parent.top + height: 80 + color: "#F0EBED" + border.color: "#3870BA" + border.width: 2 + radius: 10 + + Text { + id: selectText + color: "#3870BA" + font.pixelSize: 34 + anchors.centerIn: parent + text: "Select Device" + } + } + + Rectangle { + id: spinner + width: parent.width + anchors.top: select.bottom + anchors.bottom: demoMode.top + visible: false + color: "#F0EBED" + z: 100 + + Rectangle { + id: inside + anchors.centerIn: parent + Image { + id: background + + width:100 + height:100 + anchors.horizontalCenter: parent.horizontalCenter + + source: "busy_dark.png" + fillMode: Image.PreserveAspectFit + NumberAnimation on rotation { duration: 3000; from:0; to: 360; loops: Animation.Infinite} + } + + Text { + id: infotext + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: background.bottom + text: heartRate.message + color: "#8F8F8F" + } + } + } + + Component.onCompleted: { + heartRate.deviceSearch(); + spinner.visible=true; + } + + ListView { + id: theListView + width: parent.width + onModelChanged: spinner.visible=false + anchors.top: select.bottom + anchors.bottom: demoMode.top + model: heartRate.name + + delegate: Rectangle { + id: box + height:140 + width: parent.width + color: "#3870BA" + border.color: "#F0EBED" + border.width: 5 + radius: 15 + + MouseArea { + anchors.fill: parent + onPressed: { box.color= "#3265A7"; box.height=110} + onClicked: { + heartRate.connectToService(modelData.deviceAddress); + pageLoader.source="monitor.qml"; + } + } + + Text { + id: device + font.pixelSize: 30 + text: modelData.deviceName + anchors.top: parent.top + anchors.topMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + color: "#F0EBED" + } + + Text { + id: deviceAddress + font.pixelSize: 30 + text: modelData.deviceAddress + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + color: "#F0EBED" + } + } + } + + Button { + id:demoMode + buttonWidth: parent.width + buttonHeight: 0.1*parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: scanAgain.top + text: "Run Demo" + onButtonClick: { + heartRate.startDemo(); + pageLoader.source="monitor.qml"; + } + } + + Button { + id:scanAgain + buttonWidth: parent.width + buttonHeight: 0.1*parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + text: "Menu" + onButtonClick: pageLoader.source="main.qml" + } +} diff --git a/examples/bluetooth/heartlistener/assets/main.qml b/examples/bluetooth/heartlistener/assets/main.qml new file mode 100644 index 00000000..e892eb47 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/main.qml @@ -0,0 +1,84 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 400 + height: 600 + id: begin + + Rectangle { + color: "#F0EBED" + anchors.fill: parent + Rectangle { + id: about + width: 0.75*parent.width + height: 0.1*parent.height + anchors.top: parent.top + anchors.topMargin: 20 + anchors.horizontalCenter: parent.horizontalCenter + color: "#F0EBED" + border.color: "#3870BA" + border.width: 2 + radius: 10 + Text { + id: aboutinfo + anchors.centerIn: parent + color: "#3870BA" + text: "Welcome to the Heart Listener Application" + } + } + + Button { + id:call + buttonWidth: 0.75*parent.width + buttonHeight: 0.15*parent.height + anchors.centerIn: parent + text: "Scan for Devices" + onButtonClick: pageLoader.source="home.qml" + } + } + + Loader { + id: pageLoader + anchors.fill: parent + } +} diff --git a/examples/bluetooth/heartlistener/assets/monitor.qml b/examples/bluetooth/heartlistener/assets/monitor.qml new file mode 100644 index 00000000..5dbf66c3 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/monitor.qml @@ -0,0 +1,154 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Particles 2.0 + +Rectangle { + id: screenMonitor + color: "#F0EBED" + + Button { + id:menu + buttonWidth: parent.width + buttonHeight: 0.1 * parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + text: "Menu" + onButtonClick: { + heartRate.disconnectService(); + pageLoader.source="home.qml"; + } + } + + Text { + id: hrValue + font.pointSize: 24; font.bold: true + anchors.top:menu.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 25 + + color: "#3870BA" + text: heartRate.hr + onTextChanged: { + if (heartRate.hr > 0 && updatei != null && heartRate.numDevices() > 0) { + updatei.destroy() + } + } + } + + Rectangle { + id: updatei + width: parent.width + height: 80 + anchors.bottom: stop.top + + color: "#F0EBED" + border.color: "#3870BA" + border.width: 2 + + Text { + id: logi + text: heartRate.message + anchors.centerIn: parent + color: "#3870BA" + } + } + + Image { + id: background + width: 300 + height: width + anchors.centerIn: parent + source: "blue_heart.png" + fillMode: Image.PreserveAspectFit + NumberAnimation on width { + running: heartRate.hr > 0; + duration: heartRate.hr/60*250; + from:300; to: 350; + loops: Animation.Infinite; + } + + ParticleSystem { + id: systwo + anchors.fill: parent + + ImageParticle { + system: systwo + id: cptwo + source: "star.png" + colorVariation: 0.4 + color: "#000000FF" + } + + Emitter { + //burst on click + id: burstytwo + system: systwo + enabled: true + x: 160 + y: 150 + emitRate: heartRate.hr*100 + maximumEmitted: 4000 + acceleration: AngleDirection {angleVariation: 360; magnitude: 360; } + size: 4 + endSize: 8 + sizeVariation: 4 + } + + + } + + } + + Button { + id:stop + buttonWidth: parent.width + buttonHeight: 0.1*parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + text: "Stop Monitoring" + onButtonClick: { + burstytwo.enabled = false; + heartRate.disconnectService(); + pageLoader.source = "results.qml"; + } + } +} diff --git a/examples/bluetooth/heartlistener/assets/results.qml b/examples/bluetooth/heartlistener/assets/results.qml new file mode 100644 index 00000000..78c08873 --- /dev/null +++ b/examples/bluetooth/heartlistener/assets/results.qml @@ -0,0 +1,290 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "draw.js" as DrawGraph + +Rectangle { + id: results + color: "#F0EBED" + + Component.onCompleted: heartRate.obtainResults() + + function getTime() { + var t = heartRate.time; + var min = Math.floor(t/60); + var sec = t%60; + var r = min + " min " + sec + " sec " + return r; + } + + function drawGraph() { + var b = plot.height/200; + var ctx = canvas1.getContext('2d'); + ctx.beginPath() + ctx.moveTo(10, plot.height- (b*60)) + var size = heartRate.measurementsSize(); + var difference = (plot.width-topbar.width)/size; + + for (var i = 0; i< size; i++) { + var value = heartRate.measurements(i); + if (i == 0) { + ctx.moveTo(10+2, (plot.height- (value*b) + 2)); + ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4); + + } + else { + ctx.lineTo((10+2 + i*difference), (plot.height- (value*b) + 2)); + ctx.rect((10 + i*difference), (plot.height- (value*b)), 4, 4); + } + + } + ctx.fillStyle = "#3870BA" + ctx.fill() + ctx.strokeStyle = "#3870BA" + ctx.stroke() + ctx.closePath() + } + + Rectangle { + id: res + width: parent.width + anchors.top: parent.top + height: 80 + color: "#F0EBED" + border.color: "#3870BA" + border.width: 2 + radius: 10 + Text { + id: restText + color: "#3870BA" + font.pixelSize: 34 + anchors.centerIn: parent + text: "Results" + } + } + + Text { + id: topbar + text: "200" + anchors.left: parent.left + anchors.top: res.bottom + anchors.rightMargin: 4 + color: "#3870BA" + z: 50 + } + + Rectangle { + id: level + anchors.left: topbar.right + + anchors.top: res.bottom + height: ((results.height -(res.height + menuLast.height + start.height ))/2) + width: 3 + color: "#3870BA" + } + + Text { + id: middlebar + anchors.verticalCenter: level.verticalCenter + anchors.left: parent.left + text: "100" + color: "#3870BA" + z: 50 + } + + Rectangle{ + id: downlevel + anchors.bottom: cover.top + width: parent.width + anchors.left: level.right + height: 3 + color: "#3870BA" + z: 50 + } + + Rectangle { + id: plot + anchors.left: level.right + anchors.leftMargin: 15 + width: results.width + height: ((parent.height-(res.height+menuLast.height+start.height))/2) + + anchors.top: res.bottom + color: "#F0EBED" + Canvas { + id: canvas1 + anchors.fill: parent + z: 150 + onPaint: drawGraph() + } + } + + Rectangle { + id: cover + anchors.top: plot.bottom + anchors.bottom: menuLast.top + width: parent.width + height: ((parent.height-(res.height+menuLast.height+start.height))/2) + color: "#F0EBED" + radius: 10 + border.color: "#3870BA" + border.width: 2 + + Flickable { + id: scroll + anchors.fill: parent + anchors.margins: 5 + clip: true + contentWidth: parent.width + contentHeight: stresult.height + + Rectangle { + id: stresult + width: parent.width + height: (results.height - (res.height + menuLast.height + start.height - 100)) + color: "#F0EBED" + radius: 10 + + Text { + id: averageHR + font.pixelSize: 30; + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + + color: "#3870BA" + text: "Average Heart Rate" + } + + Text { + id: averageHRt + font.pixelSize: 40; font.bold: true + anchors.top: averageHR.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: heartRate.average + } + + Text { + id: time + font.pixelSize: 30; + anchors.top: averageHRt.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: "Seconds measured " + } + + Text { + id: timet + font.pixelSize: 40; font.bold: true + anchors.top: time.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: getTime() + } + Text { + id: maxi + font.pixelSize: 30; + anchors.top: timet.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: " Max || Min " + } + + Text { + id: mini + font.pixelSize: 40; font.bold: true + anchors.top:maxi.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: " " + heartRate.maxHR + " || " + heartRate.minHR + } + + Text { + id: calories + font.pixelSize: 30; + anchors.top: mini.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: " Calories " + } + + Text { + id: caloriestext + font.pixelSize: 40; font.bold: true + anchors.top:calories.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.topMargin: 20 + color: "#3870BA" + text: Math.floor(heartRate.calories) + } + } + } + } + + Button { + id:menuLast + buttonWidth: parent.width + buttonHeight: 0.1*parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: start.top + text: "Menu" + onButtonClick: { pageLoader.source="main.qml"} + } + + Button { + id:start + buttonWidth: parent.width + buttonHeight: 0.1*parent.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + text: "Start Monitoring" + onButtonClick: { + heartRate.connectToService(heartRate.deviceAddress()); + pageLoader.source="monitor.qml"; + } + } +} diff --git a/examples/bluetooth/heartlistener/assets/star.png b/examples/bluetooth/heartlistener/assets/star.png new file mode 100644 index 00000000..defbde53 Binary files /dev/null and b/examples/bluetooth/heartlistener/assets/star.png differ diff --git a/examples/bluetooth/heartlistener/deviceinfo.cpp b/examples/bluetooth/heartlistener/deviceinfo.cpp new file mode 100644 index 00000000..656d6126 --- /dev/null +++ b/examples/bluetooth/heartlistener/deviceinfo.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "deviceinfo.h" + +DeviceInfo::DeviceInfo(const QBluetoothDeviceInfo &device): + m_device(device) +{ + Q_EMIT deviceChanged(); +} + +QBluetoothDeviceInfo DeviceInfo::getDevice() +{ + return m_device; +} + +void DeviceInfo::setDevice(const QBluetoothDeviceInfo &device) +{ + m_device = device; +} diff --git a/examples/bluetooth/heartlistener/deviceinfo.h b/examples/bluetooth/heartlistener/deviceinfo.h new file mode 100644 index 00000000..94b0db80 --- /dev/null +++ b/examples/bluetooth/heartlistener/deviceinfo.h @@ -0,0 +1,68 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DEVICEINFO_H +#define DEVICEINFO_H + +#include +#include +#include +#include + +class DeviceInfo: public QObject +{ + Q_OBJECT + Q_PROPERTY(QString deviceName READ getName NOTIFY deviceChanged) + Q_PROPERTY(QString deviceAddress READ getAddress NOTIFY deviceChanged) +public: + DeviceInfo(const QBluetoothDeviceInfo &device); + void setDevice(const QBluetoothDeviceInfo &device); + QString getName() { return m_device.name(); } + QString getAddress() { return m_device.address().toString(); } + QBluetoothDeviceInfo getDevice(); + +signals: + void deviceChanged(); + +private: + QBluetoothDeviceInfo m_device; +}; + +#endif // DEVICEINFO_H diff --git a/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png b/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png new file mode 100644 index 00000000..ed51ba86 Binary files /dev/null and b/examples/bluetooth/heartlistener/doc/images/hearratemonitor.png differ diff --git a/examples/bluetooth/heartlistener/doc/images/hearrateresults.png b/examples/bluetooth/heartlistener/doc/images/hearrateresults.png new file mode 100644 index 00000000..2c961517 Binary files /dev/null and b/examples/bluetooth/heartlistener/doc/images/hearrateresults.png differ diff --git a/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png b/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png new file mode 100644 index 00000000..7af63b57 Binary files /dev/null and b/examples/bluetooth/heartlistener/doc/images/hearrateresults1.png differ diff --git a/examples/bluetooth/heartlistener/doc/images/heartrateintro.png b/examples/bluetooth/heartlistener/doc/images/heartrateintro.png new file mode 100644 index 00000000..fb0a7b34 Binary files /dev/null and b/examples/bluetooth/heartlistener/doc/images/heartrateintro.png differ diff --git a/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc new file mode 100644 index 00000000..fa63714a --- /dev/null +++ b/examples/bluetooth/heartlistener/doc/src/heartlistener.qdoc @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example heartlistener + \title Bluetooth Low Energy Heart Listener example + + The Bluetooth Low Energy (BLE) Heart Listener Example shows how to develop a Bluetooth + Low Energy applications using the Qt Bluetooth API. The application covers + the scanning for BLE devices, connecting to the BLE Heart Rate service and + receiving updates from the BLE heart belt. The BLE heart belt is required + for this application to work. + + \image heartrateintro.png + + The best and the safest approach is to do a service discovery for BLE device first and + then pick the heart rate service. Before that it is necessary to connect signals from + the QLowEnergyController class, which is responsible for the communication with the + BLE device. + + \snippet heartlistener/heartrate.cpp Connect signals + + After service scan is done and heart rate service found, the heart rate measurement + characteristic needs to be found and enabled for the notifications (advertisements). + + \snippet heartlistener/heartrate.cpp Connecting to service + + The enableNotifications(m_heartRateCharacteristic) method is the one that + will enable advertisement from the BLE device. Every time, when new update gets from + the BLE device (in our case heart rate belt) QLowEnergyController will emit + valueChanged(QLowEnergyCharacteristicInfo) method, which will invoke + receiveMeasurement(const QLowEnergyCharacteristicInfo &) slot. + + \snippet heartlistener/heartrate.cpp Reading value + + Every BLE device has its own structure of data that is advertising. In the code above, + the approach for checking the value structure is presented. The heart rate service contains + that information in the first 8 bits of the advertised value. For instance, first bit tells + the format of the value (is it 8 or 16 bit value), fourth tells does the heart belt provide + energy spenditure information, etc. + + \snippet heartlistener/heartrate.cpp Error handling + + In case an error occurs, QLowEnergyController will emit error, which can be read with + errorString() method. An error for BLE service can occur in the process of connecting to + the service. For BLE characteristics, an error can occur when trying to subscribe for the + notifications. + + In the end, it is required to disconnect from the service. + + \snippet heartlistener/heartrate.cpp Disconnecting from service + + \image hearratemonitor.png + \image hearrateresults.png + \image hearrateresults1.png + +*/ + diff --git a/examples/bluetooth/heartlistener/heartlistener.pro b/examples/bluetooth/heartlistener/heartlistener.pro new file mode 100644 index 00000000..7856b64e --- /dev/null +++ b/examples/bluetooth/heartlistener/heartlistener.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = heartlistener + +QT += quick bluetooth + +# Input +HEADERS += deviceinfo.h \ + heartrate.h +SOURCES += deviceinfo.cpp \ + heartrate.cpp \ + main.cpp + +OTHER_FILES += assets/*.qml \ + assets/*.js + +RESOURCES += \ + resources.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/heartlistener +INSTALLS += target diff --git a/examples/bluetooth/heartlistener/heartrate.cpp b/examples/bluetooth/heartlistener/heartrate.cpp new file mode 100644 index 00000000..a80f0c0c --- /dev/null +++ b/examples/bluetooth/heartlistener/heartrate.cpp @@ -0,0 +1,397 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "heartrate.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +HeartRate::HeartRate(): + m_currentDevice(QBluetoothDeviceInfo()), foundHeartRateService(false), foundHeartRateCharacteristic(false), m_HRMeasurement(0), m_max(0), m_min(0), calories(0), m_leInfo(0), timer(0) +{ + m_deviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(); + m_serviceDiscoveryAgent = new QBluetoothServiceDiscoveryAgent(QBluetoothAddress()); + + connect(m_deviceDiscoveryAgent, SIGNAL(deviceDiscovered(const QBluetoothDeviceInfo&)), + this, SLOT(addDevice(const QBluetoothDeviceInfo&))); + connect(m_deviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)), + this, SLOT(deviceScanError(QBluetoothDeviceDiscoveryAgent::Error))); + connect(m_deviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(scanFinished())); + + connect(m_serviceDiscoveryAgent, SIGNAL(serviceDiscovered(const QLowEnergyServiceInfo&)), + this, SLOT(addLowEnergyService(const QLowEnergyServiceInfo&))); + connect(m_serviceDiscoveryAgent, SIGNAL(finished()), this, SLOT(serviceScanDone())); + connect(m_serviceDiscoveryAgent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)), + this, SLOT(serviceScanError(QBluetoothServiceDiscoveryAgent::Error))); +} + +HeartRate::~HeartRate() +{ + delete m_deviceDiscoveryAgent; + delete m_serviceDiscoveryAgent; + delete m_leInfo; + delete timer; + qDeleteAll(m_devices); + m_devices.clear(); +} + +void HeartRate::deviceSearch() +{ + m_devices.clear(); + m_deviceDiscoveryAgent->start(); + setMessage("Scanning for devices..."); +} + +void HeartRate::addDevice(const QBluetoothDeviceInfo &device) +{ + if (device.coreConfiguration() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { + QBluetoothLocalDevice localDevice; + QBluetoothLocalDevice::Pairing pairingStatus = localDevice.pairingStatus(device.address()); + if (pairingStatus == QBluetoothLocalDevice::Paired || pairingStatus == QBluetoothLocalDevice::AuthorizedPaired ) + qWarning() << "Discovered LE Device name: " << device.name() << " Address: " << device.address().toString() << " Paired"; + else + qWarning() << "Discovered LE Device name: " << device.name() << " Address: " << device.address().toString() << " not Paired"; + DeviceInfo *dev = new DeviceInfo(device); + m_devices.append(dev); + setMessage("Low Energy device found. Scanning for more..."); + } +} + +void HeartRate::scanFinished() +{ + if (m_devices.size() == 0) + setMessage("No Low Energy devices found"); + Q_EMIT nameChanged(); +} + +void HeartRate::setMessage(QString message) +{ + m_info = message; + Q_EMIT messageChanged(); +} + +QString HeartRate::message() const +{ + return m_info; +} + +QVariant HeartRate::name() +{ + return QVariant::fromValue(m_devices); +} + +void HeartRate::connectToService(const QString &address) +{ + bool deviceHere = false; + for (int i = 0; igetAddress() == address ) { + m_currentDevice.setDevice(((DeviceInfo*)m_devices.at(i))->getDevice()); + setMessage("Device selected."); + deviceHere = true; + } + } + // This in case we are running demo mode + if (!deviceHere) + startDemo(); + else { + QBluetoothDeviceInfo device = m_currentDevice.getDevice(); + //! [Connect signals] + m_serviceDiscoveryAgent->setRemoteAddress(device.address()); + m_serviceDiscoveryAgent->start(); + if (!m_leInfo) { + m_leInfo = new QLowEnergyController(); + connect(m_leInfo, SIGNAL(connected(QLowEnergyServiceInfo)), this, SLOT(serviceConnected(QLowEnergyServiceInfo))); + connect(m_leInfo, SIGNAL(disconnected(QLowEnergyServiceInfo)), this, SLOT(serviceDisconnected(QLowEnergyServiceInfo))); + connect(m_leInfo, SIGNAL(error(QLowEnergyServiceInfo)), this, SLOT(errorReceived(QLowEnergyServiceInfo))); + connect(m_leInfo, SIGNAL(error(QLowEnergyCharacteristicInfo)), this, SLOT(errorReceivedCharacteristic(QLowEnergyCharacteristicInfo))); + connect(m_leInfo, SIGNAL(valueChanged(QLowEnergyCharacteristicInfo)), this, SLOT(receiveMeasurement(QLowEnergyCharacteristicInfo))); + } + //! [Connect signals] + } +} + +void HeartRate::addLowEnergyService(const QLowEnergyServiceInfo &gatt) +{ + if (gatt.uuid() == QBluetoothUuid::HeartRate) { + setMessage("Heart Rate service discovered. Waiting for service scan to be done..."); + m_heartRateService = QLowEnergyServiceInfo(gatt); + foundHeartRateService = true; + } +} + +//! [Connecting to service] +void HeartRate::serviceScanDone() +{ + //If HeartBelt is not connected (installed on the body) this message will stay. + setMessage("Connecting to service... Be patient..."); + //It is not advisable to connect to BLE device right after scanning. + if (foundHeartRateService) + QTimer::singleShot(3000, this, SLOT(startConnection())); + else + setMessage("Heart Rate Service not found. Make sure your device is paired."); +} + +void HeartRate::startConnection() +{ + // HeartRate belt that this application was using had a random device address. This is only needed + // for Linux platform. + // m_heartRateService.setRandomAddress(); + m_leInfo->connectToService(m_heartRateService); +} + +void HeartRate::serviceConnected(const QLowEnergyServiceInfo &leService) +{ + setMessage("Connected to service. Waiting for updates"); + if (leService.uuid() == QBluetoothUuid::HeartRate) { + for ( int i = 0; ienableNotifications(m_heartRateCharacteristic); + foundHeartRateCharacteristic = true; + } + } + } +} +//! [Connecting to service] + +void HeartRate::receiveMeasurement(const QLowEnergyCharacteristicInfo &characteristic) +{ + m_heartRateCharacteristic = QLowEnergyCharacteristicInfo(characteristic); + //! [Reading value] + QString val; + qint16 energy_expended = 0; + int flags = 0; + int index = 0; + val[0] = m_heartRateCharacteristic.value().at(index++); + // Each Heart Belt has its own settings and fetarues, besides heart rate measurement + // By checking the flags we can determine whether it has energy feature. We will go through the array + // of the characters in the characteristic value. + if (val.toUInt(0, 16) > 3) + flags = val.toUInt(0, 16); + else { + val[1] = m_heartRateCharacteristic.value().at(index++); + flags = val.toUInt(0, 16); + } + QString value; + value[0] = m_heartRateCharacteristic.value().at(index++); + value[1] = m_heartRateCharacteristic.value().at(index++); + m_HRMeasurement = value.toUInt(0, 16); + //! [Reading value] + m_measurements.append(m_HRMeasurement); + // The following flags are used to determine what kind of value is being sent from the device. + // FLAGS field bit mask values + qint8 heartRateValueFormat = 1;// 0 + qint8 energyExpendedFeature = 8;// 3 + bool hrDataFormat = false; + bool energyExpendedFeatureSupported = false; + + hrDataFormat = ((flags & heartRateValueFormat) != heartRateValueFormat); // 0 means 8 bit, 1 means 16 bit + energyExpendedFeatureSupported = ((flags & energyExpendedFeature) == 0); + if (!hrDataFormat) + qWarning() << "XXXX 16 bit heart rate measurement data encountered!"; + if (energyExpendedFeatureSupported) { + QString energy; + int counter1 = 0; + for (int i = index; i < (m_heartRateCharacteristic.value().size() - 1); i++) { + if (counter1 > 3) + break; + energy[i] = m_heartRateCharacteristic.value().at(i); + counter1 ++; + } + energy_expended = energy.toUInt(0, 16); + index = index + 2; + } + qWarning() << "Used energy: " << energy_expended; + Q_EMIT hrChanged(); +} + +int HeartRate::hR() const +{ + return m_HRMeasurement; +} + +//! [Error handling] +void HeartRate::errorReceived(const QLowEnergyServiceInfo &leService) +{ + setMessage(QStringLiteral("Error: ") + leService.errorString()); +} + +void HeartRate::errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &leCharacteristic) +{ + setMessage(QStringLiteral("Error: ") + leCharacteristic.errorString()); +} +//! [Error handling] + +void HeartRate::disconnectService() +{ + if (foundHeartRateCharacteristic) { + m_stop = QDateTime::currentDateTime(); + //! [Disconnecting from service] + m_leInfo->disableNotifications(m_heartRateCharacteristic); + m_leInfo->disconnectFromService(); + //! [Disconnecting from service] + } + else if (m_devices.size() == 0) { + m_stop = QDateTime::currentDateTime(); + timer->stop(); + timer = 0; + } + foundHeartRateCharacteristic = false; + foundHeartRateService = false; +} + +void HeartRate::obtainResults() +{ + Q_EMIT timeChanged(); + Q_EMIT averageChanged(); + Q_EMIT caloriesChanged(); +} + +int HeartRate::time() +{ + return m_start.secsTo(m_stop); +} + +int HeartRate::maxHR() const +{ + return m_max; +} + +int HeartRate::minHR() const +{ + return m_min; +} + +float HeartRate::average() +{ + if (m_measurements.size() == 0) + return 0; + else { + m_max = 0; + m_min = 1000; + int sum = 0; + for (int i=0; i< m_measurements.size(); i++) { + sum += (int) m_measurements.value(i); + if (((int)m_measurements.value(i)) > m_max) + m_max = (int)m_measurements.value(i); + if (((int)m_measurements.value(i)) < m_min) + m_min = (int)m_measurements.value(i); + } + return sum/m_measurements.size(); + } +} + +int HeartRate::measurements(int index) +{ + if (index> m_measurements.size()) + return 0; + else + return (int)m_measurements.value(index); +} + +int HeartRate::measurementsSize() +{ + return m_measurements.size(); +} + +QString HeartRate::deviceAddress() +{ + return m_currentDevice.getDevice().address().toString(); +} + +float HeartRate::caloriesCalculation() +{ + calories = ((-55.0969 + (0.6309 * average()) + (0.1988 * 94) + (0.2017 * 24)) / 4.184) * 60 * time()/3600 ; + return calories; +} + +void HeartRate::serviceDisconnected(const QLowEnergyServiceInfo &service) +{ + setMessage("Heart Rate service disconnected"); + qWarning() << "Service disconnected: " << service.uuid(); +} + +int HeartRate::numDevices() const +{ + return m_devices.size(); +} + +void HeartRate::startDemo() +{ + m_start = QDateTime::currentDateTime(); + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(receiveDemo())); + timer->start(1000); + setMessage("This is Demo mode"); +} + +void HeartRate::receiveDemo() +{ + m_HRMeasurement = 60; + m_measurements.append(m_HRMeasurement); + Q_EMIT hrChanged(); +} + +void HeartRate::serviceScanError(QBluetoothServiceDiscoveryAgent::Error error) +{ + if (error == QBluetoothServiceDiscoveryAgent::PoweredOffError) + setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery."); + else if (error == QBluetoothServiceDiscoveryAgent::InputOutputError) + setMessage("Writing or reading from the device resulted in an error."); + else + setMessage("An unknown error has occurred."); +} + +void HeartRate::deviceScanError(QBluetoothDeviceDiscoveryAgent::Error error) +{ + if (error == QBluetoothDeviceDiscoveryAgent::PoweredOffError) + setMessage("The Bluetooth adaptor is powered off, power it on before doing discovery."); + else if (error == QBluetoothDeviceDiscoveryAgent::InputOutputError) + setMessage("Writing or reading from the device resulted in an error."); + else + setMessage("An unknown error has occurred."); +} diff --git a/examples/bluetooth/heartlistener/heartrate.h b/examples/bluetooth/heartlistener/heartrate.h new file mode 100644 index 00000000..e7d75666 --- /dev/null +++ b/examples/bluetooth/heartlistener/heartrate.h @@ -0,0 +1,144 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef HEARTRATE_H +#define HEARTRATE_H + +#include +#include +#include +#include +#include +#include +#include +#include "deviceinfo.h" +#include +#include +#include +#include "qlowenergyserviceinfo.h" +#include "qlowenergycontroller.h" +#include +#include + +QT_FORWARD_DECLARE_CLASS (QLowEnergyServiceInfo) +QT_FORWARD_DECLARE_CLASS (QLowEnergyCharacteristicInfo) +QT_FORWARD_DECLARE_CLASS (QLowEnergyController) + +QT_USE_NAMESPACE +class HeartRate: public QObject +{ + Q_OBJECT + Q_PROPERTY(QVariant name READ name NOTIFY nameChanged) + Q_PROPERTY(QString message READ message NOTIFY messageChanged) + Q_PROPERTY(int hr READ hR NOTIFY hrChanged) + Q_PROPERTY(int maxHR READ maxHR NOTIFY averageChanged) + Q_PROPERTY(int minHR READ minHR NOTIFY averageChanged) + Q_PROPERTY(float average READ average NOTIFY averageChanged) + Q_PROPERTY(int time READ time NOTIFY timeChanged) + Q_PROPERTY(float calories READ caloriesCalculation NOTIFY caloriesChanged) + +public: + HeartRate(); + ~HeartRate(); + void setMessage(QString message); + QString message() const; + QVariant name(); + int hR() const; + int time(); + float average(); + int maxHR() const; + int minHR() const; + float caloriesCalculation(); + +public slots: + void deviceSearch(); + void addDevice(const QBluetoothDeviceInfo&); + void deviceScanError(QBluetoothDeviceDiscoveryAgent::Error); + void scanFinished(); + void connectToService(const QString &address); + void addLowEnergyService(const QLowEnergyServiceInfo&); + void serviceScanDone(); + void serviceScanError(QBluetoothServiceDiscoveryAgent::Error); + void serviceConnected(const QLowEnergyServiceInfo &); + void receiveMeasurement(const QLowEnergyCharacteristicInfo &); + void errorReceived(const QLowEnergyServiceInfo &); + void errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &); + void serviceDisconnected(const QLowEnergyServiceInfo &); + void disconnectService(); + void obtainResults(); + void startConnection(); + int measurements(int index); + int measurementsSize(); + QString deviceAddress(); + int numDevices() const; + void startDemo(); + void receiveDemo(); + +Q_SIGNALS: + void messageChanged(); + void nameChanged(); + void hrChanged(); + void averageChanged(); + void timeChanged(); + void caloriesChanged(); + +private: + DeviceInfo m_currentDevice; + QBluetoothServiceDiscoveryAgent *m_serviceDiscoveryAgent; + QBluetoothDeviceDiscoveryAgent *m_deviceDiscoveryAgent; + QLowEnergyCharacteristicInfo m_heartRateCharacteristic; + QList m_devices; + QString m_info; + QLowEnergyServiceInfo m_heartRateService; + bool foundHeartRateService; + bool foundHeartRateCharacteristic; + int m_HRMeasurement; + QVector m_measurements; + QDateTime m_start; + QDateTime m_stop; + int m_max; + int m_min; + QVector m_timestamps; + float calories; + QLowEnergyController *m_leInfo; + QTimer *timer; // for demo application +}; + +#endif // HEARTRATE_H diff --git a/examples/bluetooth/heartlistener/main.cpp b/examples/bluetooth/heartlistener/main.cpp new file mode 100644 index 00000000..3ea3a652 --- /dev/null +++ b/examples/bluetooth/heartlistener/main.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** +** +** Copyright (C) 2014 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the QtBluetooth module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "heartrate.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + HeartRate heartRate; + QQuickView *view = new QQuickView; + view->rootContext()->setContextProperty("heartRate", &heartRate); + view->setSource(QUrl("qrc:/assets/main.qml")); + view->setResizeMode(QQuickView::SizeRootObjectToView); + view->show(); + return app.exec(); + +} diff --git a/examples/bluetooth/heartlistener/resources.qrc b/examples/bluetooth/heartlistener/resources.qrc new file mode 100644 index 00000000..ac6f9c83 --- /dev/null +++ b/examples/bluetooth/heartlistener/resources.qrc @@ -0,0 +1,16 @@ + + + assets/blue_heart.png + assets/busy_dark.png + assets/Button.qml + assets/dialog.qml + assets/draw.js + assets/home.qml + assets/main.qml + assets/monitor.qml + assets/Point.qml + assets/results.qml + assets/star.png + assets/blue_heart_small.png + + diff --git a/src/bluetooth/doc/src/bluetooth-index.qdoc b/src/bluetooth/doc/src/bluetooth-index.qdoc index 77575994..5fc1b7c7 100644 --- a/src/bluetooth/doc/src/bluetooth-index.qdoc +++ b/src/bluetooth/doc/src/bluetooth-index.qdoc @@ -69,6 +69,7 @@ import statement in your \c .qml file: \list \li \l {scanner}{QML Bluetooth Scanner} \li \l {picturetransfer}{QML Bluetooth Picture Push} + \li \l {heartlistener}{Heart Listener} \endlist \li C++ \list diff --git a/src/bluetooth/doc/src/examples.qdoc b/src/bluetooth/doc/src/examples.qdoc index 11e38d36..3b9ea577 100644 --- a/src/bluetooth/doc/src/examples.qdoc +++ b/src/bluetooth/doc/src/examples.qdoc @@ -74,6 +74,10 @@ \row \li \l{lowenergyscanner}{QML Bluetooth Low Energy Scanner} \li Scan for Bluetooth Low Energy devices, services and characteristics. + \row + \li \l{heartlistener}{QML Bluetooth Low Energy Heart Listener} + \li Connect to the Bluetooth Low Energy heart belt and receive + measurements. \endtable */ -- cgit v1.2.3