// write RR values to a text file kept in the application data directory for possible later use
  public void writeRR(View v) {
    try {

      // status.setMessage("writing RR values to file");
      SimpleDateFormat format = new SimpleDateFormat("yyyy_MM_dd_HH_mm");

      // give user feedback the button worked
      v.playSoundEffect(SoundEffectConstants.CLICK);

      double starttime = series.getX(0);
      String mydate = (format.format(starttime));

      String FILENAME = "rr_" + mydate + ".txt";
      status.setMessage("writing RR values to file to Documents  " + FILENAME);
      File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
      File file = new File(path, "/" + FILENAME);

      dbg(file.getAbsolutePath().toString());
      file.createNewFile();

      FileOutputStream fos = new FileOutputStream(file);

      for (int i = 1; i < series.getItemCount(); i++) {
        int temprr = (int) (series.getX(i) - series.getX(i - 1));
        String s = String.valueOf(temprr) + "\n";

        fos.write(s.getBytes());
      }
      fos.close();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 public void startZephyr(View v) {
   v.playSoundEffect(SoundEffectConstants.CLICK);
   status.setMessage("Connecting Zephyr");
   x = System.currentTimeMillis();
   zm.connect();
 }
  // the zephry manager will send RR values to this listener.
  // RRs are the milliseconds between beats.  Example, steady 60 BPM heartbeat sends rr values of
  // 1000 because there is a full second between beats
  public void updateChart(int rr) {

    // we throw out any 0s or absurd values.  We have found this tends not to happen with a good
    // chest strap
    if ((rr < 1) || (rr > 3000)) return;
    int pulserate = 60000 / rr;
    series.add(x, pulserate);
    x = x + rr; // time is also the accumulation of RR values

    // Achartengine stuff
    XYSeriesRenderer renderer = new XYSeriesRenderer();
    XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();

    // Set the right side to current time
    mRenderer.setXAxisMax(x);

    // set the left side to one minute earlier 60000 miliseconds
    mRenderer.setXAxisMin(x - 60000);

    mRenderer.setYAxisMin(MIN_HEART_RATE);
    mRenderer.setYAxisMax(MAX_HEART_RATE);

    mRenderer.setLabelsTextSize(LABELTEXTSIZE);
    renderer.setFillPoints(true);
    renderer.setLineWidth(2);

    renderer.setPointStyle(style);
    mRenderer.setShowLegend(false);
    mRenderer.setChartTitle(title);
    mRenderer.setShowGrid(true);
    mRenderer.setGridColor(gridcolor);
    mRenderer.setXLabels(11);
    mRenderer.setYLabels(5);

    mRenderer.setAxisTitleTextSize(25);
    mRenderer.setChartTitleTextSize(30);
    mRenderer.setLabelsTextSize(20);
    mRenderer.setLegendTextSize(15);
    mRenderer.setPointSize(2f);
    mRenderer.setMargins(new int[] {20, 30, 15, 0});

    mRenderer.setYLabelsAlign(Align.RIGHT);
    mDataset.removeSeries(0);

    mDataset.addSeries(series);

    renderer.setColor(linecolor);
    context = getApplicationContext();
    mRenderer.setApplyBackgroundColor(true);
    mRenderer.setBackgroundColor(bgcolor);
    mRenderer.addSeriesRenderer(renderer);

    chartview = ChartFactory.getTimeChartView(context, mDataset, mRenderer, null);
    chartview.invalidate();
    ((TextView) findViewById(R.id.heartratelabel)).setText("HR:" + pulserate);

    chartview.repaint();

    FrameLayout chartlayout = (FrameLayout) findViewById(R.id.chartlayout);
    chartlayout.removeAllViewsInLayout();

    chartlayout.addView(
        chartview,
        new FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT));

    status
        .checkForClear(); // this needs to be done time to time regularly so statuses are not stuck
                          // on.
  }