Ocean sports fitness tracker

Real-time GPS tracker for surfskiing (or kayaking, paddling, rowing) with real-time display as well as LoRa and LTE radios for safety.

Similar projects worth following
The ocean sports fitness tracker's purpose is to track a paddler in the ocean, provide real-time performance feedback to the paddler on a screen, and to also provide real-time tracking to on-shore family or buddies for safety purposes. After the outing the track is saved for performance analysis and long term monitoring of progress, possibly using one of the popular sports fitness tracking sites.

The background for this project is that I recently started to surfski, which is paddling a high-performance sit-on-top kayak in the open ocean. The more wind and waves the better because that's where it is the most fun: surfskis are deigned specifically for surfing waves in the open ocean. With this activity come several challenges, in particular safety and tracking one's performance in order to learn and improve. Despite first appearances, it's a very technical sport and there is a lot to learn both about stroke technique as well as wave riding skill.

Most surfskiers use a GPS watch, e.g. a Garmin or similar, attached to the foot strap. Looking at the prices and limitations of these things, plus the fact that one ends up tied into some vendor's tracking platform made me want to build my own. There are also a few more specialized trackers, such as SpeedCoach or from Vaaka, but they're very pricey and don't provide a real-time connection for someone on shore to track from a safety point of view.

I tried to use an Android phone for many months and have concluded that it just doesn't work. Right off the bat the battery life doesn't make it. I use an excellent GPS tracking app designed to track family members and it works beautifully as long as the phone screen is off and tucked in my PFD. But it provides no real-time information about the speed I'm going at, my heart rate, etc. If I use a sports tracking app that displays this type of data and mount the phone so I can see it then the battery lasts at best for an hour. Plus Android tries hard to terminate the app to save battery. It has been an exercise in frustration!

=== Goals ===

So I thought "how hard can it be?" :-). The minimal goals I set for the tracker are the following:

- track the activity in real-time using GPS plus a heart rate monitor and display speed, time, distance, and heart rate in real-time on a screen mounted to the footstrap

- send the tracking info in real-time via LoRa and/or 4G LTE to my own server and display progress on a map with some additional info useful for safety (heart rate, current speed, etc)

- the enclosure must be waterproof for shallow immersion, the screen must be legible in full sunlight, and the battery has to last comfortably for 2 hour outings

I have some additional stretch goals:

- display min/max speed so I can see the acceleration going down a wave and the slow-down hitting the back of one

- determine paddle stroke parameters, such as stroke rate, stroke distance, etc. using either boat acceleration or a paddle mounted sensor

- determine wave parameters, such as wave height, speed frequency using an accelerometer

=== Initial prototype ===

The initial prototype I build consists of a number of parts I cobbled together from previous projects:

- Small stm32L082 board (Jeenode) with Hoperf RFM98 433Mhz LoRa radio

- Globaltop PA6H GPS on adafruit breakout board

- Bosch BNO055 compass, accelerometer, gyro on Adafruit breakout board

- Small protoboard tieing everything together and having a 16MB SPI flash chip mounted

In addition I added:

- Battery holder for an 18650, with small USB charger board

- Monochrome transflective ("sunlight readable") 128x64 LCD with SPI interface

- HM-11 bluetooth BLE radio to get the heart rate from a polaris 7 heart rate monitor

- Waterproof case with quick latch

I threw the prototype together so I could experiment with a number of pieces:

- How well does the GPS track quick accelerations and decelerations (the Garmin phones tend to be really sluggish, the tracker in my Android phone reliably records impossible speed bursts). I figured I might have to try a couple of different GPS devices in order to find one that works for the purpose.

- Can I make the LoRa link work? I live about 10 miles (16km) away from the harbor where I usually paddle and at an altitude of 2100ft (about 650m) where I have line of sight. But that's quite a distance and starts to cut into speed vs...

