diff --git a/.gitignore b/.gitignore
index 04d47c56d6b887c18d9c38c1dd029ecbb1e9c277..007d64268841d3fb3282a82e2376522174a3d543 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ local.properties
 .idea
 bugfender.properties
 /app/app.iml
+gradle.properties
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index bc39a1084d08f077d7b3212257ff6b73dbe50000..027d93daafacb3fecbcc0d36f3fc6073a5eeb215 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -27,7 +27,7 @@ apply plugin: 'realm-android'
 def gitVersion() {
     // current dir is <your proj>/app, so it's likely that all your git repo files are in the dir
     // above.
-    ext.repo = Grgit.open(project.file('..'))
+    ext.repo = Grgit.open()
 
     // should result in the same value as running
     // git tag -l | wc -l or git tag -l | grep -c ".*" -
@@ -36,14 +36,15 @@ def gitVersion() {
 }
 
 def gitCommitId() {
-    //def process = ['sh', '-c', 'git tag -l | grep -c ".*" -'].execute().text.trim()
-    //return process.toInteger() + 1
-    //return 42
-    // current dir is <your proj>/app, so it's likely that all your git repo files are in the dir
-    // above.
-    ext.repo = Grgit.open(project.file('..'))
+    ext.repo = Grgit.open()
+
+    return ext.repo.log().first().id.substring(0, 7) //+ " " + ext.repo.branch.current.name
+}
+
 
-    return ext.repo.log().first().id.substring(0, 7)
+def gitBranch() {
+    ext.repo = Grgit.open()
+    return ext.repo.branch.current.name
 }
 
 def getBugfenderApiKey() {
@@ -66,7 +67,7 @@ android {
         applicationId "info.nightscout.android"
         minSdkVersion 14
         targetSdkVersion 23
-        versionName project.properties['version'] + "/" + gitCommitId()
+        versionName project.properties['version'] + "/" + gitCommitId() // + " (" + gitBranch()+")"
         versionCode gitVersion()
         buildConfigField "String", "BUGFENDER_API_KEY", getBugfenderApiKey()
     }
@@ -154,8 +155,7 @@ dependencies {
     compile 'com.mikepenz:google-material-typeface:2.2.0.1.original@aar'
     compile 'uk.co.chrisjenx:calligraphy:2.2.0'
     compile 'com.bugfender.sdk:android:0.6.2'
-    compile 'com.github.PhilJay:MPAndroidChart-Realm:v2.0.2@aar'
-    compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'
+    compile 'com.jjoe64:graphview:4.2.1'
     compile 'com.android.support:support-v4:23.4.0'
     compile 'com.google.code.gson:gson:2.7'
     compile 'com.squareup.retrofit2:retrofit:2.1.0'
diff --git a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
index 2e2fab454bf50f53735d055af908f3d63be10a53..363c97116956403dea14cdd6033079536b1fca84 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java
@@ -10,7 +10,9 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Paint;
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbManager;
 import android.net.Uri;
@@ -33,25 +35,19 @@ import android.util.Log;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.MotionEvent;
 import android.view.View;
 import android.widget.TextView;
 import android.widget.TextView.BufferType;
-
-import com.github.mikephil.charting.charts.ScatterChart;
-import com.github.mikephil.charting.components.AxisBase;
-import com.github.mikephil.charting.components.XAxis;
-import com.github.mikephil.charting.components.YAxis;
-import com.github.mikephil.charting.data.Entry;
-import com.github.mikephil.charting.data.ScatterData;
-import com.github.mikephil.charting.data.ScatterDataSet;
-import com.github.mikephil.charting.data.realm.implementation.RealmScatterDataSet;
-import com.github.mikephil.charting.formatter.IAxisValueFormatter;
-import com.github.mikephil.charting.formatter.IValueFormatter;
-import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
-import com.github.mikephil.charting.listener.ChartTouchListener;
-import com.github.mikephil.charting.listener.OnChartGestureListener;
-import com.github.mikephil.charting.utils.ViewPortHandler;
+import android.widget.Toast;
+
+import com.jjoe64.graphview.DefaultLabelFormatter;
+import com.jjoe64.graphview.GraphView;
+import com.jjoe64.graphview.Viewport;
+import com.jjoe64.graphview.series.DataPoint;
+import com.jjoe64.graphview.series.DataPointInterface;
+import com.jjoe64.graphview.series.OnDataPointTapListener;
+import com.jjoe64.graphview.series.PointsGraphSeries;
+import com.jjoe64.graphview.series.Series;
 import com.mikepenz.google_material_typeface_library.GoogleMaterial;
 import com.mikepenz.materialdrawer.AccountHeaderBuilder;
 import com.mikepenz.materialdrawer.Drawer;
@@ -61,9 +57,8 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
 
 import java.text.DateFormat;
 import java.text.DecimalFormat;
-import java.util.ArrayList;
+import java.text.NumberFormat;
 import java.util.Date;
-import java.util.List;
 import java.util.Locale;
 import java.util.Queue;
 import java.util.concurrent.ArrayBlockingQueue;
@@ -79,7 +74,6 @@ import info.nightscout.android.model.medtronicNg.PumpInfo;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
 import info.nightscout.android.settings.SettingsActivity;
 import info.nightscout.android.upload.nightscout.NightscoutUploadIntentService;
-import io.realm.DynamicRealmObject;
 import io.realm.Realm;
 import io.realm.RealmChangeListener;
 import io.realm.RealmResults;
@@ -88,6 +82,7 @@ import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
 
 public class MainActivity extends AppCompatActivity implements OnSharedPreferenceChangeListener, OnEulaAgreedTo {
     private static final String TAG = MainActivity.class.getSimpleName();
+    public static final float MMOLXLFACTOR = 18.016f;
 
     public static int batLevel = 0;
     public static boolean reducePollOnPumpAway = false;
@@ -95,13 +90,18 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
     public static long lowBatteryPollInterval = MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS;
 
     private static long activePumpMac;
+    private int chartZoom = 3;
+    private boolean hasZoomedChart = false;
 
+    private NumberFormat sgvFormatter;
+    private boolean mmolxl;
+    private boolean mmolxlDecimals;
 
     boolean mEnableCgmService = true;
     SharedPreferences prefs = null;
     private PumpInfo mActivePump;
     private TextView mTextViewLog; // This will eventually move to a status page.
-    private ScatterChart mChart;
+    private GraphView mChart;
     private Intent mNightscoutUploadService;
     private Handler mUiRefreshHandler = new Handler();
     private Runnable mUiRefreshRunnable = new RefreshDisplayRunnable();
@@ -109,6 +109,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
     private StatusMessageReceiver statusMessageReceiver = new StatusMessageReceiver();
     private MedtronicCnlAlarmReceiver medtronicCnlAlarmReceiver = new MedtronicCnlAlarmReceiver();
 
+
     public static long getNextPoll(PumpStatusEvent pumpStatusData) {
         long nextPoll = pumpStatusData.getEventDate().getTime() + pumpStatusData.getPumpTimeOffset()
                 + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS;
@@ -146,6 +147,18 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         MainActivity.pollInterval = Long.parseLong(prefs.getString("pollInterval", Long.toString(MedtronicCnlIntentService.POLL_PERIOD_MS)));
         MainActivity.lowBatteryPollInterval = Long.parseLong(prefs.getString("lowBatPollInterval", Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS)));
         MainActivity.reducePollOnPumpAway = prefs.getBoolean("doublePollOnPumpAway", false);
+        chartZoom = Integer.parseInt(prefs.getString("chartZoom", "3"));
+        mmolxl = prefs.getBoolean("mmolxl", false);
+        mmolxlDecimals = prefs.getBoolean("mmolDecimals", false);
+
+        if (mmolxl) {
+            if (mmolxlDecimals)
+                sgvFormatter = new DecimalFormat("0.00");
+            else
+                sgvFormatter = new DecimalFormat("0.0");
+        } else {
+            sgvFormatter = new DecimalFormat("0");
+        }
 
         // Disable battery optimization to avoid missing values on 6.0+
         // taken from https://github.com/NightscoutFoundation/xDrip/blob/master/app/src/main/java/com/eveningoutpost/dexdrip/Home.java#L277L298
@@ -268,68 +281,57 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                 .build();
 
         mTextViewLog = (TextView) findViewById(R.id.textview_log);
-        mChart = (ScatterChart) findViewById(R.id.chart);
 
-        mChart.setDescription(null);    // Hide the description
+        mChart = (GraphView) findViewById(R.id.chart);
 
-        mChart.setTouchEnabled(true);
-        mChart.setPinchZoom(true);
-        mChart.setHighlightPerDragEnabled(false);
-        mChart.setHighlightPerTapEnabled(false);
-        mChart.setOnChartGestureListener(new OnChartGestureListener() {
+        // disable scrolling at the moment
+        mChart.getViewport().setScalable(false);
+        mChart.getViewport().setScrollable(false);
+        mChart.getViewport().setXAxisBoundsManual(true);
+        final long now = System.currentTimeMillis(),
+                left = now - chartZoom * 60 * 60 * 1000;
 
-            @Override
-            public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {}
-
-            @Override
-            public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {}
+        mChart.getViewport().setMaxX(now);
+        mChart.getViewport().setMinX(left);
 
+        mChart.getViewport().setOnXAxisBoundsChangedListener(new Viewport.OnXAxisBoundsChangedListener() {
             @Override
-            public void onChartLongPressed(MotionEvent me) {
-                mChart.fitScreen();
+            public void onXAxisBoundsChanged(double minX, double maxX, Reason reason) {
+                double rightX = mChart.getSeries().get(0).getHighestValueX();
+                hasZoomedChart = (rightX != maxX || rightX - chartZoom * 60 * 60 * 1000 != minX);
             }
-
-            @Override
-            public void onChartDoubleTapped(MotionEvent me) {}
-
-            @Override
-            public void onChartSingleTapped(MotionEvent me) {}
-
-            @Override
-            public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {}
-
-            @Override
-            public void onChartScale(MotionEvent me, float scaleX, float scaleY) {}
-
-            @Override
-            public void onChartTranslate(MotionEvent me, float dX, float dY) {}
         });
 
-        XAxis xAxis = mChart.getXAxis();
-        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
-        xAxis.setTextSize(10f);
-        xAxis.setTextColor(Color.WHITE);
-        xAxis.setDrawAxisLine(true);
-        xAxis.setDrawGridLines(true);
-        xAxis.setDrawLabels(true);
-        xAxis.setValueFormatter(new IAxisValueFormatter() {
-            private DateFormat mFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
-
+        mChart.setOnLongClickListener(new View.OnLongClickListener() {
             @Override
-            public String getFormattedValue(float value, AxisBase axis) {
-                return mFormat.format(new Date((long) value));
+            public boolean onLongClick(View v) {
+                if (!mChart.getSeries().isEmpty() && !mChart.getSeries().get(0).isEmpty()) {
+                    double rightX = mChart.getSeries().get(0).getHighestValueX();
+                    mChart.getViewport().setMaxX(rightX);
+                    mChart.getViewport().setMinX(rightX - chartZoom * 60 * 60 * 1000);
+                }
+                hasZoomedChart = false;
+                return true;
             }
         });
+        mChart.getGridLabelRenderer().setNumHorizontalLabels(6);
+        mChart.getGridLabelRenderer().setHumanRounding(false);
 
-        // left axis
-        mChart.getAxisLeft().setDrawLabels(false);
-
-        // right axis
-        YAxis yAxis = mChart.getAxisRight();
-        yAxis.setTextSize(10f);
-        yAxis.setTextColor(Color.WHITE);
-
-        mChart.getLegend().setEnabled(false);   // Hide the legend
+        mChart.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() {
+            DateFormat mFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
+            @Override
+            public String formatLabel(double value, boolean isValueX) {
+                if (isValueX) {
+                    return mFormat.format(new Date((long) value));
+                } else {
+                    if (mmolxl) {
+                        return sgvFormatter.format(value / MMOLXLFACTOR);
+                    } else {
+                        return sgvFormatter.format(value);
+                    }
+                }
+            }}
+        );
     }
 
     @Override
@@ -490,7 +492,17 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                 mEnableCgmService = true;
                 startCgmService();
             }
-        } else if (key.equals("mmolxl")) {
+        } else if (key.equals("mmolxl") || key.equals("mmolDecimals")) {
+            mmolxl = sharedPreferences.getBoolean("mmolxl", false);
+            mmolxlDecimals = sharedPreferences.getBoolean("mmolDecimals", false);
+            if (mmolxl) {
+                if (mmolxlDecimals)
+                    sgvFormatter = new DecimalFormat("0.00");
+                else
+                    sgvFormatter = new DecimalFormat("0.0");
+            } else {
+                sgvFormatter = new DecimalFormat("0");
+            }
             refreshDisplay();
         } else if (key.equals("pollInterval")) {
             MainActivity.pollInterval = Long.parseLong(sharedPreferences.getString("pollInterval",
@@ -500,6 +512,10 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
                     Long.toString(MedtronicCnlIntentService.LOW_BATTERY_POLL_PERIOD_MS)));
         } else if (key.equals("doublePollOnPumpAway")) {
             MainActivity.reducePollOnPumpAway = sharedPreferences.getBoolean("doublePollOnPumpAway", false);
+        } else if (key.equals("chartZoom")) {
+            chartZoom = Integer.parseInt(sharedPreferences.getString("chartZoom", "3"));
+            hasZoomedChart = false;
+            refreshDisplay();
         }
     }
 
@@ -684,7 +700,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
             TextView textViewBg = (TextView) findViewById(R.id.textview_bg);
             TextView textViewBgTime = (TextView) findViewById(R.id.textview_bg_time);
             TextView textViewUnits = (TextView) findViewById(R.id.textview_units);
-            if (prefs.getBoolean("mmolxl", false)) {
+            if (mmolxl) {
                 textViewUnits.setText(R.string.text_unit_mmolxl);
             } else {
                 textViewUnits.setText(R.string.text_unit_mgxdl);
@@ -710,27 +726,17 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
 
             if (pumpStatusData != null) {
 
-                String sgvString, units;
-                if (prefs.getBoolean("mmolxl", false)) {
-                    DecimalFormat df;
-                    if (prefs.getBoolean("mmolDecimals", false))
-                        df = new DecimalFormat("0.00");
-                    else
-                        df = new DecimalFormat("0.0");
-
+                String sgvString;
+                if (mmolxl) {
                     float fBgValue = (float) pumpStatusData.getSgv();
-                    sgvString = df.format(fBgValue / 18.016f);
-                    units = "mmol/L";
+                    sgvString = sgvFormatter.format(fBgValue / MMOLXLFACTOR);
                     Log.d(TAG, sgvString + " mmol/L");
-
                 } else {
                     sgvString = String.valueOf(pumpStatusData.getSgv());
-                    units = "mg/dL";
                     Log.d(TAG, sgvString + " mg/dL");
                 }
 
                 textViewBg.setText(sgvString);
-                textViewUnits.setText(units);
                 textViewBgTime.setText(DateUtils.getRelativeTimeSpanString(pumpStatusData.getEventDate().getTime()));
                 textViewTrend.setText(Html.fromHtml(renderTrendHtml(pumpStatusData.getCgmTrend())));
                 textViewIOB.setText(String.format(Locale.getDefault(), "%.2f", pumpStatusData.getActiveInsulin()));
@@ -772,71 +778,102 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
 
         private void updateChart(RealmResults<PumpStatusEvent> results) {
             int size = results.size();
-            if (size == 0) return;
+            if (size == 0) {
+                final long now = System.currentTimeMillis(),
+                        left = now - chartZoom * 60 * 60 * 1000;
+
+                mChart.getViewport().setXAxisBoundsManual(true);
+                mChart.getViewport().setMaxX(now);
+                mChart.getViewport().setMinX(left);
+
+                mChart.getViewport().setYAxisBoundsManual(true);
+                if (mmolxl) {
+                    mChart.getViewport().setMinY(80 / MMOLXLFACTOR);
+                    mChart.getViewport().setMaxY(120 / MMOLXLFACTOR);
+                } else {
+                    mChart.getViewport().setMinY(80);
+                    mChart.getViewport().setMaxY(120);
+                }
+                mChart.postInvalidate();
+                return;
+            }
 
-            List<Entry> entries = new ArrayList<Entry>(size);
-            int[] colors = new int[size];  // getColor is called with (i/2)
+            DataPoint[] entries = new DataPoint[size];
+            final long left = System.currentTimeMillis() - chartZoom * 60 * 60 * 1000;
 
+            int pos = 0;
             for (PumpStatusEvent pumpStatus: results) {
                 // turn your data into Entry objects
-                int sgv = pumpStatus.getSgv(),
-                    pos = entries.size();
-
-                entries.add(new Entry(pumpStatus.getEventDate().getTime(), pumpStatus.getSgv()));
-                if (sgv < 80)
-                    colors[pos] = Color.RED;
-                else if (sgv <= 180)
-                    colors[pos] = Color.GREEN;
-                else if (sgv <= 260)
-                    colors[pos] = Color.YELLOW;
-                else
-                    colors[pos] = Color.RED;
+                int sgv = pumpStatus.getSgv();
+
+                if (mmolxl) {
+                    entries[pos++] = new DataPoint(pumpStatus.getEventDate(), pumpStatus.getSgv() / MMOLXLFACTOR);
+                } else {
+                    entries[pos++] = new DataPoint(pumpStatus.getEventDate(), pumpStatus.getSgv());
+                }
             }
 
-            if (mChart.getData() == null) {
-                mChart.setMinimumHeight(200);
+            if (mChart.getSeries().size() == 0) {
+//                long now = System.currentTimeMillis();
+//                entries = new DataPoint[1000];
+//                int j = 0;
+//                for(long i = now - 24*60*60*1000; i < now - 30*60*1000; i+= 5*60*1000) {
+//                    entries[j++] = new DataPoint(i, (float) (Math.random()*200 + 89));
+//                }
+//                entries = Arrays.copyOfRange(entries, 0, j);
 
-                ScatterDataSet dataSet = new ScatterDataSet(entries, null);
+                PointsGraphSeries sgvSerie = new PointsGraphSeries(entries);
+//                sgvSerie.setSize(3.6f);
+//                sgvSerie.setColor(Color.LTGRAY);
 
-                //dataSet.setColors(colors); // disabled tue to a bug(??) in MPAndroid Chart
-                dataSet.setColor(Color.LTGRAY);
-                dataSet.setValueTextColor(Color.WHITE);
-                dataSet.setScatterShape(ScatterChart.ScatterShape.CIRCLE);
-                dataSet.setScatterShapeSize(7.2f);
-                dataSet.setValueFormatter(new IValueFormatter() {
-                    @Override
-                    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
-                        DecimalFormat df;
 
-                        if (prefs.getBoolean("mmolxl", false)) {
-                            if (prefs.getBoolean("mmolDecimals", false))
-                                df = new DecimalFormat("0.00");
-                            else
-                                df = new DecimalFormat("0.0");
+                sgvSerie.setOnDataPointTapListener(new OnDataPointTapListener() {
+                    DateFormat mFormat = DateFormat.getTimeInstance(DateFormat.MEDIUM);
+
+                    @Override
+                    public void onTap(Series series, DataPointInterface dataPoint) {
+                        double sgv = dataPoint.getY();
 
-                            return df.format(value / 18.016f);
+                        StringBuilder sb = new StringBuilder(mFormat.format(new Date((long) dataPoint.getX())) + ": ");
+                        if (mmolxl) {
+                            sb.append(sgvFormatter.format(sgv / MMOLXLFACTOR));
                         } else {
-                            return new DecimalFormat("0").format(value);
+                            sb.append(sgvFormatter.format(sgv));
                         }
+                        Toast.makeText(getBaseContext(), sb.toString(), Toast.LENGTH_SHORT).show();
                     }
                 });
 
-                ArrayList<IScatterDataSet> dataSets = new ArrayList<IScatterDataSet>();
-                dataSets.add(dataSet);
+                sgvSerie.setCustomShape(new PointsGraphSeries.CustomShape() {
+                    @Override
+                    public void draw(Canvas canvas, Paint paint, float x, float y, DataPointInterface dataPoint) {
+                        double sgv = dataPoint.getY();
+                        if (sgv < 80)
+                            paint.setColor(Color.RED);
+                        else if (sgv <= 180)
+                            paint.setColor(Color.GREEN);
+                        else if (sgv <= 260)
+                            paint.setColor(Color.YELLOW);
+                        else
+                            paint.setColor(Color.RED);
+                        canvas.drawCircle(x, y, 3.6f, paint);
+                    }
+                });
 
-                ScatterData lineData = new ScatterData(dataSets);
-                mChart.setData(lineData);
+                mChart.getViewport().setYAxisBoundsManual(false);
+                mChart.addSeries(sgvSerie);
             } else {
-                ((ScatterDataSet)mChart.getScatterData().getDataSets().get(0)).setValues(entries);
-                //((ScatterDataSet)mChart.getScatterData().getDataSets().get(0)).setColors(colors); // disabled tue to a bug(??) in MPAndroid Chart
-                //dataSet.notifyDataSetChanged();
+                if (entries.length > 0) {
+                    ((PointsGraphSeries) mChart.getSeries().get(0)).resetData(entries);
+                }
             }
 
-            //TODO: make the display timespan configurable
-            mChart.getXAxis().setAxisMaximum(System.currentTimeMillis());
-            mChart.getXAxis().setAxisMinimum(mChart.getXAxis().getAxisMaximum() - 24 * 60 * 60 * 1000);
-
-            mChart.postInvalidate();
+            // set vieport to latest SGV
+            long lastSGVTimestamp = (long) mChart.getSeries().get(0).getHighestValueX();
+            if (!hasZoomedChart) {
+                mChart.getViewport().setMaxX(lastSGVTimestamp);
+                mChart.getViewport().setMinX(lastSGVTimestamp - chartZoom * 60 * 60 * 1000);
+            }
         }
     }
 
@@ -905,31 +942,4 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc
         }
     }
 
-    private class PumsStatusDataSet extends RealmScatterDataSet<PumpStatusEvent> {
-
-        public PumsStatusDataSet(RealmResults<PumpStatusEvent> result, String yValuesField) {
-            super(result, yValuesField);
-        }
-
-        public PumsStatusDataSet(RealmResults<PumpStatusEvent> result, String xValuesField, String yValuesField) {
-            super(result, xValuesField, yValuesField);
-        }
-
-        public Entry buildEntryFromResultObject(PumpStatusEvent realmObject, float x) {
-            DynamicRealmObject dynamicObject = new DynamicRealmObject(realmObject);
-            float xFloat, yFloat;
-
-            if (mXValuesField == null) {
-                xFloat = x;
-            } else {
-                xFloat = dynamicObject.getDate(mXValuesField).getTime();
-            }
-            yFloat = dynamicObject.getInt(mYValuesField);
-
-            return new Entry(mXValuesField == null ? x : xFloat, yFloat);
-        }
-
-    }
-
-
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
index 07727c4258f768bdfcd2dac4175dfb36316a3a19..47c33dcf6a980e1a93dff4fb3ebefc40ecae3767 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
@@ -1,19 +1,25 @@
 package info.nightscout.android.medtronic.message;
 
+import android.util.Log;
+
 import java.nio.ByteBuffer;
 
 import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
 
+import info.nightscout.android.BuildConfig;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.utils.HexDump;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
 public class MedtronicResponseMessage extends ContourNextLinkResponseMessage {
+    private static final String TAG = MedtronicResponseMessage.class.getSimpleName();
+
     static int ENVELOPE_SIZE = 22;
     static int ENCRYPTED_ENVELOPE_SIZE = 3;
     static int CRC_SIZE = 2;
@@ -43,6 +49,11 @@ public class MedtronicResponseMessage extends ContourNextLinkResponseMessage {
             // Should be fine provided we check the CCITT first...
             this.mPayload.position(57);
             this.mPayload.put(decryptedPayload);
+
+            if (BuildConfig.DEBUG) {
+                String outputString = HexDump.dumpHexString(this.mPayload.array());
+                Log.d(TAG, "DECRYPTED: " + outputString);
+            }
         }
     }
 
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
index 4ef072df354fe1c0fb4ecdb5d72f3f4f0c1072fd..7afec5012a1f53eecf855cd4deb4ec78fc663d95 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
@@ -8,11 +8,13 @@ import java.nio.ByteOrder;
 import java.util.Date;
 import java.util.Locale;
 
+import info.nightscout.android.BuildConfig;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
 import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 import info.nightscout.android.model.medtronicNg.PumpStatusEvent;
+import info.nightscout.android.utils.HexDump;
 
 /**
  * Created by lgoedhart on 27/03/2016.
@@ -61,6 +63,10 @@ public class PumpStatusResponseMessage extends MedtronicSendMessageResponseMessa
         statusBuffer.order(ByteOrder.BIG_ENDIAN);
         statusBuffer.put(this.encode(), 0x39, 96);
 
+        if (BuildConfig.DEBUG) {
+            String outputString = HexDump.dumpHexString(statusBuffer.array());
+            Log.d(TAG, "PAYLOAD: " + outputString);
+        }
         // Status Flags
         suspended = ((statusBuffer.get(0x03) & 0x01) != 0x00);
         bolusing = ((statusBuffer.get(0x03) & 0x02) != 0x00);
@@ -108,9 +114,6 @@ public class PumpStatusResponseMessage extends MedtronicSendMessageResponseMessa
 
         // CGM SGV
         sgv = (statusBuffer.getShort(0x35) & 0x0000ffff); // In mg/DL. 0 means no CGM reading
-
-        // SGV Date
-
         if ((sgv & 0x200) == 0x200) {
             // Sensor error. Let's reset. FIXME - solve this more elegantly later
             sgv = 0;
@@ -123,6 +126,7 @@ public class PumpStatusResponseMessage extends MedtronicSendMessageResponseMessa
             cgmTrend = (PumpStatusEvent.CGM_TREND.fromMessageByte(statusBuffer.get(0x40)));
         }
 
+        // SGV Date
         // TODO - this should go in the sgvDate, and eventDate should be the time of this poll.
         sgvDate = MessageUtils.decodeDateTime(rtc, offset);
         Log.d(TAG, "original sgv date: " + sgvDate);
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
index 2e73205c360252e37063b29eb117aae34c1317a4..06d88ce206d0d88fa28fbda2bfb313c0d61131d6 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
@@ -6,9 +6,11 @@ import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Date;
 
+import info.nightscout.android.BuildConfig;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.utils.HexDump;
 
 /**
  * Created by lgoedhart on 27/03/2016.
@@ -30,6 +32,12 @@ public class PumpTimeResponseMessage extends MedtronicSendMessageResponseMessage
             ByteBuffer dateBuffer = ByteBuffer.allocate(8);
             dateBuffer.order(ByteOrder.BIG_ENDIAN);
             dateBuffer.put(this.encode(), 0x3d, 8);
+
+            if (BuildConfig.DEBUG) {
+                String outputString = HexDump.dumpHexString(dateBuffer.array());
+                Log.d(TAG, "PAYLOAD: " + outputString);
+            }
+
             long rtc = dateBuffer.getInt(0) & 0x00000000ffffffffL;
             long offset = dateBuffer.getInt(4);
             pumpTime = MessageUtils.decodeDateTime(rtc, offset);
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java
index 37805026764644405e1288684bc1a6eeb3a55b91..f77fc57a69cd621854f4712cecb57ab2b7d0b11d 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java
@@ -5,6 +5,7 @@ import android.util.Log;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
+import info.nightscout.android.BuildConfig;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
@@ -32,6 +33,10 @@ public class ReadHistoryInfoResponseMessage extends MedtronicSendMessageResponse
             basalRatesBuffer.order(ByteOrder.BIG_ENDIAN);
             basalRatesBuffer.put(this.encode());
 
+            if (BuildConfig.DEBUG) {
+                String outputString = HexDump.dumpHexString(basalRatesBuffer.array());
+                Log.d(TAG, "PAYLOAD: " + outputString);
+            }
             String responseString = HexDump.dumpHexString(basalRatesBuffer.array());
             Log.d(TAG, "ReadHistoryInfo: " + responseString);
             Log.d(TAG, "ReadHistoryInfo-length: " + basalRatesBuffer.getLong(28));
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
index d56b74b45e076b91467e9215d6b5a8bd92c0211f..9b041daf2e537086e1b164b90e5c80b9f34fd2e0 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
@@ -197,16 +197,14 @@ public class MedtronicCnlIntentService extends IntentService {
 
                 activePump.updateLastQueryTS();
 
-
                 byte radioChannel = cnlReader.negotiateChannel(activePump.getLastRadioChannel());
                 if (radioChannel == 0) {
                     sendStatus("Could not communicate with the 640g. Are you near the pump?");
                     Log.i(TAG, "Could not communicate with the 640g. Are you near the pump?");
 
                     // reduce polling interval to half until pump is available
-                    //TODO: make it configurable???
-                    MedtronicCnlAlarmManager.setAlarmAfterMillis(
-                            (MainActivity.pollInterval  + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS) / (MainActivity.reducePollOnPumpAway?2L:1L)
+                    MedtronicCnlAlarmManager.setAlarm(activePump.getLastQueryTS() +
+                            (MainActivity.pollInterval / (MainActivity.reducePollOnPumpAway?2L:1L))
                     );
                 } else {
                     setActivePumpMac(pumpMAC);
diff --git a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
index 60ad396bfba9043268d5e65486dee173f711d6ee..cfe52c2cf6dd3ea601171455a3b5ca1adf67b851 100644
--- a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
+++ b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
@@ -1,7 +1,5 @@
 package info.nightscout.android.model.medtronicNg;
 
-import com.github.mikephil.charting.interfaces.datasets.IScatterDataSet;
-
 import java.util.Date;
 
 import io.realm.RealmObject;
diff --git a/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java b/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
index d14c7ed19af7df4025bd0731227abfecfb380208..cbabb6a4ec7e9a497f487642f0fd8f1f06ccf3da 100644
--- a/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
+++ b/app/src/main/java/info/nightscout/android/settings/SettingsFragment.java
@@ -51,8 +51,7 @@ public class SettingsFragment extends PreferenceFragment implements OnSharedPref
      */
     private void setMinBatPollIntervall(ListPreference pollIntervalPref, ListPreference lowBatPollIntervalPref) {
         final String currentValue = lowBatPollIntervalPref.getValue();
-        final int pollIntervalPos = pollIntervalPref.findIndexOfValue(pollIntervalPref.getValue()),
-                lowBatPollIntervalPos = lowBatPollIntervalPref.findIndexOfValue(currentValue),
+        final int pollIntervalPos = (pollIntervalPref.findIndexOfValue(pollIntervalPref.getValue()) >= 0?pollIntervalPref.findIndexOfValue(pollIntervalPref.getValue()):0),
                 length = pollIntervalPref.getEntries().length;
 
         CharSequence[] entries = new String[length - pollIntervalPos],
diff --git a/app/src/main/java/info/nightscout/android/utils/HexDump.java b/app/src/main/java/info/nightscout/android/utils/HexDump.java
index 0f7ccab2c47d427c20c4b3c02fa61d476fe9e3ff..ff441ced24ba8bc11f04cc1a57f7ec99a032302a 100644
--- a/app/src/main/java/info/nightscout/android/utils/HexDump.java
+++ b/app/src/main/java/info/nightscout/android/utils/HexDump.java
@@ -35,7 +35,12 @@ public class HexDump {
         byte[] line = new byte[16];
         int lineIndex = 0;
 
+        result.append("\n          ");
+        for (int i = 0; i < Math.min(16, array.length); i++) {
+            result.append(" ?" + HEX_DIGITS[i]);
+        }
         result.append("\n0x");
+
         result.append(toHexString(offset));
 
         for (int i = offset; i < offset + length; i++) {
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 1360a2b54f3cdb032af6023402f818de2b39e7f6..95148622918e6cc996d1ce7e5c3075d7ff3e399a 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -119,11 +119,10 @@
 
     </LinearLayout>
 
-    <com.github.mikephil.charting.charts.ScatterChart
-        android:id="@+id/chart"
+    <com.jjoe64.graphview.GraphView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:visibility="visible" />
+        android:layout_height="100dip"
+        android:id="@+id/chart" />
 
     <ScrollView
         android:id="@+id/scrollView"
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index d84a02f6bb920f7d4afe27e28ed60ab9cba5f38b..cfb3458e897140a9308cac32f15041128630caad 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -21,4 +21,20 @@
         <item>3600000</item>
         <!--item>0</item-->
     </string-array>
+
+    <string-array name="chart_zoom">
+        <item>1 hour</item>
+        <item>3 hours</item>
+        <item>6 hours</item>
+        <item>12 hours</item>
+        <item>24 hours</item>
+    </string-array>
+
+    <string-array name="chart_zoom_hours">
+        <item>1</item>
+        <item>3</item>
+        <item>6</item>
+        <item>12</item>
+        <item>24</item>
+    </string-array>
 </resources>
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 48268a1e642c4b34d2d4e52b74dbdd9963f34731..580e85d04a9bbe67a3b112aa026ec9c260224707 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -57,4 +57,5 @@
     <string name="no_registered_contour_next_link_devices">No registered Contour Next Link devices</string>
     <string name="to_register_a_contour_next_link_you_must_first_plug_it_in_and_get_a_reading_from_the_pump">To register a Contour Next Link you must first plug it in, and get a reading from the pump.</string>
     <string name="serial_number">Serial number</string>
+    <string name="preferences_chart_interval">Chart Zoom</string>
 </resources>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 0183e9581d19c4460d5007c0d754336c9a092668..de93838a97ceafac7a7701ecfbb6ee914ed9c5c3 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -41,6 +41,15 @@
             android:entries="@array/poll_interval"
             android:entryValues="@array/poll_interval_millis"/>
     </PreferenceCategory>
+    <PreferenceCategory android:title="Display">
+    <ListPreference
+        android:key="chartZoom"
+        android:defaultValue="3"
+        android:title="@string/preferences_chart_interval"
+        android:summary="%s"
+        android:entries="@array/chart_zoom"
+        android:entryValues="@array/chart_zoom_hours"/>
+    </PreferenceCategory>
     <PreferenceCategory android:title="Sharing">
         <CheckBoxPreference
             android:disableDependentsState="false"