Complete rewrite.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 569549f..709aa7e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0" >
<uses-sdk
- android:minSdkVersion="8"
+ android:minSdkVersion="14"
android:targetSdkVersion="19" />
<application
@@ -23,7 +23,4 @@
</intent-filter>
</activity>
</application>
-
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
</manifest>
diff --git a/assets/plox.dat b/assets/plox.dat
deleted file mode 100644
index bf1e6c5..0000000
--- a/assets/plox.dat
+++ /dev/null
Binary files differ
diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar
deleted file mode 100644
index a7e9919..0000000
--- a/libs/android-support-v4.jar
+++ /dev/null
Binary files differ
diff --git a/res/layout/activity_ara_plox.xml b/res/layout/activity_ara_plox.xml
index 4063dbb..a0d8222 100644
--- a/res/layout/activity_ara_plox.xml
+++ b/res/layout/activity_ara_plox.xml
@@ -1,41 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:keepScreenOn="true">
<TextView
android:id="@+id/textView"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
+ android:layout_width="match_parent"
+ android:layout_height="28sp"
android:gravity="center"
- android:layout_weight="1"
android:background="#FFFFFF"
android:fontFamily="sans-serif"
- android:textSize="32sp"
- android:text="@string/hello_world" />
+ android:textSize="20sp"
+ android:text="@string/chart1_name"/>
<LinearLayout android:id="@+id/irChart"
android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="3"/>
- <LinearLayout android:id="@+id/redChart"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="3"/>
-
-
-<!--
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
<TextView
android:id="@+id/textView"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_height="28sp"
android:gravity="center"
- android:layout_weight="1"
android:background="#FFFFFF"
android:fontFamily="sans-serif"
- android:textSize="64sp"
- android:text="@string/hello_world" />
--->
-
+ android:textSize="20sp"
+ android:text="@string/chart2_name"/>
+ <LinearLayout android:id="@+id/redChart"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
</LinearLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 8c5ee37..8acf43f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <string name="app_name">AraPloxIO</string>
- <string name="hello_world">Pulse Monitor</string>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name">AraPulseOx</string>
+ <string name="chart1_name">940nm</string>
+ <string name="chart2_name">660nm</string>
</resources>
diff --git a/src/com/google/araploxio/AFE4400Thread.java b/src/com/google/araploxio/AFE4400Thread.java
deleted file mode 100644
index 4193341..0000000
--- a/src/com/google/araploxio/AFE4400Thread.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2014 Google, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.araploxio;
-
-import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
-import android.hardware.I2cManager;
-import android.hardware.I2cTransaction;
-import android.util.Log;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import java.io.DataOutputStream;
-import java.io.DataInputStream;
-import java.io.FileOutputStream;
-
-public class AFE4400Thread extends Thread {
-
- // The 7-bit slave address
- private static final int address = (0x50 >> 1);
- private static final String TAG = "araplox";
-
- private static final String preferredI2cBus = "/dev/i2c-4";
-
- private static final boolean useRecordedData = false;
-
- private Handler handler;
- private I2cManager i2c;
- private Context context;
-
- private volatile boolean stopped;
- private DataInputStream ploxInputStream;
-
- private static final I2cTransaction[] setupWrites = {
- WriteReg(0x00, 0x00, 0x00, 0x00), //AFE4400_CONTROL0
- WriteReg(0x01, 0x00, 0x17, 0xD4), //AFE4400_LED2STC
- WriteReg(0x02, 0x00, 0x1D, 0xAE), //AFE4400_LEDENDC
- WriteReg(0x03, 0x00, 0x17, 0x70), //AFE4400_LED2LEDSTC
- WriteReg(0x04, 0x00, 0x1D, 0xAF), //AFE4400_LED2LEDENDC
- WriteReg(0x05, 0x00, 0x00, 0x00), //AFE4400_ALED2STC
- WriteReg(0x06, 0x00, 0x06, 0x3E), //AFE4400_ALED2ENDC
- WriteReg(0x07, 0x00, 0x08, 0x34), //AFE4400_LED1STC
- WriteReg(0x08, 0x00, 0x0E, 0x0E), //AFE4400_LED1ENDC
- WriteReg(0x09, 0x00, 0x07, 0xD0), //AFE4400_LED1LEDSTC
- WriteReg(10, 0x00, 0x0E, 0x0F), //AFE4400_LED1LEDENDC
-
- WriteReg(11, 0x00, 0x0F, 0xA0), //AFE4400_ALED1STC
- WriteReg(12, 0x00, 0x15, 0xDE), //AFE4400_ALED1ENDC
- WriteReg(13, 0x00, 0x00, 0x02), //AFE4400_LED2CONVST
- WriteReg(14, 0x00, 0x07, 0xCF), //AFE4400_LED2CONVEND
- WriteReg(15, 0x00, 0x07, 0xD2), //AFE4400_ALED2CONVST
- WriteReg(16, 0x00, 0x0F, 0x9F), //AFE4400_ALED2CONVEND
- WriteReg(17, 0x00, 0x0F, 0xA2), //AFE4400_LED1CONVST
- WriteReg(18, 0x00, 0x17, 0x6F), //AFE4400_LED1CONVEND
- WriteReg(19, 0x00, 0x17, 0x72), //AFE4400_ALED1CONVST
- WriteReg(20, 0x00, 0x1F, 0x3F), //AFE4400_ALED1CONVEND
-
- WriteReg(21, 0x00, 0x00, 0x00),//AFE4400_ADCRSTSTCT0
- WriteReg(22, 0x00, 0x00, 0x00),//AFE4400_ADCRSTENDCT0
- WriteReg(23, 0x00, 0x07, 0xD0),//AFE4400_ADCRSTSTCT1
- WriteReg(24, 0x00, 0x07, 0xD0),//AFE4400_ADCRSTENDCT1
- WriteReg(25, 0x00, 0x0F, 0XA0),//AFE4400_ADCRSTSTCT2
- WriteReg(26, 0x00, 0x0F, 0XA0),//AFE4400_ADCRSTENDCT2
- WriteReg(27, 0x00, 0x17, 0x70),//AFE4400_ADCRSTSTCT3
- WriteReg(28, 0x00, 0x17, 0x70),//AFE4400_ADCRSTENDCT3
- WriteReg(29, 0x00, 0x1F, 0x3F),//AFE4400_PRPCOUNT
- WriteReg(30, 0x00, 0x01, 0x01),//AFE4400_CONTROL1
-
- WriteReg(31, 0x00, 0x00, 0x00),//AFE4400_SPARE1
- WriteReg(32, 0x00, 0x00, 0x00),//AFE4400_TIAGAIN
- WriteReg(33, 0x00, 0x00, 0x0A),//AFE4400_TIA_AMB_GAIN
- WriteReg(34, 0x01, 0x14, 0x29),//AFE4400_LEDCNTRL
- WriteReg(35, 0x02, 0x01, 0x00),//AFE4400_CONTROL2
- WriteReg(36, 0x00, 0x00, 0x00),//AFE4400_SPARE2
- WriteReg(37, 0x00, 0x00, 0x00),//AFE4400_SPARE3
- WriteReg(38, 0x00, 0x00, 0x00),//AFE4400_SPARE4
- WriteReg(39, 0x00, 0x00, 0x00),//AFE4400_RESERVED1
- WriteReg(40, 0x00, 0x00, 0x00),//AFE4400_RESERVED2
- WriteReg(41, 0x00, 0x00, 0x00),//AFE4400_ALARM
- WriteReg(42, 0x00, 0x00, 0x00),//AFE4400_LED2VAL
-
- WriteReg(43, 0x00, 0x00, 0x00),//AFE4400_ALED2VAL
- WriteReg(44, 0x00, 0x00, 0x00),//AFE4400_LED1VAL
- WriteReg(45, 0x00, 0x00, 0x00),//AFE4400_ALED1VAL
- WriteReg(46, 0x00, 0x00, 0x00),//AFE4400_LED2-ALED2VAL
- WriteReg(47, 0x00, 0x00, 0x00),//AFE4400_LED1-ALED1VAL
- WriteReg(48, 0x00, 0x00, 0x00),//AFE4400_DIAG
-
- // Setup SPI_READ
- WriteReg(0, 0x00, 0x00, 0x01),//AFE4400_DIAG
- };
-
- public AFE4400Thread(Context context, Handler handler) {
- this.context = context;
- this.i2c = (I2cManager)context.getSystemService(Context.I2C_SERVICE);
- this.stopped = false;
- this.handler = handler;
- }
-
- private void startRecordedStream() {
- Log.d(TAG, "Playing back recorded data");
-
- try {
- ploxInputStream = new DataInputStream(context.getAssets().open("plox.dat"));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- int x = 0;
- while (!stopped) {
- Message msg;
- try {
- msg = handler.obtainMessage(0, ploxInputStream.readInt(), ploxInputStream.readInt());
- msg.sendToTarget();
- } catch (IOException e1) {
- e1.printStackTrace();
- requestStop();
- break;
- }
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- try {
- ploxInputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private void startSensorStream() {
- String[] buses = i2c.getI2cBuses();
- if (buses.length == 0) {
- setText("no I2C buses found :(");
- return;
- }
- String bus = buses[0];
- for (String b: buses) {
- if (b.equals(preferredI2cBus)) {
- bus = b;
- }
- }
- Log.i(TAG, "[pulse ox app] Using I2C bus: " + bus);
-
- I2cTransaction[] results;
- for (I2cTransaction txn: setupWrites) {
- try {
- results = i2c.performTransactions(bus, address, txn);
- } catch (IOException e) {
- setText("transaction error: " + e);
- return;
- }
- }
-
- while (!isStopped()) {
- results = null;
- byte[] data;
- int LED1VAL;
- int LED2VAL;
- I2cTransaction[] txns0 = {
- I2cTransaction.newWrite(0x01, // Select SPI device 1
- 0x2e, // LED2-ALED2VAL
- 0xff, 0xff, 0xff), // 3 dummy bytes
- I2cTransaction.newRead(4),
- };
- I2cTransaction[] txns1 = {
- I2cTransaction.newWrite(0x01, // Select SPI device 1
- 0x2f, // LED2-ALED2VAL
- 0xff, 0xff, 0xff), // 3 dummy bytes
- I2cTransaction.newRead(4),
- };
-
-
- try {
- for (I2cTransaction txn: txns0) {
- results = i2c.performTransactions(bus, address, txn);
- }
- } catch (IOException e) {
- setText("error while reading back: " + e);
- return;
- }
-
- data = results[0].data;
-
- LED1VAL = (((int)data[1]) << 16) |
- (((int)data[2] & 0xFF) << 8) |
- (((int)data[3] & 0xFF));
-
- try {
- for (I2cTransaction txn: txns1) {
- results = i2c.performTransactions(bus, address, txn);
- }
- } catch (IOException e) {
- setText("error while reading back: " + e);
- return;
- }
-
- data = results[0].data;
-
- LED2VAL = (((int)data[1]) << 16) |
- (((int)data[2] & 0xFF) << 8) |
- (((int)data[3] & 0xFF));
-
- Message msg = handler.obtainMessage(0, LED1VAL, LED2VAL);
- msg.sendToTarget();
-
- try {
- Thread.sleep(5);
- } catch (Exception e) {
- e.printStackTrace();
- requestStop();
- }
- }
- }
-
- @Override
- public void run() {
- if (useRecordedData) {
- startRecordedStream();
- } else {
- startSensorStream();
- }
- }
-
-
- private static I2cTransaction WriteReg(int reg, int b1, int b2, int b3) {
- return I2cTransaction.newWrite(0x01, reg, b1, b2, b3);
- }
-
- private void setText(String s) {
- // TODO -- it'd be nice to actually have a text field for this
- // stuff.
- Log.i(TAG, s);
- }
-
- // ------------------------------------------------------------
-
- public void requestStop() {
- this.stopped = true;
- }
-
- public boolean isStopped() {
- return this.stopped;
- }
-}
diff --git a/src/com/google/araploxio/AraPloxActivity.java b/src/com/google/araploxio/AraPloxActivity.java
index bc9a0af..f04ead3 100644
--- a/src/com/google/araploxio/AraPloxActivity.java
+++ b/src/com/google/araploxio/AraPloxActivity.java
@@ -16,177 +16,46 @@
package com.google.araploxio;
-import org.achartengine.ChartFactory;
-import org.achartengine.GraphicalView;
-import org.achartengine.chart.PointStyle;
-import org.achartengine.model.XYMultipleSeriesDataset;
-import org.achartengine.model.XYSeries;
-import org.achartengine.renderer.XYMultipleSeriesRenderer;
-import org.achartengine.renderer.XYSeriesRenderer;
-
import android.app.Activity;
import android.graphics.Color;
-import android.graphics.Paint.Align;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Log;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
-import android.widget.TextView;
public class AraPloxActivity extends Activity {
- private static final String TAG = "AraPlox/Activity";
- private static final int SCROLLBACK_SIZE = 200;
+ private Chart irChart, redChart;
+ private Sensor sensor;
- private static TextView bpmTextView;
- private static Handler mHandler = null;
- private static AFE4400Thread afe4400Thread = null;
- private static int sampleCount = 0;
-
- private AraPloxChart irPloxChart = new AraPloxChart(R.id.irChart);
- private AraPloxChart redPloxChart = new AraPloxChart(R.id.redChart);
-
- private class AraPloxChart {
- int id;
- private XYMultipleSeriesRenderer renderer;
- private XYMultipleSeriesDataset dataSet;
- private XYSeriesRenderer xySeriesRenderer;
- private XYSeries xySeries;
- private GraphicalView chartView;
-
- public AraPloxChart(int id) {
- this.id = id;
+ private final Handler handler = new Handler() {
+ public void handleMessage(Message msg) {
+ irChart.add(msg.arg1);
+ redChart.add(msg.arg2);
}
+ };
- public void makeChart(int pointColor) {
- dataSet = new XYMultipleSeriesDataset();
- xySeries = new XYSeries("");
- dataSet.addSeries(xySeries);
-
- int[] colors = new int[] {pointColor};
- PointStyle[] styles = new PointStyle[] {PointStyle.CIRCLE};
-
- renderer = new XYMultipleSeriesRenderer();
-
- int length = colors.length;
- for (int i = 0; i < length; i++) {
- xySeriesRenderer = new XYSeriesRenderer();
- xySeriesRenderer.setFillPoints(true);
- xySeriesRenderer.setLineWidth(10.0f);
- xySeriesRenderer.setPointStrokeWidth(1);
- xySeriesRenderer.setColor(colors[i]);
- xySeriesRenderer.setPointStyle(styles[i]);
- renderer.addSeriesRenderer(xySeriesRenderer);
- }
-
- renderer.setChartTitleTextSize(20);
- renderer.setLabelsTextSize(15);
- renderer.setLegendTextSize(15);
- renderer.setPointSize(5f);
- renderer.setMargins(new int[] { 50, 50, 50, 50 });
- renderer.setXAxisMin(0);
- renderer.setXAxisMax(10);
- renderer.setYAxisMin(0);
- renderer.setYAxisMax(100);
- renderer.setAxesColor(Color.BLACK);
- renderer.setLabelsColor(Color.BLACK);
- renderer.setShowLegend(false);
- renderer.setXLabels(10);
- renderer.setYLabels(0);
- renderer.setShowGrid(false);
- renderer.setXLabelsAlign(Align.CENTER);
- renderer.setApplyBackgroundColor(true);
- renderer.setBackgroundColor(Color.WHITE);
- renderer.setMarginsColor(Color.WHITE);
-
- chartView = ChartFactory.getCubeLineChartView(getApplicationContext(), dataSet, renderer, 1.0f);
-
- LinearLayout layout = (LinearLayout)findViewById(id);
- layout.addView(chartView, new LayoutParams(LayoutParams.FILL_PARENT,
- LayoutParams.FILL_PARENT));
- chartView.repaint();
- }
-
- public void removeChart() {
- LinearLayout layout = (LinearLayout)findViewById(id);
- layout.removeView(chartView);
- }
-
- public void handleNewSample(double x, double y) {
- xySeries.add(x, y);
-
- // Scroll continuously after SCROLLBACK_SIZE points
- if (x > SCROLLBACK_SIZE) {
- xySeries.remove(0);
- }
-
- // Autoscale
- double maxX = xySeries.getMaxX();
- double minX = xySeries.getMinX();
- double maxY = xySeries.getMaxY();
- double minY = xySeries.getMinY();
-
- maxY *= 1.01;
- minY *= .99;
-
- renderer.setXAxisMax(maxX);
- renderer.setXAxisMin(minX);
- renderer.setYAxisMax(maxY);
- renderer.setYAxisMin(minY);
-
- chartView.repaint();
-
- sampleCount++;
- }
- }
-
+ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Log.d(TAG, "onCreate()");
- requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_ara_plox);
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- double irLedSample = msg.arg1;
- double redLedSample = msg.arg2;
-
- irPloxChart.handleNewSample(sampleCount, irLedSample);
- redPloxChart.handleNewSample(sampleCount, redLedSample);
-
- sampleCount++;
- }
- };
+ irChart = new Chart(this, (LinearLayout) findViewById(R.id.irChart), "ir", Color.GREEN);
+ redChart = new Chart(this, (LinearLayout) findViewById(R.id.redChart), "red", Color.RED);
}
+ @Override
protected void onResume() {
+ irChart.clear();
+ redChart.clear();
super.onResume();
- Log.d(TAG, "onResume()");
- if (afe4400Thread == null) {
- afe4400Thread = new AFE4400Thread(getApplicationContext(), mHandler);
- afe4400Thread.start();
- }
- irPloxChart.makeChart(Color.GREEN);
- redPloxChart.makeChart(Color.RED);
+ sensor = new Sensor(this, handler);
+ sensor.start();
}
+ @Override
protected void onPause() {
+ sensor.stop();
+ sensor = null;
+ handler.removeMessages(0);
super.onPause();
- Log.d(TAG, "onPause()");
- if (afe4400Thread != null) {
- afe4400Thread.requestStop();
- afe4400Thread = null;
- }
- irPloxChart.removeChart();
- redPloxChart.removeChart();
- }
-
- protected void onStop() {
- super.onStop();
- Log.d(TAG, "onStop()");
}
}
diff --git a/src/com/google/araploxio/Chart.java b/src/com/google/araploxio/Chart.java
new file mode 100644
index 0000000..e8ae9c0
--- /dev/null
+++ b/src/com/google/araploxio/Chart.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.araploxio;
+
+import org.achartengine.ChartFactory;
+import org.achartengine.GraphicalView;
+import org.achartengine.model.XYMultipleSeriesDataset;
+import org.achartengine.model.XYSeries;
+import org.achartengine.renderer.XYMultipleSeriesRenderer;
+import org.achartengine.renderer.XYSeriesRenderer;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Paint.Align;
+import android.widget.LinearLayout;
+
+public class Chart {
+ private static final int SCROLLBACK_SIZE = 200;
+
+ private int sampleCount = 0;
+ private XYMultipleSeriesDataset mDataset;
+ private XYMultipleSeriesRenderer mRenderer;
+ private XYSeries mCurrentSeries;
+ private XYSeriesRenderer mCurrentRenderer;
+ private GraphicalView mChart;
+
+ public Chart(Context context, LinearLayout layout, String name, int color) {
+ mDataset = new XYMultipleSeriesDataset();
+
+ mRenderer = new XYMultipleSeriesRenderer();
+ mRenderer.setAxisTitleTextSize(0);
+ mRenderer.setChartTitleTextSize(0);
+ mRenderer.setLabelsTextSize(15);
+ mRenderer.setLegendTextSize(15);
+ mRenderer.setPointSize(1.0f);
+ mRenderer.setMargins(new int[] { 10, 30, 30, 30 });
+ mRenderer.setXAxisMin(0);
+ mRenderer.setXAxisMax(10);
+ mRenderer.setYAxisMin(0);
+ mRenderer.setYAxisMax(100);
+ mRenderer.setAxesColor(Color.BLACK);
+ mRenderer.setLabelsColor(Color.BLACK);
+ mRenderer.setLegendHeight(0);
+ mRenderer.setShowLegend(false);
+ mRenderer.setXLabels(0);
+ mRenderer.setYLabels(2);
+ mRenderer.setShowGrid(false);
+ mRenderer.setXLabelsAlign(Align.CENTER);
+ mRenderer.setYLabelsAlign(Align.LEFT);
+ mRenderer.setApplyBackgroundColor(true);
+ mRenderer.setBackgroundColor(Color.WHITE);
+ mRenderer.setMarginsColor(Color.WHITE);
+ mRenderer.setAntialiasing(false);
+ mRenderer.setPanEnabled(false, false);
+ mRenderer.setZoomEnabled(false, false);
+
+ mCurrentSeries = new XYSeries(name);
+ mDataset.addSeries(mCurrentSeries);
+
+ mCurrentRenderer = new XYSeriesRenderer();
+ mCurrentRenderer.setColor(color);
+ mRenderer.addSeriesRenderer(mCurrentRenderer);
+
+ mChart = ChartFactory.getLineChartView(context, mDataset, mRenderer);
+ layout.addView(mChart);
+ }
+
+ public void add(int y) {
+ int x = sampleCount++;
+
+ mCurrentSeries.add(x, y);
+
+ mRenderer.setXAxisMax(x);
+ mRenderer.setXAxisMin(x - SCROLLBACK_SIZE + 1);
+
+ if (mCurrentSeries.getItemCount() > SCROLLBACK_SIZE)
+ mCurrentSeries.remove(0);
+
+ // Autoscale
+ double maxY = mCurrentSeries.getMaxY();
+ double minY = mCurrentSeries.getMinY();
+
+ double diffY = maxY - minY;
+ double avgY = (maxY + minY) / 2.0;
+ if (diffY < 4000.0)
+ diffY = 4000.0;
+ maxY = avgY + diffY * 0.625;
+ minY = avgY - diffY * 0.625;
+
+ mRenderer.setYAxisMax(maxY);
+ mRenderer.setYAxisMin(minY);
+
+ mChart.repaint();
+ }
+
+ public void clear() {
+ mCurrentSeries.clear();
+ }
+}
diff --git a/src/com/google/araploxio/Sensor.java b/src/com/google/araploxio/Sensor.java
new file mode 100644
index 0000000..fcd7522
--- /dev/null
+++ b/src/com/google/araploxio/Sensor.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.araploxio;
+
+import android.content.Context;
+import android.hardware.I2cManager;
+import android.hardware.I2cTransaction;
+import android.os.Handler;
+import android.os.Message;
+
+import java.io.IOException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class Sensor {
+ // The 7-bit slave address
+ private static final int address = (0x50 >> 1);
+ private static final String bus = "/dev/i2c-4";
+
+ private Context context;
+ private I2cManager i2c;
+ private Handler handler;
+ private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
+
+ private static I2cTransaction WriteReg(int reg, int b1, int b2, int b3) {
+ return I2cTransaction.newWrite(0x01, reg, b1, b2, b3);
+ }
+
+ private static final I2cTransaction[] setupTxns = {
+ WriteReg(0x00, 0x00, 0x00, 0x08), //AFE4400_CONTROL0
+
+ WriteReg(0x01, 0x00, 0x17, 0xD4), //AFE4400_LED2STC
+ WriteReg(0x02, 0x00, 0x1D, 0xAE), //AFE4400_LED2ENDC
+ WriteReg(0x03, 0x00, 0x17, 0x70), //AFE4400_LED2LEDSTC
+ WriteReg(0x04, 0x00, 0x1D, 0xAF), //AFE4400_LED2LEDENDC
+ WriteReg(0x05, 0x00, 0x00, 0x00), //AFE4400_ALED2STC
+ WriteReg(0x06, 0x00, 0x06, 0x3E), //AFE4400_ALED2ENDC
+
+ WriteReg(0x07, 0x00, 0x08, 0x34), //AFE4400_LED1STC
+ WriteReg(0x08, 0x00, 0x0E, 0x0E), //AFE4400_LED1ENDC
+ WriteReg(0x09, 0x00, 0x07, 0xD0), //AFE4400_LED1LEDSTC
+ WriteReg(0x0A, 0x00, 0x0E, 0x0F), //AFE4400_LED1LEDENDC
+ WriteReg(0x0B, 0x00, 0x0F, 0xA0), //AFE4400_ALED1STC
+ WriteReg(0x0C, 0x00, 0x15, 0xDE), //AFE4400_ALED1ENDC
+
+ WriteReg(0x0D, 0x00, 0x00, 0x02), //AFE4400_LED2CONVST
+ WriteReg(0x0E, 0x00, 0x07, 0xCF), //AFE4400_LED2CONVEND
+ WriteReg(0x0F, 0x00, 0x07, 0xD2), //AFE4400_ALED2CONVST
+ WriteReg(0x10, 0x00, 0x0F, 0x9F), //AFE4400_ALED2CONVEND
+
+ WriteReg(0x11, 0x00, 0x0F, 0xA2), //AFE4400_LED1CONVST
+ WriteReg(0x12, 0x00, 0x17, 0x6F), //AFE4400_LED1CONVEND
+ WriteReg(0x13, 0x00, 0x17, 0x72), //AFE4400_ALED1CONVST
+ WriteReg(0x14, 0x00, 0x1F, 0x3F), //AFE4400_ALED1CONVEND
+
+ WriteReg(0x15, 0x00, 0x00, 0x00), //AFE4400_ADCRSTSTCT0
+ WriteReg(0x16, 0x00, 0x00, 0x00), //AFE4400_ADCRSTENDCT0
+ WriteReg(0x17, 0x00, 0x07, 0xD0), //AFE4400_ADCRSTSTCT1
+ WriteReg(0x18, 0x00, 0x07, 0xD0), //AFE4400_ADCRSTENDCT1
+ WriteReg(0x19, 0x00, 0x0F, 0xA0), //AFE4400_ADCRSTSTCT2
+ WriteReg(0x1A, 0x00, 0x0F, 0xA0), //AFE4400_ADCRSTENDCT2
+ WriteReg(0x1B, 0x00, 0x17, 0x70), //AFE4400_ADCRSTSTCT3
+ WriteReg(0x1C, 0x00, 0x17, 0x70), //AFE4400_ADCRSTENDCT3
+
+ WriteReg(0x1D, 0x00, 0x1F, 0x3F), //AFE4400_PRPCOUNT
+ WriteReg(0x1E, 0x00, 0x01, 0x01), //AFE4400_CONTROL1
+ WriteReg(0x20, 0x00, 0x00, 0x00), //AFE4400_TIAGAIN
+ // Rf=100k Cf=50pF gain=0dB stage2=bypass ambdac=0µA
+ WriteReg(0x21, 0x00, 0x00, 0x3A), //AFE4400_TIA_AMB_GAIN
+ //WriteReg(0x22, 0x01, 0x14, 0x29), //AFE4400_LEDCNTRL
+ WriteReg(0x22, 0x01, 0x4f, 0x4f), //AFE4400_LEDCNTRL
+ WriteReg(0x23, 0x02, 0x01, 0x00), //AFE4400_CONTROL2
+ WriteReg(0x29, 0x00, 0x00, 0x00), //AFE4400_ALARM
+
+ // Setup SPI_READ
+ WriteReg(0x00, 0x00, 0x00, 0x01), //AFE4400_CONTROL0
+ };
+
+ private static final I2cTransaction[] led2Read = {
+ WriteReg(0x2e, // LED2-ALED2VAL
+ 0xff, 0xff, 0xff), // 3 dummy bytes
+ I2cTransaction.newRead(4),
+ };
+ private static final I2cTransaction[] led1Read = {
+ WriteReg(0x2f, // LED1-ALED1VAL
+ 0xff, 0xff, 0xff), // 3 dummy bytes
+ I2cTransaction.newRead(4),
+ };
+
+ private static final I2cTransaction[] resetTxns = {
+ WriteReg(0x00, 0x00, 0x00, 0x08), //AFE4400_CONTROL0
+ };
+
+ public Sensor(Context context, Handler handler) {
+ this.context = context;
+ this.i2c = (I2cManager)context.getSystemService(Context.I2C_SERVICE);
+ this.handler = handler;
+ }
+
+ private I2cTransaction[] execute(I2cTransaction[] txns) {
+ I2cTransaction[] results;
+ try {
+ results = null;
+ for (I2cTransaction txn: txns)
+ results = i2c.performTransactions(bus, address, txn);
+ } catch (IOException e) {
+ throw new RuntimeException("I2C error: " + e);
+ }
+ return results;
+ }
+
+ public void start() {
+ execute(setupTxns);
+ executor.scheduleAtFixedRate(collector, 20, 20, TimeUnit.MILLISECONDS);
+ }
+
+ public void stop() {
+ executor.shutdown();
+ try {
+ executor.awaitTermination(20, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ assert false;
+ }
+ execute(resetTxns);
+ }
+
+ private final Runnable collector = new Runnable() {
+ public void run() {
+ I2cTransaction[] results;
+ byte[] data;
+ int LED1VAL;
+ int LED2VAL;
+
+ results = execute(led2Read);
+ data = results[0].data;
+ LED2VAL = (((int)data[1] & 0xFF) << 16) |
+ (((int)data[2] & 0xFF) << 8) |
+ (((int)data[3] & 0xFF) << 0);
+ if (LED2VAL >= 0x800000 && LED2VAL < 0x1000000)
+ LED2VAL -= 0x1000000;
+
+ results = execute(led1Read);
+ data = results[0].data;
+ LED1VAL = (((int)data[1] & 0xFF) << 16) |
+ (((int)data[2] & 0xFF) << 8) |
+ (((int)data[3] & 0xFF) << 0);
+ if (LED1VAL >= 0x800000 && LED1VAL < 0x1000000)
+ LED1VAL -= 0x1000000;
+
+ handler.obtainMessage(0, LED1VAL, LED2VAL).sendToTarget();
+ }
+ };
+}