I successively had a Garmin Forerunner 205 that I unfortunately lost during a windsurfing trip. Then a Garmin Forerunner 310XT that took on water after 7 years of intensive use.
![]() Garmin Forerunner 205 |
![]() Garmin Forerunner 310XT |
I then
moved on to the Garmin Forerunner 735XT which has the
advantage of having a development environment that
allows you to customize it as you can see below (see this post for more details). Unfortunately it is a fairly fragile watch and I broke the screen fairly quickly during a windsurfing session (see this post ) and I had to deal with a cracked screen for almost 4 years before it finally gave up on me. |
![]() |
I have since replaced it with a Garmin Instinct surf model that I customized with the Connect IQ development environment .
In the rest of this page I have maintained the configuration details specific to previous GPS watches which no longer evolve and which I have placed at the end of this page.
It is seen as a standard USB storage perimeter and is automatically mounted.
Nov 24
10:37:36 predator.kervao.fr kernel: usb 3-8: new
full-speed USB device number 7 using xhci_hcd
Nov 24 10:37:36
predator.kervao.fr kernel: usb 3-8: New USB device found,
idVendor=091e, idProduct=0f30, bcdDevice= 5.09
Nov 24 10:37:36
predator.kervao.fr kernel: usb 3-8: New USB device
strings: Mfr=0, Product=0, SerialNumber=0
Nov 24 10:37:36
predator.kervao.fr kernel: usb-storage 3-8:1.0: USB Mass
Storage device detected
Nov 24 10:37:36
predator.kervao.fr kernel: scsi host7: usb-storage 3-8:1.0
Nov. 24 10:37:36
predator.kervao.fr mtp-probe[210266]: checking bus 3,
device 7: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-8"
Nov. 24 10:37:36
predator.kervao.fr mtp-probe[210266]: bus: 3, device: 7
was not an MTP device
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210267]: checking bus 3,
device 7: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-8"
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210267]: bus: 3, device: 7
was not an MTP device
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210280]: checking bus 3,
device 7: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-8"
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210280]: bus: 3, device: 7
was not an MTP device
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210286]: checking bus 3,
device 7: "/sys/devices/pci0000:00/0000:00:14.0/usb3/3-8"
Nov 24 10:37:36
predator.kervao.fr mtp-probe[210286]: bus: 3, device: 7
was not an MTP device
Nov 24 10:37:36
predator.kervao.fr Thunar[210279]: thunar-volman:
Unsupported USB device of type 'usb'.
Nov 24 10:37:36
predator.kervao.fr Thunar[210294]: thunar-volman:
Unsupported USB device of type 'usb-storage'.
Nov 24 10:37:37
predator.kervao.fr kernel: scsi 7:0:0:0: Direct-Access
Garmin instinct2S Flash PQ: 0 ANSI:
Nov 5 24 10:37:37
predator.kervao.fr kernel: sd 7:0:0:0: [sde] 37211
512-byte logical blocks: (19.1 MB/18.2 MiB)
Nov. 24 10:37:37
predator.kervao.fr kernel: sd 7:0:0:0: [sde] Write Protect
is off
Nov. 24 10:37:37
predator.kervao.fr kernel: sd 7:0:0:0: [sde] Mode Sense:
23 00 00 00
Nov. 24 10:37:37
predator.kervao.fr kernel: sd 7:0:0:0: [sde] Write cache:
enabled, read cache: enabled, doesn't support DPO or FUA
Nov. 24 10:37:37
predator.kervao.fr kernel: sde:
Nov. 24 10:37:37
predator.kervao.fr kernel: sd 7:0:0:0: [sde] Attached SCSI
removable disk
Nov 24 10:37:43
predator.kervao.fr udisksd[3491]: Mounted /dev/sde at
/run/media/olivier/GARMIN on behalf of uid 5001
And in the GARMIN directory that is automatically mounted we find a GARMIN/ACTIVITY directory where we will find our activities in FIT format. The lsusb command will give
Bus 003
Device 007: ID 091e:0f30 Garmin International
Unlike the 735XT which is based on Eclipse, it is based on the Visual Studio Code development environment .
All the installation details are given in English here. To summarize we will retrieve the SDK at this address. And we will type the following commands to install it and launch it the first time.
mkdir
connectiq-sdk
unzip
connectiq-sdk-manager-linux.zip
cd connectiq-sdk/
cd bin/
./sdkmanager
If necessary, you may need to install the lib64webkit2gtk4.0_37 package.
You will first need to log into your Garmin account or create one.
Then there is a window to know if SDK updates should be downloaded automatically when there is a new version. Then comes a window to know if we also perform device updates automatically. At this point you can select the devices concerned, I advise you to strictly select the useful device category because otherwise it takes up space unnecessarily.
Next comes the next window with a SDK and DEVICES tab , I clicked on the latest SDK version and only watches (watches and wearables).
The Connect IQ SDK is based on Visual Studio Code which can be downloaded here. It is installed and launched by typing:
tar tar
xvfz code-stable-x64-1739405584.tar.gz
cd VSCode-linux-x64/
bin/code
You will now need to install the Monkey C extension which includes an editor, a compiler and a debugger. To do this in Visual Studio Code , go to View->Extensions and type Monkey C . Then click on the blue Install button. You will then need to relaunch Visual Studio Code .
We now generate a developer key that will be useful for signing applications, be careful to keep it somewhere else, otherwise we will no longer be able to edit the different projects! To generate it, type the key combination Ctrl+Shift+P and in the drop-down list choose Monkey C: Generate a developer key .
While doing so with the same key combination we will download Monkey code examples C: Open Samples Folder . They ended up under .Garmin/ConnectIQ/Sdks/connectiq-sdk-lin-7.3.1-2024-09-23-df7b5816a/samples . So I made a link from this directory to my Connect IQ working directory .
We can move on to our first Hello Word application ! For the code, it's a bit of a jungle, you have to navigate by sight on the Connect IQ page and fumble around a lot, we can start with the page to build our first application. The page giving the details of the API is a must, for my Instinct 2, there is a specific page but I did not find specific codes even in the downloaded examples. The dedicated forum is also a good source of information and help. You can then share your code here but it is clear that few developers share their code.
In the end it took me hours to try to understand how to code all this and achieve this result, all this from the original Hello World project . It's quite a pain because there are generally very few commented examples.
The application will be tested via the simulator accessible via Run->Run without debugging , it will also be necessary to ensure that the application is tested in sleep mode because the display may be different (box checked Sleep Mode then Display Mode -> Always Active)
To debug, you can set a breakpoint from the Run->toggle breakpoint menu , the breakpoint is represented by a red dot next to the line number.
We launch the
simulator in debug mode with Run->Start debugging , we find on the left the state of the variables and just
below the name of the project, we find the debug commands to move from breakpoint to breakpoint or from line to
line.
We can also enter a command in the code like System.println("my variable"+variable); and we will find the command displayed in the DEBUG CONSOLE tab at the bottom .
We stop the simulation mode from the Run->Stop debugging menu .
Once the application is running on the simulator, you need to build the binary, access it via the key combination Ctrl+Shift+P and choose Monkey C: Build for device. The compilation will generate a .PRG file , once the watch is connected via USB, it will be placed under GARMIN/APPS . To go back, simply delete the said file.
And this is what it looks like with the watch running
![]() Version 0.1.0 initial release with a rectangle shaped gauge for battery charge |
![]() Version 0.2.0 with arc-shaped gauges for battery and step ratio and daily step goal and custom fonts |
I particularly struggled with displaying the seconds because by default there is an update every minute when the watch is in low power mode (most of the time) and you have to use the onPartialUpdate function which allows a local display with a refresh every second.
I also took some time to create a battery gauge, I started from this page on the Garmin forum.
I also used a custom font because the default ones were too big, even the smallest ones. I used this page https://jeffchen.dev/posts/Garmin-Watch-Faces-Custom-Fonts-On-MacOS/ its author forked the FontBuilder software which will allow you to generate fonts in a format that Garmin can understand from the fonts present on a Linux system under /usr/share/fonts (or elsewhere).
We download the fork from https://github.com/jchen1/fontbuilder/. We then unzip the archive by typing
unzip fontbuilder-master.zip
You may need to install the freetype2-devel , lib64qt5widgets-devel and lib64qt5xml-devel packages. Then type
cd
fontbuilder-master/
qmake
make
and we launch the software by typing bin/FontBuilder
![]() In this tab we will load the font |
![]() And in this tab we export it in BMFont format |
We will then place the generated .fnt and .PNG files in a resources/fonts directory of the project.
The operation is sometimes haphazard and it does not always work, I also recommend the fontbm tool which can be found at this address https://github.com/vladimirgamalyan/fontbm we decompress by typing
tar xvfz fontbm-0.6.1.tar.gz
and type the following command
cd
fontbm-0.6.1/
mkdir build
cd build/
cmake ..
make
then as root (path to modify)
ln -s /usr/local/linux/system/fontbm-0.6.1/build/fontbm /usr/local/bin
For example, I got a diverted Indigo Outline font from the site https://www.fontsquirrel.com/fonts/indigo , I will create a compatible font of size 32 by typing
fontbm --font-size 32 --font-file Indigo\ Outline.otf --output IndigoOutline32
The fonts will be placed under resources/fonts of the project
Finally, if you want to consult the commented sources, you will find them at this address https://github.com/funix83/Funix-Watch
I have also written several posts about this on my blog where you can find additional information:
tar xvfj wxWidgets-3.2.6.tar.bz2
this gives the wxWidgets-3.2.6 directory in which we type
./configure
make
then as root
make install
we now install the packages tinyxml-devel, lib64glew-devel, lib64archive-devel and lib64usb1.0-devel. The official OpenCPN website is https://opencpn.org/ but we will get the sources from there https://github.com/OpenCPN/OpenCPN/releases we unzip them by typing
tar xvfz OpenCPN-Release_5.10.2.tar.gz
this gives the OpenCPN-Release_5.10.2 directory in which we type
mkdir build
cd build
cmake..
then
make
Now that's not all, we need to get the maps, we can start with the coastal maps of OpenSeaMap here http://openseamap.org/index.php?id=kartendownload&L=1 or better still the CM93 maps here http://pierre.lavergne1.free.fr/special_voileux/OpenCPN.html (but not sure that it must be free...). We unzip all that in a directory that we will then indicate to OpenCPN .
And here is the result when typing opencpn
mkdir build
cd build/
cmake ..
make
cd gui
make
then as root
cp gpsbabel /usr/local/bin
cp
gui/GPSBabelFE/gpsbabelfe /usr/local/bin
To transform a .fit file into a .gpx file, type:
gpsbabel -i garmin_fit -f 2020-07-25-tracegps-fun-sainte-marguerite-2.FIT -o gpx -F 2020-07-25-tracegps-fun-sainte-marguerite-2.gpx
The following command will download files from a forerunner 205 and save them to a .gpx file
gpsbabel -i garmin -f /dev/ttyUSB0 -o gpx -F file.gpxThe following command allows you to upload a .tcx training file to a forerunner 205
gpsbabel -i
gtrnctr -f file.tcx -o garmin -F /dev/ttyUSB0
Note that it does not seem to work with an ANT+ connection. For example, to download a track to the forerunner in order to follow it, you generally retrieve a .gpx track that you will need to convert to .tcx training format like this
gpsbabel -i gpx -f file.gpx -o gtrnctr -F file.tcx
To upload, simply type
gpsbabel -i gtrnctr -f file.tcx -o garmin -F /dev/ttyUSB0
it now has a graphical interface that can be called by typing gpsbabelfe
First of all, online alternatives to import GPS point files. We will start with GPS Visualizer which allows you to display the values in knots and nautical miles and to colorize the track according to the speed.
we will note the instantaneous speed peak at 31.1 knots.
There is also My GPS Files which gives something like this:
Please note that it does not recognize the .FIT format.
There is however a small bug in the display of the speed marked in knots but which is in km/h in fact. The replay of the trace is possible.
There are now solutions that allow archiving of outings but which require having an account, this is the case with Strava or Garmin Connect which I use
file is automatically created, here is mine
crw-rw---- 1
root dialout 188, 0 Nov 2 10:52 /dev/ttyUSB0
If you have problems with
access rights on the USB port, it will probably be useful to
add your user to the dialout and lp group ( /etc/group file ) or to type (you will have
to do this each time) as root
chmod 666 /dev/ttyUSB0
lsusb gives me
Bus 001 Device
005: ID 091e:0003 Garmin International GPS (various models)
We then create a file /etc/udev/rules.d/51-garmin.rules containing
SUBSYSTEM=="usb",
ATTR{idVendor}=="091e", ATTR{idProduct}=="0003", MODE="0666"
and we add to the file /etc/modprobe.d/blacklist-mga.conf (for a mageia) the
line blacklist garmin_gps
directory in which as root we type
python setup.py install
Now we get antfs-cli , which was previously called Garmin-Forerunner-610-Extractor or Garmin-Extractor and which allows to retrieve the FIT activity files of a device and write them to a directory. The official website https://github.com/Tigge/antfs-cli we retrieve the archive that we unzip by typing
unzip antfs-cli-master.zip
this gives the antfs-cli-master directory in which we type as root
python setup.py
install
When we look more closely, it created under /etc/udev/rules.d/ the file ant-usb-sticks.rules which contains
SUBSYSTEM=="usb",
ATTR{idVendor}=="0fcf", ATTR{idProduct}=="1008", MODE="0666",
SYMLINK+="ttyANT2", ACTION=="add"
SUBSYSTEM=="usb",
ATTR{idVendor}=="0fcf", ATTR{idProduct}=="1009", MODE="0666",
SYMLINK+="ttyANT3", ACTION=="add"
when the key is actually plugged in, when we type
ll /dev/ttyANT3
we can see
lrwxrwxrwx 1
root root April 15, 25 9:59 PM /dev/ttyANT3 ->
bus/usb/002/007
to launch it just type in a shell
antfs-cli
--upload
here is the trace
Driver available: [<class
ant.base.driver.SerialDriver at 0x7f2d38e1aef0>, <class
ant.base.driver.USB2Driver at 0x7f2d387c8600>, <class
ant.base.driver.USB3Driver at 0x7f2d387c8668>]
- Using:
ant.base.driver.USB3Driver
Request basic information...
Capabilities:
array('B', [8, 8, 0, 186, 54, 0, 223, 230])
Starting system...
Key done...
Searching...
Authenticating with Forerunner
310XT (3872022432)
- Pairing:
When you launch it for the
first time, you have to synchronize with the watch (pair),on
the watch it asks for permission to do so, we obviously answer
yes.
OK
Downloading 121 file(s)
and uploading 0 file(s)
Downloading
1989-12-31_01-00-00_1_65535.fit:
[..............................] ETA: 0:00:00
Downloading
1989-12-31_01-00-00_2_65535.fit:
[..............................] ETA: 0:00:00
....
In fact, there is nothing to do, it is a simple USB device which is perfectly recognized as a storage device, here is the trace with journalctl
August 30
14:20:43 predator.kervao.fr kernel: usb 2-9: new
full-speed USB device number 10 using xhci_hcd
August 30 14:20:44
predator.kervao.fr kernel: usb 2-9: New USB device found,
idVendor=091e, idProduct=086e, bcdDevice= 5.09
August 30 14:20:44
predator.kervao.fr kernel: usb 2-9: New USB device
strings: Mfr=0, Product=0, SerialNumber=0
August 30 14:20:44
predator.kervao.fr kernel: usb-storage 2-9:1.0: USB Mass
Storage device detected
August 30 14:20:44
predator.kervao.fr kernel: scsi host8: usb-storage 2-9:1.0
Aug 30 14:20:44
predator.kervao.fr mtp-probe[15639]: checking bus 2,
device 10: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-9"
Aug 30 14:20:44
predator.kervao.fr mtp-probe[15639]: bus: 2, device: 10
was not an MTP device
Aug 30 2:20:44 PM
predator.kervao.fr baloo_file[4770]: UdevQt: unhandled
device action "bind"
Aug 30 2:20:44 PM
predator.kervao.fr mtp-probe[15655]: checking bus 2,
device 10: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-9"
Aug 30 14:20:44
predator.kervao.fr mtp-probe[15655]: bus: 2, device: 10
was not an MTP device
Aug 30 14:20:44
predator.kervao.fr baloo_file[4770]: UdevQt: unhandled
device action "bind"
Aug 30 14:20:44
predator.kervao.fr Thunar[4571]: thunar-volman:
Unsupported USB device of type 'usb'.
Aug 30 14:20:44
predator.kervao.fr Thunar[4571]: thunar-volman:
Unsupported USB device of type 'usb-storage'.
Aug 30 14:20:45
predator.kervao.fr kernel: scsi 8:0:0:0: Direct-Access
Garmin FR735XT Flash 1.00 PQ: 0 ANSI: 5
Aug 30 14:20:45
predator.kervao.fr kernel: sd 8:0:0:0: [sdf] 20646
512-byte logical blocks: (10.6 MB/10.1 MiB)
Aug 30 14:20:45
predator.kervao.fr kernel: sd 8:0:0:0: [sdf] Write Protect
is off
Aug 30 14:20:45
predator.kervao.fr kernel: sd 8:0:0:0: [sdf] Mode Sense:
23 00 00 00
Aug 30 14:20:45
predator.kervao.fr kernel: sd 8:0:0:0: [sdf] Write cache:
enabled, read cache: enabled, doesn't support DPO or FUA
August 30 14:20:45
predator.kervao.fr kernel: sdf:
August 30 14:20:45
predator.kervao.fr kernel: sd 8:0:0:0: [sdf] Attached SCSI
removable disk
August 30 14:20:50
predator.kervao.fr udisksd[3008]: Mounted /dev/sdf at
/run/media/olivier/GARMIN on behalf of uid 5001
And in the GARMIN directory that is automatically mounted we find a GARMIN/ACTIVITY directory where we will find our activities in FIT format. Otherwise an lsusb will give
Bus 002 Device 010: ID 091e:086e Garmin International Forerunner 735XT
[ Back to FUNIX home page ] | [ back to top of page ] |