Permalink
Browse files

Merge branch 'refs/heads/master' into develop

Conflicts:
	.gitignore
  • Loading branch information...
2 parents cc6cadd + 9a298fd commit 15b2be4b4846620094eb94b845803620a08a3862 @reefab committed Mar 3, 2013
View
@@ -2,35 +2,34 @@
## Description
-This project provides an [Arduino](http://arduino.cc/) sketch that can power an Arduino + Ethernet Shield (or Arduino with built-in ethernet) to make a stationary bike computer that can upload Cycling workout sessions results to [Runkeeper](http://runkeeper.com/)'s [Healthgraph API](http://developer.runkeeper.com/healthgraph), where it get added to the user's activities feed.
-The activity can then be posted to Twitter or Facebook automatically by Runkeeper.
+This project provides an [Arduino](http://arduino.cc/) sketch that can power an Arduino + Ethernet Shield (or Arduino with built-in ethernet)
+to make a stationary bike computer that can upload Cycling workout sessions results to [Runkeeper](http://runkeeper.com/)'s [Healthgraph API](http://developer.runkeeper.com/healthgraph).
+This activity get added to the user's activities feed and could then be posted to Twitter or Facebook automatically by Runkeeper.
-It doesn't need to be connected to a computer for that purpose, only a wired ethernet connection + DHCP is required.
+It doesn't need to be connected to a computer for that purpose, only a wired ethernet connection is required.
-It'll also display either current speed and total distance or average speed and elapsed time during normal use via a LCD.
+It'll also display the current speed and either the total distance or average speed or elapsed time during normal use via a LCD.
The sensor used is the [reed switch](http://en.wikipedia.org/wiki/Reed_switch) that was already present in my stationary bike connected to the Arduino with a pulldown resistor.
-The elapsed time only counts 15 seconds chunks when there was some activity, otherwise it'll pause.
+The elapsed time only counts 15 seconds chunks when there was some activity, otherwise it'll pause automatically.
-If the pause last more than 5 minutes, it'll upload to Runkeeper the:
+If the pause last more than 2 minutes, it'll upload to Runkeeper the:
* Starting Time
* Total Distance
* Elapsed Time
-for the current session. From this, Runkeeper computes the average speed, pace and
-total calories burned.
+for the current session. From this, Runkeeper computes the average speed, pace and total calories burned.
## Usage
Plug the ethernet cable and the USB/Power cable in.
-The Arduino will beep once it has obtained the current time and is ready for
-use.
+The Arduino will beep once it has obtained the current time and is ready for use.
Pedal away and it'll display the current speed while cycling between the total distance. average speed and elapsed time.
-Stop pedaling for ~ 15 seconds and the pause screen will come up. 60 seconds, the lcd's backlight will be switched off. 5 minutes and it'll end the session and upload the result or discard the session if the "valid activity" threshold hasn't been reached.
+Stop pedaling for ~ 15 seconds and the pause screen will come up. 60 seconds, the lcd's backlight will be switched off. 2 minutes and it'll end the session and upload the result or discard the session if the "valid activity" threshold hasn't been reached.
It'll beep every 5km by default.
@@ -41,10 +40,9 @@ To start a new session, just use the bike again, it'll start over.
### Device
![Device in clear enclosure](https://github.com/reefab/CyclingPusher/raw/master/images/finishedVersion.jpg)
[Prototype during testing](https://github.com/reefab/CyclingPusher/raw/master/images/prototype.jpg)
-### Runkeeper's screenshot
+[Stationary bike's reed switch and magnetic brake](https://github.com/reefab/CyclingPusher/raw/master/images/bike.jpg)
+### Runkeeper screenshot
![Runkeeper screenshot](https://github.com/reefab/CyclingPusher/raw/master/images/BikeProjectRunkeeper.png)
-### Reed Switch (at the top of the picture)
-![Stationary bike's reed switch and magnetic brake](https://github.com/reefab/CyclingPusher/raw/master/images/bike.jpg)
## Setup
@@ -70,9 +68,9 @@ Here is the breadboard view:
You'll need to modify/provide the MAC address and Healthgraph's access token in the config.h (that you'll copy from config.h-dist) file.
You might want to change the number of meters per reed switch activation too.
-### How to get access token
+### How to get the access token
-First, once you have your Runkeeper account got to:
+First, once you have your Runkeeper account go to:
http://runkeeper.com/partner/applications/registerForm
@@ -95,4 +93,4 @@ Now, in a shell:
Please note that the 'redirect_uri' needs to the be exact same one as before.
-It'll then give you the access token you can use in your Arduino's code.
+It'll then give you the access token you can use in your Arduino code.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,70 +0,0 @@
-/**
- * SyncArduinoClock.
- *
- * portIndex must be set to the port connected to the Arduino
- *
- * The current time is sent in response to request message from Arduino
- * or by clicking the display window
- *
- * The time message is 11 ASCII text characters; a header (the letter 'T')
- * followed by the ten digit system time (unix time)
- */
-
-
-import processing.serial.*;
-
-public static final short portIndex = 1; // select the com port, 0 is the first port
-public static final char TIME_HEADER = 'T'; //header byte for arduino serial time message
-public static final char TIME_REQUEST = 7; // ASCII bell character
-public static final char LF = 10; // ASCII linefeed
-public static final char CR = 13; // ASCII linefeed
-Serial myPort; // Create object from Serial class
-
-void setup() {
- size(200, 200);
- println(Serial.list());
- println(" Connecting to -> " + Serial.list()[portIndex]);
- myPort = new Serial(this,Serial.list()[portIndex], 9600);
-}
-
-void draw()
-{
- if ( myPort.available() > 0) { // If data is available,
- char val = char(myPort.read()); // read it and store it in val
- if(val == TIME_REQUEST){
- long t = getTimeNow();
- sendTimeMessage(TIME_HEADER, t);
- }
- else
- {
- if(val == LF)
- ; //igonore
- else if(val == CR)
- println();
- else
- print(val); // echo everying but time request
- }
- }
-}
-
-void mousePressed() {
- sendTimeMessage( TIME_HEADER, getTimeNow());
-}
-
-
-void sendTimeMessage(char header, long time) {
- String timeStr = String.valueOf(time);
- myPort.write(header); // send header and time to arduino
- myPort.write(timeStr);
-}
-
-long getTimeNow(){
- // java time is in ms, we want secs
- GregorianCalendar cal = new GregorianCalendar();
- cal.setTime(new Date());
- int tzo = cal.get(Calendar.ZONE_OFFSET);
- int dst = cal.get(Calendar.DST_OFFSET);
- long now = (cal.getTimeInMillis() / 1000) ;
- now = now + (tzo/1000) + (dst/1000);
- return now;
-}
@@ -1,9 +0,0 @@
-SyncArduinoClock is a Processing sketch that responds to Arduino requests for
-time synchronization messages.
-
-The portIndex must be set the Serial port connected to Arduino.
-
-Download TimeSerial.pde onto Arduino and you should see the time
-message displayed when you run SyncArduinoClock in Processing.
-The Arduino time is set from the time on your computer through the
-Processing sketch.
@@ -1,82 +0,0 @@
-/*
- * TimeGPS.pde
- * example code illustrating time synced from a GPS
- *
- */
-
-#include <Time.h>
-#include <TinyGPS.h> //http://arduiniana.org/libraries/TinyGPS/
-#include <NewSoftSerial.h> //http://arduiniana.org/libraries/newsoftserial/
-// GPS and NewSoftSerial libraries are the work of Mikal Hart
-
-TinyGPS gps;
-NewSoftSerial serial_gps = NewSoftSerial(3, 2); // receive on pin 3
-
-const int offset = 1; // offset hours from gps time (UTC)
-time_t prevDisplay = 0; // when the digital clock was displayed
-
-void setup()
-{
- Serial.begin(9600);
- serial_gps.begin(4800);
- Serial.println("Waiting for GPS time ... ");
- setSyncProvider(gpsTimeSync);
-}
-
-void loop()
-{
- while (serial_gps.available())
- {
- gps.encode(serial_gps.read()); // process gps messages
- }
- if(timeStatus()!= timeNotSet)
- {
- if( now() != prevDisplay) //update the display only if the time has changed
- {
- prevDisplay = now();
- digitalClockDisplay();
- }
- }
-}
-
-void digitalClockDisplay(){
- // digital clock display of the time
- Serial.print(hour());
- printDigits(minute());
- printDigits(second());
- Serial.print(" ");
- Serial.print(day());
- Serial.print(" ");
- Serial.print(month());
- Serial.print(" ");
- Serial.print(year());
- Serial.println();
-}
-
-void printDigits(int digits){
- // utility function for digital clock display: prints preceding colon and leading 0
- Serial.print(":");
- if(digits < 10)
- Serial.print('0');
- Serial.print(digits);
-}
-
-time_t gpsTimeSync(){
- // returns time if avail from gps, else returns 0
- unsigned long fix_age = 0 ;
- gps.get_datetime(NULL,NULL, &fix_age);
- unsigned long time_since_last_fix;
- if(fix_age < 1000)
- return gpsTimeToArduinoTime(); // return time only if updated recently by gps
- return 0;
-}
-
-time_t gpsTimeToArduinoTime(){
- // returns time_t from gps date and time with the given offset hours
- tmElements_t tm;
- int year;
- gps.crack_datetime(&year, &tm.Month, &tm.Day, &tm.Hour, &tm.Minute, &tm.Second, NULL, NULL);
- tm.Year = year - 1970;
- time_t time = makeTime(tm);
- return time + (offset * SECS_PER_HOUR);
-}
@@ -1,120 +0,0 @@
-/*
- * Time_NTP.pde
- * Example showing time sync to NTP time source
- *
- * This sketch uses the Ethenet library with the user contributed UdpBytewise extension
- */
-
-#include <Time.h>
-#include <Ethernet.h>
-#include <UdpBytewise.h> // UDP library from: bjoern@cs.stanford.edu 12/30/2008
-#if UDP_TX_PACKET_MAX_SIZE <64 || UDP_RX_PACKET_MAX_SIZE < 64
-#error : UDP packet size to small - modify UdpBytewise.h to set buffers to 64 bytes
-#endif
-/*
- *
- * You may need to modify the UdpBytewise.h library to allow enough space in the buffers for the NTP packets.
- * Open up UdpBytewse.h and set the following buffers to 64 bytes:
- * #define UDP_TX_PACKET_MAX_SIZE 64
- * #define UDP_RX_PACKET_MAX_SIZE 64
- */
-
-
-byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
-byte ip[] = { 192, 168, 1, 44 }; // set the IP address to an unused address on your network
-
-byte SNTP_server_IP[] = { 192, 43, 244, 18}; // time.nist.gov
-//byte SNTP_server_IP[] = { 130,149,17,21}; // ntps1-0.cs.tu-berlin.de
-//byte SNTP_server_IP[] = { 192,53,103,108}; // ptbtime1.ptb.de
-
-
-time_t prevDisplay = 0; // when the digital clock was displayed
-const long timeZoneOffset = 0L; // set this to the offset in seconds to your local time;
-
-void setup()
-{
- Serial.begin(9600);
- Ethernet.begin(mac,ip);
- Serial.println("waiting for sync");
- setSyncProvider(getNtpTime);
- while(timeStatus()== timeNotSet)
- ; // wait until the time is set by the sync provider
-}
-
-void loop()
-{
- if( now() != prevDisplay) //update the display only if the time has changed
- {
- prevDisplay = now();
- digitalClockDisplay();
- }
-}
-
-void digitalClockDisplay(){
- // digital clock display of the time
- Serial.print(hour());
- printDigits(minute());
- printDigits(second());
- Serial.print(" ");
- Serial.print(day());
- Serial.print(" ");
- Serial.print(month());
- Serial.print(" ");
- Serial.print(year());
- Serial.println();
-}
-
-void printDigits(int digits){
- // utility function for digital clock display: prints preceding colon and leading 0
- Serial.print(":");
- if(digits < 10)
- Serial.print('0');
- Serial.print(digits);
-}
-
-/*-------- NTP code ----------*/
-
-unsigned long getNtpTime()
-{
- sendNTPpacket(SNTP_server_IP);
- delay(1000);
- if ( UdpBytewise.available() ) {
- for(int i=0; i < 40; i++)
- UdpBytewise.read(); // ignore every field except the time
- const unsigned long seventy_years = 2208988800UL + timeZoneOffset;
- return getUlong() - seventy_years;
- }
- return 0; // return 0 if unable to get the time
-}
-
-unsigned long sendNTPpacket(byte *address)
-{
- UdpBytewise.begin(123);
- UdpBytewise.beginPacket(address, 123);
- UdpBytewise.write(B11100011); // LI, Version, Mode
- UdpBytewise.write(0); // Stratum
- UdpBytewise.write(6); // Polling Interval
- UdpBytewise.write(0xEC); // Peer Clock Precision
- write_n(0, 8); // Root Delay & Root Dispersion
- UdpBytewise.write(49);
- UdpBytewise.write(0x4E);
- UdpBytewise.write(49);
- UdpBytewise.write(52);
- write_n(0, 32); //Reference and time stamps
- UdpBytewise.endPacket();
-}
-
-unsigned long getUlong()
-{
- unsigned long ulong = (unsigned long)UdpBytewise.read() << 24;
- ulong |= (unsigned long)UdpBytewise.read() << 16;
- ulong |= (unsigned long)UdpBytewise.read() << 8;
- ulong |= (unsigned long)UdpBytewise.read();
- return ulong;
-}
-
-void write_n(int what, int how_many)
-{
- for( int i = 0; i < how_many; i++ )
- UdpBytewise.write(what);
-}
Oops, something went wrong.

0 comments on commit 15b2be4

Please sign in to comment.