Skip to content
Browse files

Working "offline" support using EEPROM to save session data

The session activity data will be saved every minute to the Arduino's
EEPROM and before uploading.

If uploading fail or the Arduino lose power during a workout session,
it'll try to upload the saved data during next boot.
  • Loading branch information...
1 parent 7c5f7fd commit 04effd5e7fa32c755a60a60217bb24de059207c5 @reefab committed
Showing with 84 additions and 91 deletions.
  1. +59 −38 Bike/Bike.ino
  2. +0 −10 Bike/ntp.h
  3. +25 −40 Bike/persistent.h
  4. +0 −3 Bike/runkeeper.h
View
97 Bike/Bike.ino
@@ -34,7 +34,7 @@ EthernetClient client;
#include "config.h"
#include "runkeeper.h"
#include "ntp.h"
-//#include "persistent.h"
+#include "persistent.h"
// This needs to be pin 2 to use interrupt 0
#define reedPin 2
@@ -56,6 +56,8 @@ EthernetClient client;
#define maxTime 120
// Change the data displayed on the second line of the lcd every X seconds
#define changeSecondLine 5
+// Save session data every X seconds
+#define saveInterval 60
// Global Vars
unsigned int nbRotation = 0;
@@ -68,6 +70,7 @@ unsigned long enterLoop = 0;
unsigned long exitLoop = 0;
unsigned long time_elasped = 0;
unsigned long effectiveTime = 0;
+unsigned long lastSave = 0;
volatile boolean backlight = false;
volatile boolean paused = false;
volatile boolean resetRequested = false;
@@ -85,16 +88,15 @@ boolean uploaded = false;
// Messages
#define msg_start " Starting up."
#define msg_ipget "Getting IP..."
-#define msg_ethfail1 "Failed to configure"
-#define msg_ethfail2 "Ethernet using DHCP"
+#define msg_ethfail "Eth Failure"
#define msg_savedact1 "Prev. act. found"
#define msg_savedact2 "Updlng prv. act."
-int freeRam () {
- extern int __heap_start, *__brkval;
- int v;
- return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
-}
+//int freeRam () {
+// extern int __heap_start, *__brkval;
+// int v;
+// return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
+//}
void setup() {
Serial.begin(9600);
@@ -111,30 +113,38 @@ void setup() {
// start Ethernet
if (Ethernet.begin(mac) == 0) {
lcd.clear();
- lcd.print(msg_ethfail1);
- lcd.setCursor(0, 1);
- lcd.print(msg_ethfail2);
- delay(50000);
+ lcd.print(msg_ethfail);
+ delay(50000000);
}
else {
setStartTime();
- //startTimeStr = getTimeString();
- displayInitScreen();
+ delay(1000);
+ // Retry if unable to get time from NTP
+ if (year() == 1970) {
+ while(year() == 1970){
+ delay(10000);
+ lcd.clear();
+ lcd.print("Retrying ...");
+ setStartTime();
+ }
+ }
+ //displayInitScreen();
+ }
+ // Upload saved session if present
+ if (savePresent()) {
+ lcd.clear();
+ lcd.print(msg_savedact1);
+ lcd.setCursor(0, 1);
+ lcd.print(msg_savedact2);
+ lcd.clear();
+ uploaded = uploadResult(getSavedStartTimeStr(), getSavedDistance(), getSavedTime());
+ if(uploaded) {
+ resetRequested=true;
+ eraseProgress();
+ lcd.print("Saved data uploaded");
+ delay(1000);
+ }
}
-// if (savePresent()) {
-// lcd.clear();
-// lcd.print(msg_savedact1);
-// lcd.setCursor(0, 1);
-// lcd.print(msg_savedact2);
-// Serial.print("Time: ");
-// Serial.println(getSavedTime(), DEC);
-// Serial.print("Distance: ");
-// Serial.println(getSavedDistance(), DEC);
-// Serial.print("Start Time: ");
-// Serial.println(getSavedStartTimeStr());
-// delay(1000);
-// eraseProgress();
-// }
lcd.clear();
lastReedPress = millis();
@@ -172,13 +182,16 @@ void loop() {
lcd.setCursor(0, 0);
lcd.print(" Activity ended ");
delay(500);
-// lcd.clear();
-// saveProgress(startTimeStr, totalDistance, effectiveTime);
-// lcd.print(" Activity saved ");
-// delay(500);
+ lcd.clear();
+ saveProgress(startTimeStr, totalDistance, effectiveTime);
+ lcd.print(" Activity saved ");
+ delay(500);
lcd.clear();
uploaded = uploadResult(startTimeStr, totalDistance, effectiveTime);
- if(uploaded) resetRequested=true;
+ if(uploaded) {
+ resetRequested=true;
+ eraseProgress();
+ }
delay(5000);
switchBacklight(false);
}
@@ -186,7 +199,10 @@ void loop() {
// Activity in progres
// Start a new session if requested
if (resetRequested) {
- if (start) firstLine = "Activity started";
+ if (start) {
+ lcd.setCursor(0, 0);
+ lcd.print("Activity started");
+ }
delay(250);
reset(start);
delay(250);
@@ -232,13 +248,18 @@ void loop() {
delay(5000);
switchBacklight(false);
resetRequested = true;
+ eraseProgress();
}
}
-// Serial.println("\n[free RAM]");
+ // Save session data regularly
+ if((millis() - lastSave) < ((unsigned long) 1000 * saveInterval)) {
+ saveProgress(startTimeStr, totalDistance, effectiveTime);
+ lastSave = millis();
+ }
+
+ //Serial.println("\n[free RAM]");
//Serial.println(freeRam());
- //Serial.println(getTimeString());
- Serial.println(rotationCount);
-
+
displayInfo();
}
}
View
10 Bike/ntp.h
@@ -1,13 +1,3 @@
-#define SECS_PER_MIN (60UL)
-#define SECS_PER_HOUR (3600UL)
-#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
-
-/* Useful Macros for getting elapsed time */
-#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
-#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
-#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
-#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)
-
// NTP
const unsigned int localPort = 8888; // local port to listen for UDP packets
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
View
65 Bike/persistent.h
@@ -1,67 +1,52 @@
-//#include <EEPROM.h>
-
-void saveProgress(String startTimeStr, unsigned int totalDistance, unsigned long effectiveTime, unsigned int offset=1) {
+void saveProgress(String startTimeStr, unsigned int totalDistance, unsigned long effectiveTime,boolean erase=false) {
unsigned int time = effectiveTime / 1000UL;
int str_size = startTimeStr.length();
// To indicate a save is present
- EEPROM.write(0, 1);
+ if (erase) {
+ EEPROM.write(0, 0);
+ } else {
+ EEPROM.write(0, 1);
+ }
- EEPROM.write(offset, highByte(time));
- EEPROM.write(offset + 1, lowByte(time));
- EEPROM.write(offset + 2, highByte(totalDistance));
- EEPROM.write(offset + 3, lowByte(totalDistance));
- EEPROM.write(offset + 4, str_size);
+ EEPROM.write(1, highByte(time));
+ EEPROM.write(2, lowByte(time));
+ EEPROM.write(3, highByte(totalDistance));
+ EEPROM.write(4, lowByte(totalDistance));
+ EEPROM.write(5, str_size);
- for (int i = 0;i <= str_size;i++)
+ for (int i = 0;i < str_size;i++)
{
- EEPROM.write(offset + 5 + i, startTimeStr.charAt(i));
+ EEPROM.write(6 + i, startTimeStr.charAt(i));
}
}
-void eraseProgress(unsigned int offset=1) {
- EEPROM.write(offset, 0);
- EEPROM.write(offset + 1, 0);
- EEPROM.write(offset + 2, 0);
- EEPROM.write(offset + 3, 0);
- int str_size = EEPROM.read(offset + 4);
- EEPROM.write(offset + 4, 0);
-
- for (int i = 0;i <= str_size;i++)
- {
- EEPROM.write(offset + 5 + i, 0);
- }
- // Finaly remove the byte that indicate a save is present
- EEPROM.write(0, 0);
+void eraseProgress() {
+ saveProgress("", 0, 0, true);
}
boolean savePresent() {
- if (EEPROM.read(0) > 0) {
- return true;
- }
- else {
- return false;
- }
+ return (EEPROM.read(0) > 0);
}
-unsigned long getSavedTime(unsigned int offset=1) {
+unsigned long getSavedTime() {
unsigned int time;
- time = word(EEPROM.read(offset), EEPROM.read(offset + 1));
+ time = word(EEPROM.read(1), EEPROM.read(2));
return time * 1000UL;
}
-unsigned int getSavedDistance(unsigned int offset=1) {
- return word(EEPROM.read(offset + 2), EEPROM.read(offset + 3));
+unsigned int getSavedDistance() {
+ return word(EEPROM.read(3), EEPROM.read(4));
}
-String getSavedStartTimeStr(unsigned int offset=1) {
- int str_size = EEPROM.read(offset + 4);
- String str_time;
- for (int i = 0;i <= str_size;i++)
+String getSavedStartTimeStr() {
+ int str_size = EEPROM.read(5);
+ String str_time = "";
+ for (int i = 0;i < str_size;i++)
{
- str_time += char(EEPROM.read(offset + 5 + i));
+ str_time += char(EEPROM.read(6 + i));
}
return str_time;
}
View
3 Bike/runkeeper.h
@@ -6,9 +6,6 @@
* Author: reefab
*/
-#include <Arduino.h>
-#include <HTTPClient.h>
-
byte serverIp[] = {
74,50,63,142};
#define apiServer "api.runkeeper.com"

0 comments on commit 04effd5

Please sign in to comment.
Something went wrong with that request. Please try again.