Friday, September 11, 2015

Garmin fenix3

What to do with activities?

One of the cool features the fenix3 provides is the wireless lan module. I really don't wanna miss this. Once you have added your available WLAN networks (I added my home network and my  smartphone wifi tethering hotspot) and wifi auto-upload is enabled on your watch, the fenix3 will periodically try to connect to your network once a new activity has been saved.
Cool ... so after a run upon entering my house the activity is basically already uploaded to Garmin Connect.

Strava and Garmin Connect (GC)

So far so good ... the thing is some years ago I was searching for some online portal to upload my running activities (backup, stats, fun, for whatever reason ...), that time I came along One thing they had (way before garmin connect) were the so called 'segments' for runs and bike rides and associated 'koms'. Along with segments also comes a leaderboard.
Long story made short so far I was using strava not garmin connect (GC). In the past I manually uploaded my .fit files to the strava page, of course this will still work but since now everything can automatically appear in GC it makes sense this gets automatically to strava as well.
So how to do this? Simple ... strava provides the option to sync GC ... no big deal ...
Unfortunately it just did not work for me so far ... not sure why.
So I was looking for some other way to download files from GC and upload again to strava.
I found garmin-connect-export and made some minor enhancements. Once you have a .fit file you can use strava api to upload this file and it will appear on your dashboard.
To do so I make use of the node.js strava module, you can find this script and description here.

So my current "workflow" is:
  1. go running/cycling/swimming and return back home (or turn on mobile hotspot)
  2. run -d ~/MyActivities -c 5 -u (optionally provide user/pwd on cmdline)
  3. node strava-file-upload.js  -f ~/MyActivities/


Automate the steps 2 and 3 from above. Right now my idea is to monitor my wlan traffic and trigger some script once an activity upload is detected. The script should do the GC download and strava upload.

Maybe something like this (where 12:34:56:78:9A:BC is your watch mac address):
tcpdump -i wlan0 ether host 12:34:56:78:9A:BC | awk '{if (some condition) {system("somescript")}}'

And since I have now installed runalyze on my server I want to sync to this one as well ... but should not be a big deal ... especially since runalyze is open source (see also my fork).

Wednesday, May 20, 2015


A OpenSource Online Running Diary

Ever wanted to host your own running portal, something similar to strava or garmin connect?
Well ... here we go: runalyze !

Installation (Linux)

Basically you follow the instructions from the website which are as simple as getting the tarball and extract into some directory on your webserver (which you can be reached from a browser of course).
Then load the install.php (script) url from a web browser.
That should be it ... well almost. Runalyze requires an mysql database installation so it's an good idea to check with that first and have some mysql use with enough privileges.
The following grants should be fine for 'someuser':

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER ON `runalyze`.* TO 'someuser'@'localhost'

Later in the install you will have to enter that username.

One problem I had after the install was that the index page wasn't really loading. Looking into the webserver log gave the answer, I had to create a temp dir and set permissions:

# mkdir /tmp/
# chmod  777 /tmp/


FIT import not working

I had problems with uploading .fit (garmin) files. The issue here was that you could choose one or more files for upload and basically there were some calender entries but all with zero data. That means all had the same timestamp and no distance, time, ... data was shown.
The problem here was that the perl script  call/perl/ wasn't executed on that file. The reason for this script not being executed were the php safe_mode settings on the server for the runalyze directory.
So in case you have similar issues you might check the php_admin_flag safe_mode.

Monday, May 11, 2015

100 Km Albtrauf für Nepal #100atnepal

100 Km Albtrauf für Nepal #100atnepal

Ein Spendenprojekt von Andreas Bulling und Frank Weller:

Die Idee ist es, den Leuten in Nepal zu helfen, der Lauf soll dazu motivieren, die Spendensumme ist natuerlich ansporn die 100 trailigen auf-und-ab Kilometer auch durchzustehen.
Die Aktion ist auf gelistet und Spenden werden direkt an diese Organisation uebermittelt, welche sie, in diesem Fall als Hilfe fuer Nepal, projektgebunden einsetzt.

Spenden kann jeder direkt unter:

Also einfach dem Link folgen und ein paar Euro locker machen ;)
p/s: es gibt keinen Mindestbetrag ;) (max. natuerlich auch nicht)

pp/s: Ich werd mal schauen, wie weit ich mit den Beiden mithalten kann und zumindest gemeinsam mit am Start stehen und soweit laufen wie es meine Fitness erlaubt.

UPDATE (20.05.2015): erfolgreich am 15.05 gelaufen ca. 107km in 16 Stunden im Regen und Nebel auf einem tollen Wanderweg mit zwei klasse Typen. Spendenstand 3.321,80!
 Spenden werden weiterhin gerne angenommen auf der Seite von Aktion Deutschland Hilft.

Hier ein Bericht in der Geislinger Zeitung.

Foto: Karsten Dyba

Ambit 3 vs. Fenix 3

My pro and cons list

Sooner or later I might upgrade from my (in the meantime very reliable) Garmin Fenix (1).
So here is my list of pros/cons regarding those two watches.

Update: ... and the winner is ... fenix3. After my old fenix1 had issues with battery charging and lifetime I got a exchange offer from Garmin and now I'm very satisfied with the fenix3

Price (05/2015) HR Bundle
ca. 350 EUR
ca. 430 EUR

Battery (default GPS tracking)
20 (30h?)
Ambit best vs. good tracking
Charge and use while running

Usb mass storage


Wednesday, February 25, 2015

Link outdoor wiki


"Das Outdoorwiki ist ein Projekt zum Aufbau eines Nachschlagewerks unter dem Oberbegriff Outdoor. Bisher wurden 437 Artikel aufgenommen. Das Wiki ist dabei eng mit dem Forum verbunden. Gute Autoren, die aus eigener Erfahrung über ein Themengebiet schreiben können, sind stets willkommen!"

Saturday, December 13, 2014

Arduino RGB strip

Knight Rider ...

keep track of misc arduino snippets here.

Get yourself some RGB LED light strip like this one.
These are WS2812B type of chip are in a 5050 package including controller to control every single "pixel" i.e. the RGB LED on the strip and set each color individually.

I always wanted one of those :)
Shipping was from Hong-Kong to Germany a pretty reasonable amount of time (less then three weeks).

So what to do? you start with some examples you'll find on the web.
Good starting point is this page. As this page explains there's basically two major arduino libs for controlling this kind of strip the Neopixel one from Adafruit and FastLed.

From there I took another example code found here:

This gives you some "knight rider" effect.

I broaden the moving lights a bit and added some code to control the speed via a simple poti.

#include "FastLED.h"
//#include <OneSheeld.h>

// How many leds are in the strip?
#define NUM_LEDS 60
// Data pin that led data will be written out over
#define DATA_PIN 6
// This is an array of leds.  One item for each led in your strip.

const int poti = A1;
const int button8 = 8;

// This function sets up the ledsand tells the controller about them
void setup() {

  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);