Read more »

  • SPI kills LoRa radio

    Thorsten von Eicken07/21/2018 at 22:15 0 comments

    I spent some time this week troubleshooting the LoRa communication problems I encountered. To recap: I'm sending tracking packets from the tracker to the GW and the GW responds with an ACK to each packet. Both sides use the same TX power but I see 9-10dB less SNR at the node end. I thought it had something to do with the GW being a small linux SBC and having more noise or something, so I put together a simple STM32-based node to respond with ACKs like the GW does. I also displayed more info: SNR, RSSI, and noise measurements I took while there was no packet in the air. It was all rather confusing, in part because the SNR on the sx1276 LoRa chips doesn't report above about 8dB and at close range while testing it's difficult to actually go that low.

    Long story short, I saw that RSSI was within 1dB on both ends but SNR was off by 10dB. So both ends were getting the same signal strength but not the same signal-to-noise. Thus noise had to be the issue. But when I tried to measure the noise floor I got about the same values on both ends. Mystery. The answer turned out to be that reception on the linux end is fully interrupt driven while at the STM32 end the uC keeps polling the radio chip's registers to see the "RX done" flag being raised. That polling over the SPI bus creates enough noise to reduce sensitivity by 10dB!

    I did a quick test. Since the ACK comes in immediately I inserted a long-enough sleep before starting to poll such that the first poll happens after the reception is complete. Tada! This brought SNR to the same level on both ends! I then tried something different: I changed the slew rate on the SPI pins to "2Mhz", which has the effect of creating ~6-8ns rise and fall times instead of ~1.6ns. With the original polling that reduced the sensitivity loss from the 10dB to about 1dB. So that creates some options: (a) sleep for the expected time required for the ACK to come in, (b) use an interrupt for RX-done, (c) reduce the slew rate on the SPI pins.

    All this is fine and dandy for the test node I was using to try out the different combinations, but on the tracker it's somewhat more complicated. First of all, the SPI bus is used to drive not only the radio but also the flash chip and the display. That means that options (a) and (b) are useless unless  the code also avoids talking to these two devices while an ACK might be coming in. At the slow LoRa data rates an ACK takes 300-400ms and currently I'm updating the display twice a second, so there's not much time left.

    The other problem is that the GPS and the BLE interface are constantly sending stuff to the STM32 via serial ports and that is bound to also create noise. Those lines don't go to the radio module, but still. The effect of that is unknown.

    As a first step forward I ended up reducing the slew rate on all outputs from the STM32 chip. Testing at medium range seems to indicate a 2dB loss in sensitivity, which is not great but a start. I yet have to do a long range test.

    On the current stm32l082 chip package I'm out of pins, so I can't separate the radio's SPI bus from the display's. I will probably have to live with the 2dB sensitivity loss for my prototype, if that's what it comes out to be at long distance. I'm pondering what to do for the "real" version. One option is to use a uC chip with more pins so I can dedicate one SPI bus just to the radio, under the assumption that it's just the SPI bus that matters and that I can decouple power sufficiently. The other would be to break things up and use separate PCBs and uCs for radio vs. display, etc.

  • Initial status

    Thorsten von Eicken07/14/2018 at 22:25 0 comments

    I've now taken the prototype on several outings and it's starting to become useful. I'm learning how much I can display one the screen so I can actually read it with a quick glance while paddling and bouncing up&down in the ocean. It currently displays speed, min-max speeds over the past 10 seconds, heading, heart rate, time, LoRa RSSI, as well as number of stored trackpoints. Sorely missing is distance covered and to do that properly will take some work.

    The LoRa link has been giving me some trouble. It is working but not quite at the distance I need. Right now, trackpoints are recorded to the SPI flash chip and when radio connectivity is available the trackpoints are sent. What is happening is that I don't have connectivity while paddling and then on the drive home as I get closer it starts "spooling" the recorded tracks. So everything is pretty much working except for the fact that I don't quite have the range I need. I've narrowed the problem down to two issues: I have poor antenna positioning in the waterproof case (I knew that) and the anetenna isn't great (knew that too) but in addition I'm loosing close to 10dB of RX sensitivity at my GW, which is "not good". Put differently, both ends TX at the same power level and RX SNR is almost 10dB worse at the GW end. I'm suspecting it's because the radio is on a linux box (a CHIP), but it may well be something else.

    From my LoRa GW packets are injected into Node-red where they're processed and injected into the node-red-contrib-web worldmap. The code is currently displaying the "real-time" position (except for the fact that there's no real-time radio connectivity) as well as a track. One of the photos attached here shows one outing of about 6.3mi I did with the tracker.

    So far the proof of concept shows lots of promise and at the same time there's lots left to do! Yay!

    === Next steps ===

    The thing that bugs me the most is the LoRa radio connection. I've tried a better antenna (home made dipole) and I get connectivity using that, but it's not great from an ergonomic point of view. And it made it clear that if I could solve the 10dB RX sensitivity loss I could do with a smaller antenna. So that's the next thing to fix.

    One of the other tasks is to add code both in the tracker an in node-red to smooth the track in order to be able to calculate distance covered without over-inflating it due to GPS-induced zigzags. The keyword here seems to be Ramer-Douglas-Peucker algorithm and some on-line variants thereof.

    The other task is to automatically determine the start and end of an outing using some form of geofencing, and then storing the track of each outing in a proper database so it can be processed in various manners and also sent to endomondo or a similar sports tracking site automatically.

View all 2 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates