I'm currently developing an Android Application which connects via Bluetooth Low Energy to an Arduino which has the nRF8001 Bluetooth Low Energy Module with a connect the SEN-11574 Pulse Rate Sensor available at Spark Fun ( https://www.sparkfun.com/products/11574 ).
I have been trying to implement a graph which plots the data on the graph every time I tap on 'Get Heart Rate' button but I'm only managing the following:
I've researched a number of different resources which include the following yet unfortunately they don't answer my question:
I am using the Android Graph View Library to try and solve my problem as it offers the best integration with Android Studio.
I am struggling with three main things:
The full project is available at : Arduino Pulse Rate
I seem to be struggling the most with these two sections of code:
private void writeSensorData(final CharSequence text) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e(LOG_TAG,text.toString());
output=text.toString().trim();
if (output.length() > 0 && output.length() <=3) {
pulseRateView.setText(output);
rateSeries.appendData(new GraphView.GraphViewData(graph2LastXValue,Double.parseDouble(output)),AutoScrollX,maxDataCount);
}
else {
return;
}
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pulse);
//Connect U.I Elements
getPulseRate = (Button)findViewById(R.id.heartRateBtn);
pulseRateView = (TextView) findViewById(R.id.pulseValueView);
connectionStsView = (TextView) findViewById(R.id.connectionStsView);
refreshButton = (Button) findViewById(R.id.refreshBtn);
// init heart rate series data
rateSeries = new GraphViewSeries(new GraphView.GraphViewData[] {
});
GraphView graphView = new LineGraphView(this, "Pulse Rate Sensor");
graphView.addSeries(rateSeries);
graphView.setScrollable(true);
graphView.setScalable(true);
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
layout.addView(graphView);
getPulseRate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String setOutputMessage = "/bpm /";
tx.setValue(setOutputMessage.getBytes(Charset.forName("UTF-8")));
if (gatt.writeCharacteristic(tx)) {
writeConnectionData("Sent: " + setOutputMessage);
} else {
writeConnectionData("Couldn't write TX characteristic!");
}
}
});
refreshButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
restartScan();
}
});
}
Would appreciate any help and thank you for your time.
The solution below configures your graph to achieve the basic layout and functionality you want. Note that I have bound a sample graph update to the clicking of the refresh
button - you can bind a similar procedure to your interface with the actual pulse device. All you need is the time-bpm pair to be plotted to the x and y axes, respectively.
PulseActivity#onCreate
// Local variable for simulating the sample time
private int x = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pulse);
//Connect U.I Elements
getPulseRate = (Button) findViewById(R.id.heartRateBtn);
pulseRateView = (TextView) findViewById(R.id.pulseValueView);
connectionStsView = (TextView) findViewById(R.id.connectionStsView);
refreshButton = (Button) findViewById(R.id.refreshBtn);
final GraphView graphView = new LineGraphView(
this, // context
"Pulse Rate Sensor" // heading
);
graphView.setVerticalLabels(new String[]{"high", "normal", "low"});
graphView.setCustomLabelFormatter(new CustomLabelFormatter() {
@Override
public String formatLabel(double value, boolean isValueX) {
if (isValueX) {
return null;
} else {
if (value < 60) {
return "low";
} else if (value < 100) {
return "normal";
} else {
return "high";
}
}
}
});
// init heart rate series data
rateSeries = new GraphViewSeries(new GraphView.GraphViewData[]{
});
graphView.addSeries(rateSeries);
LinearLayout layout = (LinearLayout) findViewById(R.id.graph1);
layout.addView(graphView);
getPulseRate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String setOutputMessage = "/bpm /";
tx.setValue(setOutputMessage.getBytes(Charset.forName("UTF-8")));
if (gatt.writeCharacteristic(tx)) {
writeConnectionData("Sent: " + setOutputMessage);
} else {
writeConnectionData("Couldn't write TX characteristic!");
}
}
});
refreshButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//restartScan();
rateSeries.appendData(new GraphView.GraphViewData(x += 3, new Random().nextInt(100)), false, 100);
graphView.redrawAll();
}
});
}
activity_pulse.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:id="@+id/graph1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp" />
<LinearLayout
android:id="@+id/rest"
android:layout_width="fill_parent"
android:layout_height="250dip"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Refresh Connection"
android:id="@+id/refreshBtn"
android:layout_gravity="center_horizontal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Heart Rate"
android:id="@+id/heartRateBtn"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Last Pulse Rate Value"
android:id="@+id/pulsePlaceholderText"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/pulseValueView"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Connection Status"
android:id="@+id/connectionStsView"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>