SwimWatch
Tijdwaarneming voor zwemwedstrijden

Live tijden,
van de baan tot de tribune.

SwimWatch is een zelf ontwikkeld systeem voor tijdwaarneming. Elke baan heeft een baantimer met scherm en knop, een startertimer geeft het startmoment, en één server controleert de tijden, bepaalt de volgorde, toont de uitkomst en legt alles vast in een logbestand.

SwimWatch in gebruik tijdens een zwemwedstrijd
Foto 1 · SwimWatch in gebruik tijdens een wedstrijd
1 knop
per baan: de tijdwaarnemer drukt bij elke aanslag op zijn eigen klok
0 installatie
alle schermen draaien in de browser
Alles gelogd
ook geweigerde splits, met reden, te downloaden
Verplaatsbaar
geen permanente installatie in het zwembad nodig
01 · Ontstaan

Het begon met het grote scherm in het zwembad.

Als zwemmer of toeschouwer raak je snel kwijt hoe ver een wedstrijd is. Als het scherm laat zien wat er op dat moment in het water gebeurt, is een wedstrijd voor iedereen leuker en makkelijker te volgen.

Van een idee voor het scorebord tot een eigen systeem voor tijdwaarneming, in iets minder dan twee jaar.

  1. {{ s.date }}

    {{ s.title }}

    {{ s.body }}

02 · Werking

Alles centraal geregeld.

SwimWatch is draadloos en verplaatsbaar. Elke klok werkt op een eigen accu en praat via WiFi met één server, een Raspberry Pi. Er lopen geen kabels langs het bad en er wordt niets vast in het zwembad gemonteerd: router, access point, server en klokken gaan na de wedstrijd gewoon weer mee.

Alles wat een apparaat of persoon doet gaat via die server, en de server stuurt de klokken en schermen aan. Kies hieronder een datastroom om te zien hoe een bericht door het systeem gaat.

Bad 25 m · 10 banen Keerzijde Startzijde start + finish 1 2 3 4 5 6 7 8 9 10 Starter startknop Access point midden achter start Router LAN · DHCP Raspberry Pi socket- en NTP-server Operator remote en schermen Wedstrijdscherm publiek, in de browser bedraad WiFi baantimer (LilyGO T-Display S3) bericht

{{ net.text }}

Voorbeeld wedstrijdscherm
3 - 100M vrije slag | serie 2{{ net.clock }}
1Baan 1--:--:--
2Baan 2--:--:--
3Baan 3--:--:--
4Baan 450m--:--:--00:28:451
5Baan 5--:--:--
6Baan 6--:--:--
7Baan 7--:--:--
8Baan 8--:--:--
9Baan 9--:--:--
10Baan 10--:--:--
Dit zijn geen officiële tijden
Fig. 2 · Plattegrond van het bad met baantimers, starter, server en WiFi

Alles in je eigen browser.

Geen installatie nodig: elke pagina werkt in de browser van een laptop, tablet of telefoon.

Toestand
{{ variant.alt }}
Voor: {{ screen.who }}
{{ screen.name }}

{{ screen.what }}

{{ screen.note }}

{{ variant.altM }}
Op de telefoon
Splits en logboek

Elke split gecontroleerd en vastgelegd.

Een tijdwaarnemer kan per ongeluk twee keer drukken, of na de finish nog een keer. Daarom controleert de server elke split voordat die op een scherm komt: welke afstand hoort erbij, telt deze druk mee, en wie ligt er voor. Alles, ook wat niet meetelt, komt in het logboek.

Afstanden

De tijdwaarnemer staat aan de startzijde, dus een split valt na elke twee lengtes. Uit het programma weet de server de afstand van het event en daarmee hoeveel splits er komen. De laatste is de finish. Bij een estafette is dat de afstand maal het aantal zwemmers.

Bad
Afstand
{{ sp.label }}

{{ splitNote }}

Telt deze druk mee?

Per baan geldt een wachttijd (cooldown) na de start en na elke split: standaard 12 s, instelbaar van 1 tot 60 s. Een druk binnen die tijd, of na de finish, wordt genegeerd. Hij verschijnt nergens als tijd, maar staat wel met de reden in het log.

00:28,45Telt mee · split 1, 50 m
00:31,25Genegeerd · 2,8 s na de vorige split, binnen de cooldown
00:58,71Telt mee · split 2, 100 m, finish
01:00,10Genegeerd · na de finish

Voorbeeld: 100 m in een bad van 25 m, verzonnen tijden.

Aankomstvolgorde

De baan met de meeste splits staat voorop. Bij een gelijk aantal telt de vroegste tijdstempel. Zo staat op het wedstrijdscherm na elke split meteen de juiste volgorde.

Het logboek

De server schrijft elke START, SPLIT, SPLIT IGNORED en RESET in competition.log. Het bestand wordt alleen aangevuld, nooit aangepast, en staat buiten de container, zodat het een herstart overleeft.

De operator ziet de laatste regels live op de remote. De logpagina ververst elke 10 s en het hele log is te downloaden. Zo dient het log als tijdstrook: na afloop is van elke split terug te zien wanneer hij binnenkwam en of hij meetelde.

[…Z]
moment van loggen, in UTC
Lane
baan
Time
racetijd: tijdstempel min starttijd
Timestamp
ruwe tijdstempel van de klok, in ms
Elapsed
tijd volgens de hardwareteller van de baantimer
Distance · Split
afstand en splitnummer
Reason · Since last
waarom genegeerd, en hoe lang na de vorige split
competition.logvoorbeeld
{{ logSample }}
03 · De baantimer