int duration;
void loop() {
  int potiVal = analogRead(poti);
  float voltage = potiVal * (20.0 / 1023.0);
  int duration = (int)voltage;

  byte hue = 8; // some red

  larsonScanner(NUM_LEDS, hue, 255, duration);


void larsonScanner(byte ledcount, byte hue, byte sat, byte duration) {
  static unsigned long previousMillis = millis();
  static int i; // Schrittzaehler
  static int led = 0;
  static boolean reverse = false;
  byte dim;

  if(i > 8) {
    i = 0;

    if (reverse) led--;
    else led++;

    // Anfang erreicht
    if (led < 0) {
      led = 0;
      reverse =! reverse;

    // Ende erreicht
    if (led >= ledcount) {
      led = ledcount-1;
      reverse =! reverse;

  if (millis()-previousMillis > duration) {
    previousMillis = millis();
    memset(leds, 0, ledcount*3); // LED Array zuruecksetzen
    dim = i*4;

    // Aktuelle Led-4
    if (led-5>=0 && !reverse) {
      leds[led-5] = CHSV(hue, sat, 32-dim); // FadeDown
    else if (led-5>=0 && reverse) {
      leds[led-5] = CHSV(hue, sat, dim); // FadeUp

    // Aktuelle Led-3
    if (led-4>=0 && !reverse) {
      leds[led-4] = CHSV(hue, sat, 64-dim); // FadeDown
    else if (led-4>=0 && reverse) {
      leds[led-4] = CHSV(hue, sat, 32+dim); // FadeUp

    // Aktuelle Led-2
    if (led-3>=0 && !reverse) {
      leds[led-3] = CHSV(hue, sat, 128-dim); // FadeDown
    else if (led-3>=0 && reverse) {
      leds[led-3] = CHSV(hue, sat, 64+dim); // FadeUp

    // Aktuelle Led-1
    if (led-2>=0 && !reverse) {
      leds[led-2] = CHSV(hue, sat, 255-dim); // FadeDown
    else if (led-2>=0 && reverse) {
      leds[led-2] = CHSV(hue, sat, 127+dim); // FadeUp

    // Aktuelle Led
    leds[led-1] = CHSV(hue, sat, 255);
    leds[led] = CHSV(hue, sat, 255);
    leds[led+1] = CHSV(hue, sat, 255);

    // Aktuelle Led+1
    if (led+2<ledcount && !reverse) {
      leds[led+2] = CHSV(hue, sat, 127+dim); // FadeUp
    else if (led+2<ledcount && reverse) {
      leds[led+2] = CHSV(hue, sat, 255-dim); // FadeDown

    // Aktuelle Led+2
    if (led+3<ledcount && !reverse) {
      leds[led+3] = CHSV(hue, sat, 64+dim); // FadeUp
    else if (led+3<ledcount && reverse) {
      leds[led+3] = CHSV(hue, sat, 128-dim); // FadeDown

    // Aktuelle Led+3
    if (led+4<ledcount && !reverse) {
      leds[led+4] = CHSV(hue, sat, 32+dim); // FadeUp
    else if (led+4<ledcount && reverse) {
      leds[led+4] = CHSV(hue, sat, 64-dim); // FadeDown

    // Aktuelle Led+4
    if (led+5<ledcount && !reverse) {
      leds[led+5] = CHSV(hue, sat, dim); // FadeUp
    else if (led+5<ledcount && reverse) {
      leds[led+5] = CHSV(hue, sat, 32-dim); // FadeDown


The potentiometer is connected to analog 1 and the digital in of the light strip in dio6.

Sunday, November 30, 2014

strava node.js api

How to get shoe mileage on the command line

make sure you have node.js and node package manager (npm) installed.
$ sudo apt-get install node.js npm

then follow this quickstart instructions  from here:

get strava developer api access from here
access your application info and settings here:
the api doc is at:

now you should be able to run the example program from the quickstart guide.

you directory structure should look something like this:

user@host:~/Programming/node.js/strava$ tree -L 2
├── data
│   └── strava_config
├── node_modules
│   └── strava-v3
└── shoes.js

3 directories, 2 files

now edit the shoes.js file and put in this code:
user@host:~/Programming/node.js/strava$ cat shoes.js 

var strava = require('strava-v3');

strava.athlete.get({},function(err,payload) {
    if(!err) {          
for (var i=0; i<; i++) {
   console.log([i].name + " - " +[i].distance/1000 + " km");

    else {

if you run it you should get a listing of your active shoes from strava together with the mileage (here in km)

$ node shoes.js 
Salomon Fellraiser - 481.693 km
Inov-8 Roclite 315 - 383.47 km
Brooks T6 Racer - 401.136 km
Inov-8 Trailroc 255 - 656.62 km
Saucony Fastwitch 5 ( blue ) - 463.049 km
Barefoot (No Shoes) - 5.219 km
Aldi "barfuss" ?? blau - 136.115 km
Saucony Peregrine 3.0 - 479.282 km
Hoka One One Mafata 2 - 1119.308 km
New Balance Minimum Trail 00 - 403.544 km
Inov-8 Trailrc 245 - 338.791 km
Vibram FF EL-X - 46.919 km

that's it for now.