diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java index f777b63b0..c2e32f92e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java @@ -29,240 +29,14 @@ import android.content.Context; import android.content.SharedPreferences; import android.util.Log; -import java.util.LinkedList; - /** * A sensor manager to connect ANT+ sensors. - * This can include heart rate monitors. * * @author Sandor Dornbush * @author Laszlo Molnar */ -public class AntDirectSensorManager extends AntSensorManager { - - /* - * These constants are defined by the ANT+ spec. - */ - public static final byte NETWORK_NUMBER = 1; - public static final byte RF_FREQUENCY = 57; - - public abstract class AntSensorBase { - - protected byte channel; - protected short deviceNumber; - private byte deviceType; - private short channelPeriod; - - AntSensorBase(byte channel, short deviceNumber, byte deviceType, - String deviceTypeString, short channelPeriod) { - this.channel = channel; - this.deviceNumber = deviceNumber; - this.deviceType = deviceType; - this.channelPeriod = channelPeriod; - - Log.i(TAG, "Will pair with " + deviceTypeString + " device: " + ((int) deviceNumber & 0xFFFF)); - } - - protected void resolveWildcardDeviceNumber() { - if (!isPaired()) { - try { - getAntReceiver().ANTRequestMessage(channel, AntMesg.MESG_CHANNEL_ID_ID); - } catch (AntInterfaceException e) { - Log.e(TAG, "ANT error handling broadcast data", e); - } - Log.d(TAG, "Requesting channel id id on channel: " + channel); - } - } - - public abstract void handleBroadcastData(byte[] antMessage); - - public boolean setupChannel() { - Log.i(TAG, "ant sensor setupChannel " + channel + " " + deviceType); - - return setupAntSensorChannel(NETWORK_NUMBER, channel, deviceNumber, - deviceType, (byte) 0x01, channelPeriod, - RF_FREQUENCY, (byte) 0); - } - - public void setDeviceNumber(short dn) { - deviceNumber = dn; - } - - public boolean isPaired() { - return deviceNumber != WILDCARD; - } - }; - - // Heart reate monitor sensor - public class HeartRateSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ heart rate monitor spec. - */ - public static final byte HEART_RATE_DEVICE_TYPE = 120; - public static final short HEART_RATE_CHANNEL_PERIOD = 8070; - - HeartRateSensor(byte channel, short devNum) { - super(channel, devNum, HEART_RATE_DEVICE_TYPE, - "heart rate monitor", HEART_RATE_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ heart rate monitor message. - * @param antMessage The byte array received from the heart rate monitor. - */ - public void handleBroadcastData(byte[] antMessage) { - resolveWildcardDeviceNumber(); - - int bpm = (int) antMessage[8] & 0xFF; - Log.d(TAG, "now:" + System.currentTimeMillis() + " heart rate=" + bpm); - sendHeartRate(bpm); - } - }; - - /** - * Processes an ANT sensor data + timestamp pair, - * and returns the instantaneous value of the sensor - */ - public class SensorDataProcessor { - - /** - * History is used for looking back at the old data - * when no new data is present, but an instantaneous value is needed - */ - private class HistoryElement { - public long sysTime; - public int data; - public int sensorTime; - - HistoryElement(long sys, int d, int sens) { - sysTime = sys; - data = d; - sensorTime = sens; - } - }; - - // Removes old data from the history. - // Returns true if the remaining history is not empty. - protected boolean removeOldHistory(long now) { - HistoryElement h; - while ((h = history.peek()) != null) { - if (now - h.sysTime <= historyLengthMillis) { - return true; - } - history.removeFirst(); - } - return false; - } - - private int counter = -1; // the latest counter value reported by the sensor - private int actValue = 0; - public static final int historyLengthMillis = 5000; // 5 sec - private LinkedList history = new LinkedList(); - - public int getValue(int data, int sensorTime) { - long now = System.currentTimeMillis(); - int dDelta = (data - counter) & 0xFFFF; - - Log.d(TAG, "now=" + now + " data=" + data + " sensortime=" + sensorTime); - - if (counter < 0) { - // store the actual counter value from the sensor - counter = data; - return actValue = 0; - } - counter = data; - - if (dDelta != 0) { - if (removeOldHistory(now)) { - HistoryElement h = history.getLast(); - actValue = ((int) ((data - h.data) & 0xFFFF)) * 1024 * 60 - / (int) ((sensorTime - h.sensorTime) & 0xFFFF); - } - history.addLast(new HistoryElement(now, data, sensorTime)); - } else if (!history.isEmpty()) { - HistoryElement h = history.getLast(); - if (60000 < (now - h.sysTime) * actValue) { - if (!removeOldHistory(now)) { - actValue = 0; - } else { - HistoryElement f = history.getFirst(); - HistoryElement l = history.getLast(); - int sDelta = (l.sensorTime - f.sensorTime) & 0xFFFF; - int cDelta = (data - f.data) & 0xFFFF; - - // the saved actValue is not overwritten by this - // the returned value is computed from the history - int v = (int) (cDelta * 60 * 1000 / (now - l.sysTime + (sDelta / 1024) * 1000)); - Log.d(TAG, "getValue returns (2):" + v); - return v < actValue ? v : actValue; - } - } else { - // the current actValue is still valid, nothing to do here - } - } else { - actValue = 0; - } - - Log.d(TAG, "getValue returns:" + actValue); - return actValue; - } - } - - // Cadence sensor - public class CadenseSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ bike speed and cadence sensor spec. - */ - public static final byte CADENCE_DEVICE_TYPE = 122; - public static final short CADENCE_CHANNEL_PERIOD = 8102; - - SensorDataProcessor cadence = new SensorDataProcessor(); - - CadenseSensor(byte channel, short devNum) { - super(channel, devNum, CADENCE_DEVICE_TYPE, - "cadence sensor", CADENCE_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ cadence sensor message. - * @param antMessage The byte array received from the cadence sensor. - */ - public void handleBroadcastData(byte[] antMessage) { - resolveWildcardDeviceNumber(); - - int sensorTime = ((int) antMessage[5] & 0xFF) + ((int) antMessage[6] & 0xFF) * 256; - int crankRevs = ((int) antMessage[7] & 0xFF) + ((int) antMessage[8] & 0xFF) * 256; - sendCadence(cadence.getValue(crankRevs, sensorTime)); - } - }; - - // Combined cadence and speed sensor - public class CadenceSpeedSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ bike speed and cadence sensor spec. - */ - public static final byte CADENCE_SPEED_DEVICE_TYPE = 121; - public static final short CADENCE_SPEED_CHANNEL_PERIOD = 8086; - - SensorDataProcessor cadence = new SensorDataProcessor(); - - CadenceSpeedSensor(byte channel, short devNum) { - super(channel, devNum, CADENCE_SPEED_DEVICE_TYPE, - "speed&cadence sensor", CADENCE_SPEED_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ cadence&speed sensor message. - * @param antMessage The byte array received from the sensor. - */ - public void handleBroadcastData(byte[] antMessage) { - resolveWildcardDeviceNumber(); - - int sensorTime = ((int) antMessage[1] & 0xFF) + ((int) antMessage[2] & 0xFF) * 256; - int crankRevs = ((int) antMessage[3] & 0xFF) + ((int) antMessage[4] & 0xFF) * 256; - sendCadence(cadence.getValue(crankRevs, sensorTime)); - } - }; +public class AntDirectSensorManager extends AntSensorManager + implements AntSensorDataCollector { // allocating one channel for each sensor type private static final byte HEART_RATE_CHANNEL = 0; @@ -305,7 +79,10 @@ public class AntDirectSensorManager extends AntSensorManager { AntSensorBase sensor = sensors[channel]; switch (messageId) { case AntMesg.MESG_BROADCAST_DATA_ID: - sensor.handleBroadcastData(messageData); + if (sensor.getDeviceNumber() == WILDCARD) { + resolveWildcardDeviceNumber((byte) channel); + } + sensor.handleBroadcastData(messageData, this); break; case AntMesg.MESG_RESPONSE_EVENT_ID: handleMessageResponse(messageData); @@ -320,7 +97,7 @@ public class AntDirectSensorManager extends AntSensorManager { return true; } - short handleChannelId(byte[] rawMessage) { + private short handleChannelId(byte[] rawMessage) { AntChannelIdMessage message = new AntChannelIdMessage(rawMessage); short deviceNumber = message.getDeviceNumber(); byte channel = message.getChannelNumber(); @@ -347,9 +124,9 @@ public class AntDirectSensorManager extends AntSensorManager { connectingChannelsBitmap &= ~(1 << channel); Log.i(TAG, "ANT channel " + channel + " disconnected."); - if (sensors[channel].isPaired()) { + if (sensors[channel].getDeviceNumber() != WILDCARD) { Log.i(TAG, "Retrying...."); - if (sensors[channel].setupChannel()) { + if (setupChannel(sensors[channel], channel)) { connectingChannelsBitmap |= 1 << channel; } } @@ -381,6 +158,15 @@ public class AntDirectSensorManager extends AntSensorManager { } } + private void resolveWildcardDeviceNumber(byte channel) { + try { + getAntReceiver().ANTRequestMessage(channel, AntMesg.MESG_CHANNEL_ID_ID); + } catch (AntInterfaceException e) { + Log.e(TAG, "ANT error handling broadcast data", e); + } + Log.d(TAG, "Requesting channel id id on channel: " + channel); + } + @Override protected void setupAntSensorChannels() { short devIds[] = new short[sensorIdKeys.length]; @@ -394,14 +180,14 @@ public class AntDirectSensorManager extends AntSensorManager { } sensors = new AntSensorBase[] { - new HeartRateSensor(HEART_RATE_CHANNEL, devIds[HEART_RATE_CHANNEL]), - new CadenseSensor(CADENCE_CHANNEL, devIds[CADENCE_CHANNEL]), - new CadenceSpeedSensor(CADENCE_SPEED_CHANNEL, devIds[CADENCE_SPEED_CHANNEL]), + new HeartRateSensor(devIds[HEART_RATE_CHANNEL]), + new CadenceSensor(devIds[CADENCE_CHANNEL]), + new CadenceSpeedSensor(devIds[CADENCE_SPEED_CHANNEL]), }; connectingChannelsBitmap = 0; for (int i = 0; i < sensors.length; ++i) { - if (sensors[i].setupChannel()) { + if (setupChannel(sensors[i], (byte) i)) { connectingChannelsBitmap |= 1 << i; } } @@ -410,6 +196,19 @@ public class AntDirectSensorManager extends AntSensorManager { } } + private boolean setupChannel(AntSensorBase sensor, byte channel) { + Log.i(TAG, "setup channel=" + channel + " deviceType=" + sensor.getDeviceType()); + + return setupAntSensorChannel(sensor.getNetworkNumber(), + channel, + sensor.getDeviceNumber(), + sensor.getDeviceType(), + (byte) 0x01, + sensor.getChannelPeriod(), + sensor.getFrequency(), + (byte) 0); + } + private void sendSensorData(byte index, int value) { if (index >= currentSensorData.length) { Log.w(TAG, "invalid index in sendSensorData:" + index); diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java new file mode 100644 index 000000000..4212eed72 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + +import static com.google.android.apps.mytracks.Constants.TAG; + +import android.util.Log; + +/** + * Base class for ANT+ sensors. + * + * @author Laszlo Molnar + */ + +public abstract class AntSensorBase { + /* + * These constants are defined by the ANT+ spec. + */ + public static final byte NETWORK_NUMBER = 1; + public static final byte RF_FREQUENCY = 57; + + protected short deviceNumber; + private byte deviceType; + private short channelPeriod; + + AntSensorBase(short deviceNumber, byte deviceType, + String deviceTypeString, short channelPeriod) { + this.deviceNumber = deviceNumber; + this.deviceType = deviceType; + this.channelPeriod = channelPeriod; + + Log.i(TAG, "Will pair with " + deviceTypeString + " device: " + ((int) deviceNumber & 0xFFFF)); + } + + public abstract void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c); + + public void setDeviceNumber(short dn) { + deviceNumber = dn; + } + + public short getDeviceNumber() { + return deviceNumber; + } + + public byte getNetworkNumber() { + return NETWORK_NUMBER; + } + + public byte getFrequency() { + return RF_FREQUENCY; + } + + public byte getDeviceType() { + return deviceType; + } + + public short getChannelPeriod() { + return channelPeriod; + } +}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java new file mode 100644 index 000000000..88990a65a --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java @@ -0,0 +1,30 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + +/** + * Interface for collecting data from the sensor classes + * + * @author Laszlo Molnar + */ + +public interface AntSensorDataCollector { + + public void sendCadence(int value); + + public void sendHeartRate(int value); +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java new file mode 100644 index 000000000..1cc557a78 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + + +/** + * Cadence sensor. + * + * @author Laszlo Molnar + */ + +public class CadenceSensor extends AntSensorBase { + /* + * These constants are defined by the ANT+ bike speed and cadence sensor spec. + */ + public static final byte CADENCE_DEVICE_TYPE = 122; + public static final short CADENCE_CHANNEL_PERIOD = 8102; + + SensorDataProcessor cadence = new SensorDataProcessor(); + + CadenceSensor(short devNum) { + super(devNum, CADENCE_DEVICE_TYPE, + "cadence sensor", CADENCE_CHANNEL_PERIOD); + } + + /** + * Decode an ANT+ cadence sensor message. + * @param antMessage The byte array received from the cadence sensor. + */ + public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { + int sensorTime = ((int) antMessage[5] & 0xFF) + ((int) antMessage[6] & 0xFF) * 256; + int crankRevs = ((int) antMessage[7] & 0xFF) + ((int) antMessage[8] & 0xFF) * 256; + c.sendCadence(cadence.getValue(crankRevs, sensorTime)); + } +}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java new file mode 100644 index 000000000..1331fea66 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + + +/** + * Combined cadence and speed sensor. + * + * @author Laszlo Molnar + */ + +public class CadenceSpeedSensor extends AntSensorBase { + /* + * These constants are defined by the ANT+ bike speed and cadence sensor spec. + */ + public static final byte CADENCE_SPEED_DEVICE_TYPE = 121; + public static final short CADENCE_SPEED_CHANNEL_PERIOD = 8086; + + SensorDataProcessor cadence = new SensorDataProcessor(); + + CadenceSpeedSensor(short devNum) { + super(devNum, CADENCE_SPEED_DEVICE_TYPE, + "speed&cadence sensor", CADENCE_SPEED_CHANNEL_PERIOD); + } + + /** + * Decode an ANT+ cadence&speed sensor message. + * @param antMessage The byte array received from the sensor. + */ + public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { + int sensorTime = ((int) antMessage[1] & 0xFF) + ((int) antMessage[2] & 0xFF) * 256; + int crankRevs = ((int) antMessage[3] & 0xFF) + ((int) antMessage[4] & 0xFF) * 256; + c.sendCadence(cadence.getValue(crankRevs, sensorTime)); + } +}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java new file mode 100644 index 000000000..a1331578f --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + +import static com.google.android.apps.mytracks.Constants.TAG; + +import android.util.Log; + +/** + * Heart reate monitor sensor. + * + * @author Laszlo Molnar + */ + +public class HeartRateSensor extends AntSensorBase { + /* + * These constants are defined by the ANT+ heart rate monitor spec. + */ + public static final byte HEART_RATE_DEVICE_TYPE = 120; + public static final short HEART_RATE_CHANNEL_PERIOD = 8070; + + HeartRateSensor(short devNum) { + super(devNum, HEART_RATE_DEVICE_TYPE, + "heart rate monitor", HEART_RATE_CHANNEL_PERIOD); + } + + /** + * Decode an ANT+ heart rate monitor message. + * @param antMessage The byte array received from the heart rate monitor. + */ + public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { + int bpm = (int) antMessage[8] & 0xFF; + Log.d(TAG, "now:" + System.currentTimeMillis() + " heart rate=" + bpm); + c.sendHeartRate(bpm); + } +}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorDataProcessor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorDataProcessor.java new file mode 100644 index 000000000..9306aeb3f --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorDataProcessor.java @@ -0,0 +1,111 @@ +/* + * Copyright 2012 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.android.apps.mytracks.services.sensors.ant; + +import static com.google.android.apps.mytracks.Constants.TAG; +import android.util.Log; +import java.util.LinkedList; + +/** + * Processes an ANT sensor data (counter) + timestamp pair, + * and returns the instantaneous value of the sensor + * + * @author Laszlo Molnar + */ +public class SensorDataProcessor { + + /** + * History is used for looking back at the old data + * when no new data is present, but an instantaneous value is needed + */ + private class HistoryElement { + public long sysTime; + public int data; + public int sensorTime; + + HistoryElement(long sys, int d, int sens) { + sysTime = sys; + data = d; + sensorTime = sens; + } + }; + + // Removes old data from the history. + // Returns true if the remaining history is not empty. + protected boolean removeOldHistory(long now) { + HistoryElement h; + while ((h = history.peek()) != null) { + if (now - h.sysTime <= historyLengthMillis) { + return true; + } + history.removeFirst(); + } + return false; + } + + private int counter = -1; // the latest counter value reported by the sensor + private int actValue = 0; + public static final int historyLengthMillis = 5000; // 5 sec + private LinkedList history = new LinkedList(); + + public int getValue(int data, int sensorTime) { + long now = System.currentTimeMillis(); + int dDelta = (data - counter) & 0xFFFF; + + Log.d(TAG, "now=" + now + " data=" + data + " sensortime=" + sensorTime); + + if (counter < 0) { + // store the actual counter value from the sensor + counter = data; + return actValue = 0; + } + counter = data; + + if (dDelta != 0) { + if (removeOldHistory(now)) { + HistoryElement h = history.getLast(); + actValue = ((int) ((data - h.data) & 0xFFFF)) * 1024 * 60 + / (int) ((sensorTime - h.sensorTime) & 0xFFFF); + } + history.addLast(new HistoryElement(now, data, sensorTime)); + } else if (!history.isEmpty()) { + HistoryElement h = history.getLast(); + if (60000 < (now - h.sysTime) * actValue) { + if (!removeOldHistory(now)) { + actValue = 0; + } else { + HistoryElement f = history.getFirst(); + HistoryElement l = history.getLast(); + int sDelta = (l.sensorTime - f.sensorTime) & 0xFFFF; + int cDelta = (data - f.data) & 0xFFFF; + + // the saved actValue is not overwritten by this + // the returned value is computed from the history + int v = (int) (cDelta * 60 * 1000 / (now - l.sysTime + (sDelta / 1024) * 1000)); + Log.d(TAG, "getValue returns (2):" + v); + return v < actValue ? v : actValue; + } + } else { + // the current actValue is still valid, nothing to do here + } + } else { + actValue = 0; + } + + Log.d(TAG, "getValue returns:" + actValue); + return actValue; + } +}