Android Open Source - BLE-Heart-rate-variability-demo Demo Heart Rate Sensor Activity






From Project

Back to project page BLE-Heart-rate-variability-demo.

License

The source code is released under:

MIT License

If you think the Android project BLE-Heart-rate-variability-demo listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.sample.hrv.demo;
//from  w ww  .j  a va 2s .  co  m
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;

import android.content.Context;
import android.os.SystemClock;


import com.sample.hrv.R;
import com.sample.hrv.sensor.BleHeartRateSensor;
import com.sample.hrv.sensor.BleSensor;

/**
 * Created by olli on 3/28/14.
 */
public class DemoHeartRateSensorActivity extends DemoSensorActivity {
  private final static String TAG = DemoHeartRateSensorActivity.class
      .getSimpleName();

  private TextView viewText;
  private PolygonRenderer renderer;

  private GLSurfaceView view;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.demo_opengl);
    view = (GLSurfaceView) findViewById(R.id.gl);

    getActionBar().setTitle(R.string.title_demo_heartrate);

    viewText = (TextView) findViewById(R.id.text);

    renderer = new PolygonRenderer(this);
    view.setRenderer(renderer);
    //view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    // Render when hear rate data is updated
    view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  }

  @Override
  public void onDataRecieved(BleSensor<?> sensor, String text) {
    if (sensor instanceof BleHeartRateSensor) {
      final BleHeartRateSensor heartSensor = (BleHeartRateSensor) sensor;
      float[] values = heartSensor.getData();
      renderer.setInterval(values);
      view.requestRender();

      viewText.setText(text);
    }
  }
  
  public abstract class AbstractRenderer implements GLSurfaceView.Renderer {
    
    public int[] getConfigSpec() {
      int[] configSpec = { EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_NONE };
      return configSpec;
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
      gl.glDisable(GL10.GL_DITHER);
      gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
      gl.glClearColor(.5f, .5f, .5f, 1);
      gl.glShadeModel(GL10.GL_SMOOTH);
      gl.glEnable(GL10.GL_DEPTH_TEST);
    }

    public void onSurfaceChanged(GL10 gl, int w, int h) {
      gl.glViewport(0, 0, w, h);
      float ratio = (float) w / h;
      gl.glMatrixMode(GL10.GL_PROJECTION);
      gl.glLoadIdentity();
      gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
    }

    public void onDrawFrame(GL10 gl) {
      gl.glDisable(GL10.GL_DITHER);
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
      gl.glMatrixMode(GL10.GL_MODELVIEW);
      gl.glLoadIdentity();
      GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      draw(gl);
    }

    protected abstract void draw(GL10 gl);
  }

  public class PolygonRenderer extends AbstractRenderer {
    private final String TAG = PolygonRenderer.class
        .getSimpleName();

    // Number of points or vertices we want to use
    private final static int VERTS = 4;

    // A raw native buffer to hold the point coordinates
    private FloatBuffer mFVertexBuffer;

    // A raw native buffer to hold indices
    // allowing a reuse of points.
    private ShortBuffer mIndexBuffer;

    private int numOfIndecies = 0;

    private long prevtime = SystemClock.uptimeMillis();

    private int sides = 32;

    private float[] interval = { 0, 0, 0 };
    private float previousInterval = 0;

    public void setInterval(float[] interval) {
      if (this.interval[1] >= 0 && interval[1] > 0) {
        this.previousInterval = this.interval[1];
      }
      this.interval[0] = interval[0]; // heart rate
      this.interval[1] = interval[1]; // beat to beat interval
      this.interval[2] = 0;      // empty
    }
    
    public PolygonRenderer(Context context) {
      prepareBuffers(sides, interval[1]);
    }

    private void prepareBuffers(int sides, float radius) {
      Log.d(TAG,"radius: "+radius +" previous: "+previousInterval);
      // Is it a valid value?
      if (radius < 0) {
        radius = previousInterval;
      }
      
      // Double check if the previous value was valid
      if (radius < 0) {
        radius = 700;
      }
      Log.d(TAG,"final radius: "+radius);
      
      radius = ( ( radius / 1000 ) - 0.7f ) * 2;
      
      RegularPolygon t = new RegularPolygon(0, 0, 0, radius, sides);
      this.mFVertexBuffer = t.getVertexBuffer();
      this.mIndexBuffer = t.getIndexBuffer();
      this.numOfIndecies = t.getNumberOfIndecies();
      this.mFVertexBuffer.position(0);
      this.mIndexBuffer.position(0);
    }

    // overriden method
    protected void draw(GL10 gl) {
      long curtime = SystemClock.uptimeMillis();

      this.prepareBuffers(sides, interval[1]);
      gl.glColor4f(96/255.0f, 246/255.0f, 255/255.0f, 1.0f);
      gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
      gl.glDrawElements(GL10.GL_TRIANGLES, this.numOfIndecies,
          GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
    }
  }


  private static class RegularPolygon {
    private static final String TAG = RegularPolygon.class
        .getSimpleName();
    private float cx, cy, cz, r;
    private int sides;
    private float[] xarray = null;
    private float[] yarray = null;

    public RegularPolygon(float incx, float incy, float incz, // (x,y,z)
                                  // center
        float inr, // radius
        int insides) // number of sides
    {
      cx = incx;
      cy = incy;
      cz = incz;
      r = inr;
      sides = insides;

      xarray = new float[sides];
      yarray = new float[sides];
      calcArrays();
    }

    private void calcArrays() {
      float[] xmarray = this.getXMultiplierArray();
      float[] ymarray = this.getYMultiplierArray();

      // calc xarray
      for (int i = 0; i < sides; i++) {
        float curm = xmarray[i];
        float xcoord = cx + r * curm;
        xarray[i] = xcoord;
      }
      //this.printArray(xarray, "xarray");

      // calc yarray
      for (int i = 0; i < sides; i++) {
        float curm = ymarray[i];
        float ycoord = cy + r * curm;
        yarray[i] = ycoord;
      }
      //this.printArray(yarray, "yarray");

    }

    public FloatBuffer getVertexBuffer() {
      int vertices = sides + 1;
      int coordinates = 3;
      int floatsize = 4;
      int spacePerVertex = coordinates * floatsize;

      ByteBuffer vbb = ByteBuffer.allocateDirect(spacePerVertex
          * vertices);
      vbb.order(ByteOrder.nativeOrder());
      FloatBuffer mFVertexBuffer = vbb.asFloatBuffer();

      // Put the first coordinate (x,y,z:0,0,0)
      mFVertexBuffer.put(0.0f); // x
      mFVertexBuffer.put(0.0f); // y
      mFVertexBuffer.put(0.0f); // z

      int totalPuts = 3;
      for (int i = 0; i < sides; i++) {
        mFVertexBuffer.put(xarray[i]); // x
        mFVertexBuffer.put(yarray[i]); // y
        mFVertexBuffer.put(0.0f); // z
        totalPuts += 3;
      }
      //Log.d(TAG, "total puts: " + Integer.toString(totalPuts));
      return mFVertexBuffer;
    }

    public ShortBuffer getIndexBuffer() {
      short[] iarray = new short[sides * 3];
      ByteBuffer ibb = ByteBuffer.allocateDirect(sides * 3 * 2);
      ibb.order(ByteOrder.nativeOrder());
      ShortBuffer mIndexBuffer = ibb.asShortBuffer();
      for (int i = 0; i < sides; i++) {
        short index1 = 0;
        short index2 = (short) (i + 1);
        short index3 = (short) (i + 2);
        if (index3 == sides + 1) {
          index3 = 1;
        }
        mIndexBuffer.put(index1);
        mIndexBuffer.put(index2);
        mIndexBuffer.put(index3);

        iarray[i * 3 + 0] = index1;
        iarray[i * 3 + 1] = index2;
        iarray[i * 3 + 2] = index3;
      }
      //this.printShortArray(iarray, "index array");
      return mIndexBuffer;
    }

    private float[] getXMultiplierArray() {
      float[] angleArray = getAngleArrays();
      float[] xmultiplierArray = new float[sides];
      for (int i = 0; i < angleArray.length; i++) {
        float curAngle = angleArray[i];
        float sinvalue = (float) Math.cos(Math.toRadians(curAngle));
        float absSinValue = Math.abs(sinvalue);
        if (isXPositiveQuadrant(curAngle)) {
          sinvalue = absSinValue;
        } else {
          sinvalue = -absSinValue;
        }
        xmultiplierArray[i] = this.getApproxValue(sinvalue);
      }
      //this.printArray(xmultiplierArray, "xmultiplierArray");
      return xmultiplierArray;
    }

    private float[] getYMultiplierArray() {
      float[] angleArray = getAngleArrays();
      float[] ymultiplierArray = new float[sides];
      for (int i = 0; i < angleArray.length; i++) {
        float curAngle = angleArray[i];
        float sinvalue = (float) Math.sin(Math.toRadians(curAngle));
        float absSinValue = Math.abs(sinvalue);
        if (isYPositiveQuadrant(curAngle)) {
          sinvalue = absSinValue;
        } else {
          sinvalue = -absSinValue;
        }
        ymultiplierArray[i] = this.getApproxValue(sinvalue);
      }
      //this.printArray(ymultiplierArray, "ymultiplierArray");
      return ymultiplierArray;
    }

    private boolean isXPositiveQuadrant(float angle) {
      if ((0 <= angle) && (angle <= 90)) {
        return true;
      }

      if ((angle < 0) && (angle >= -90)) {
        return true;
      }
      return false;
    }

    private boolean isYPositiveQuadrant(float angle) {
      if ((0 <= angle) && (angle <= 90)) {
        return true;
      }

      if ((angle < 180) && (angle >= 90)) {
        return true;
      }
      return false;
    }

    private float[] getAngleArrays() {
      float[] angleArray = new float[sides];
      float commonAngle = 360.0f / sides;
      float halfAngle = commonAngle / 2.0f;
      float firstAngle = 360.0f - (90 + halfAngle);
      angleArray[0] = firstAngle;

      float curAngle = firstAngle;
      for (int i = 1; i < sides; i++) {
        float newAngle = curAngle - commonAngle;
        angleArray[i] = newAngle;
        curAngle = newAngle;
      }
      //printArray(angleArray, "angleArray");
      return angleArray;
    }

    private float getApproxValue(float f) {
      if (Math.abs(f) < 0.001) {
        return 0;
      }
      return f;
    }

    public int getNumberOfIndecies() {
      return sides * 3;
    }

    private void printArray(float array[], String tag) {
      StringBuilder sb = new StringBuilder(tag);
      for (int i = 0; i < array.length; i++) {
        sb.append(";").append(array[i]);
      }
      Log.d(TAG, sb.toString());
    }

    private void printShortArray(short array[], String tag) {
      StringBuilder sb = new StringBuilder(tag);
      for (int i = 0; i < array.length; i++) {
        sb.append(";").append(array[i]);
      }
      Log.d(TAG, sb.toString());
    }
  }

}




Java Source Code List

com.sample.hrv.BleService.java
com.sample.hrv.BluetoothGattExecutor.java
com.sample.hrv.DeviceScanActivity.java
com.sample.hrv.DeviceServicesActivity.java
com.sample.hrv.adapters.BleDevicesAdapter.java
com.sample.hrv.adapters.BleServicesAdapter.java
com.sample.hrv.demo.DemoGLSurfaceView.java
com.sample.hrv.demo.DemoHeartRateSensorActivity.java
com.sample.hrv.demo.DemoSensorActivity.java
com.sample.hrv.info.BleDeviceInfoService.java
com.sample.hrv.info.BleGapService.java
com.sample.hrv.info.BleGattService.java
com.sample.hrv.info.BleInfoService.java
com.sample.hrv.info.BleInfoServices.java
com.sample.hrv.sensor.BleHeartRateSensor.java
com.sample.hrv.sensor.BleSensorUtils.java
com.sample.hrv.sensor.BleSensor.java
com.sample.hrv.sensor.BleSensors.java
com.sample.hrv.sensor.BleTestSensor.java