A BlueTooth-controlled Android App to Measure Heart Rate
We made our application with the KY-039 Pulse Measurement sensor, which is easily available in the market. We connected it to the microcontroller board with the HC-05 Bluetooth module that we used in our previous applications.
As in the examples of voltmeter and ohmmeter, we read the value with the analogRead
function on the microcontroller side. The necessary formulation for heart rate measurement is in Arduino codes. We convert the calculated value to string type and send it to our Bluetooth module with the myserial.write
command.
The pulse display application we wrote with Flutter-Dart codes is quite simple. With the receiveData
function, we convert the value we receive to string type and print it to a text object.
The receiveData
command has been added to a Timer
function. Thus, we can receive incoming data at certain time intervals.
Below are the Flutter-Dart codes we wrote for the Android phone:
import 'dart:async';
import 'dart:convert';
//import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
void main() => runApp(const MyApp());
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
// ignore: library_private_types_in_public_api
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<BluetoothDevice> _devices = [];
late BluetoothConnection connection;
String adr = "00:21:07:00:50:69"; // my bluetooth device MAC Adres
String recData = "0";
late Timer _timer;
String _timeString = "";
@override
void initState() {
// _startTimer(); automatic
super.initState();
_loadDevices();
}
Future<void> _loadDevices() async {
List<BluetoothDevice> devices = await FlutterBluetoothSerial.instance
.getBondedDevices();
setState(() {
_devices = devices;
});
}
//----------------------------
Future<void> sendData(String data) async {
data = data.trim();
try {
List<int> list = data.codeUnits;
Uint8List bytes = Uint8List.fromList(list);
connection.output.add(bytes);
await connection.output.allSent;
if (kDebugMode) {
// print('Data sent successfully');
}
} catch (e) {
//print(e.toString());
}
}
// data RECEIVED --------------
Future<void> receiveData() async {
connection.input!.listen((Uint8List data) {
//Data entry point
setState(() {
recData=ascii.decode(data);
//var n1 = int.parse('-42');
});
});
}
//--------------------------------------
// TIMER START-----------
void _startTimer() {
_timer = Timer.periodic(Duration(milliseconds: 500), (timer) {
receiveData();
});
}
// TIMER STOP--------------------------------------
Future<void> _stopTimer() async {
setState(() {
});
_timer.cancel();
}
//---------------------------------------------
@override
void dispose() {
_timer.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("--- Heart rate monitor with BlueTooth-----"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("MAC Adress: 00:21:07:00:50:69"),
ElevatedButton(child: Text("Connect"), onPressed: () {
connect(adr);
},),
const SizedBox(height: 30.0,),
const Text("HR: ",style: TextStyle(fontSize: 55.0),),
Text(recData,style: TextStyle(fontSize: 90.0),),
const SizedBox(height: 10.0,),
// Text(_timeString),
const SizedBox(height: 10.0,),
ElevatedButton(child: Text("Stop timer"), onPressed: () {
_stopTimer();
},),
const SizedBox(height: 10.0,),
ElevatedButton(child: Text("Start timer"), onPressed: () {
_startTimer();
},),
],
),
),
)
);
}
Future connect(String address) async {
try {
connection = await BluetoothConnection.toAddress(address);
// sendData('111');
//durum="Connected to the device";
} catch (exception) {
// durum="Cannot connect, exception occured";
}
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
}
// --------------**************data gonder
//Future send(Uint8List data) async {
//connection.output.add(data);
// await connection.output.allSent;
// }
}
//------------*********** data gonder end
Below are the microcontroller codes:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
char Buf[50]; // to bluetooth device<------
String volt_string="0";
unsigned long oldTime = 0;
unsigned long atTime;
unsigned long passTime=0;
int Signal; // Store incoming ADC data. Value can range from 0-1024
int level = 180; // Determine which Signal to "count as a beat" and which to ignore.
float heart_peek=70;
void setup() {
Serial.begin(9600); // Set comm speed for serial plotter window
mySerial.begin(9600); // bluetooth modeule
}
void loop() {
Signal = analogRead(A1); // Read the sensor value
Serial.print("----->");Serial.println(passTime);
Serial.print("--->");Serial.println(Signal);
if(Signal > level){
atTime=millis();
passTime=atTime-oldTime;
oldTime=atTime;
heart_peek=(600000/passTime);
Serial.print("RPM:"); Serial.println(heart_peek);
volt_string=String(heart_peek);
volt_string.toCharArray(Buf, 50);
mySerial.write(Buf);
}
delay(500);
// Serial.println(Signal);
}