Klein, draadloos, met een knop die je blind vindt.

Geïnspireerd op de back-upknop die tijdwaarnemers bij ETW-systemen al gebruiken. Een LilyGO T-Display S3 met eigen firmware, in een 3D-geprinte behuizing, met een losse splitknop aan een kabel. Draai het model, sluit de knop aan en probeer het.

3D wordt in deze browser niet ondersteund. De foto hieronder laat de baantimer zien.
Sleep om te draaien · behuizing uit het 3D-printbestand
Bekijk
Probeer het

{{ msg }}

  1. Scherm achter het venster: tijd, laatste splits en status
  2. 3,5 mm jack-aansluiting voor de splitknop, aan de lange zijde
  3. Splitknop: handgreep met drukknop aan een kabel; in de starterrol geeft hij de start
  4. Behuizing: 3D-geprint in twee delen, schaal en bodemplaat
Baantimer met aangesloten splitknop, kabel en klem
Foto · baantimer met aangesloten splitknop
De splitknop

Een handgreep met drukknop aan een kabel, met een haakse jack die in de zijkant van de baantimer gaat. De tijdwaarnemer houdt de knop vast en drukt bij elke aanslag.

Bij een druk legt een interrupt direct de stand van de hardwareteller vast, voordat de software iets anders doet. In de starterrol geeft dezelfde knop de start.

De knop wordt aangesloten met een 3,5 mm jackplug. De klok zelf draait op een ingebouwde LiPo-accu, dus aan het bad is geen stroomkabel nodig.

04 · Techniek

WiFi is niet altijd even snel. De tijd moet dat wel zijn.

Een bericht is niet altijd even lang onderweg. Daarom worden alle klokken eerst gelijkgezet met dezelfde tijdbron, en rekent elke baantimer bij de start zelf uit hoe laat het bericht binnenkwam.

STAP 1 · NTP

Klokken gelijkzetten

De server draait een tijdserver (chrony). Alle klokken volgen die ene bron en stellen zich elke 60 s bij, geleidelijk en nooit met een sprong. Ook zonder internet lopen ze onderling gelijk.

STAP 2 · START

Startmoment T vastleggen

De starterklok leest zijn NTP-klok uit tot op de microseconde en stuurt T naar de server. Daarna is hij vergrendeld tot een reset. De server stuurt T ongewijzigd door.

STAP 3 · TERUGDATEREN

Vertraging eraf rekenen

Elke baantimer rekent bij ontvangst uit hoeveel later dat is dan T, en laat zijn hardwareteller lopen alsof hij precies op T is gestart.

Probeer het: hoe laat kwam de start binnen?

Kies een WiFi-vertraging. De baantimer berekent d en zet zijn startmoment zoveel terug.

d = (nms − Tms) × 1000 + nµs − Tµs

Is het verschil negatief, dan neemt de baantimer 0. Voorbeeldwaarden zijn verzonnen.

Start T (van starter){{ calc.T }}
Ontvangen n (baantimer){{ calc.n }}
Berekening{{ calc.sum }}
Vertraging d{{ calc.d }}

De timer loopt vanaf het begin {{ calc.ms }} voor op het moment van ontvangst, dus gelijk met de starter.

Netwerk en server.

NETWERK

Eigen, gesloten netwerk

Lokaal opgezet in het zwembad, geen permanente installatie. Een travelrouter kan inloggen op een ander WiFi-netwerk of via LAN/WAN internet krijgen.

  • Router
  • Eén of meer 2,4 GHz WiFi-accesspoints
  • Switch (zit vaak al in de router)
SERVER

Raspberry Pi 4

Gekozen om prijs en lage eisen. Passief gekoeld, dus in een afgesloten kist te plaatsen, weg van het water.

  • Node.js: webserver en WebSockets
  • NTP-tijdserver (chrony)
  • Draait in Docker; programma, instellingen en log overleven een herstart
TOEGANG EN UITVAL

Alleen het scorebord is publiek

Via een Cloudflare Tunnel is alleen het wedstrijdscherm via internet te zien. Remote, upload, instellingen, apparaten en logs blijven lokaal.

Browsers verbinden automatisch opnieuw. De baantimer meet op zijn eigen hardwareteller.

05 · Status

Getest in de praktijk.

Gemeten op drie wedstrijden

SwimWatch liep mee op drie niveauwedstrijden in Alphen aan de Rijn. Per baan is het log vergeleken met de officiële handtijd uit de KNZB-uitslag. Verschil = SwimWatch min officieel.

Niveauwedstrijd deel 3
1 maart 2026
Niveauwedstrijd deel 4
29 maart 2026
Niveauwedstrijd deel 1
11 oktober 2026
Eindtijden vergeleken285250230
Mediaan verschil+0,17 s+0,20 s+0,10 s
Binnen 0,30 s92%86%91%
Binnen 0,10 s na correctie per serie79%83%73%

Binnen een serie is SwimWatch precies. De vaste afwijking van +0,10 tot +0,20 s ontstaat bij de handmatige start: 50m-tijd en eindtijd wijken even veel af.

In beeld

Eén heat met starter en baantimer

Een heat 100 m rugslag met één starter en één baantimer. Links de klokken met hun splitknop, rechts de remote en het wedstrijdscherm.

In deze video
  1. Opstelling: starter, baantimer met splitknop, remote en wedstrijdscherm
  2. Start: de starter drukt en de baantimer en het wedstrijdscherm gaan lopen
  3. Split na 50 m: via de server op het scherm
  4. Finish na 100 m: de baan licht op het wedstrijdscherm op