README (5329B)
1 JJY.py: sync JJY40-enabled watches and clocks from Python 3 2 ----------------------------------------------------------- 3 This is a Python port of the 7-year old "Project Fukushima" JJY40 emulator 4 for syncing longwave-enabled watches and clocks that support this station. 5 With the help of any sort of loop antenna (or even headphones or speakers), it 6 allows you to adjust your watch without having to be close to the Japanese 7 signal. This program follows the JJY timecode specification and modulation 8 methods used by the oldest desktop applications for this very purpose, and 9 transmits on 13333.(3) Hz, whose 3rd harmonic is the reference frequency, 10 40 KHz, but the base frequency here is within the spectrum supported by any 11 consumer-grade audio hardware. 12 13 == Dependencies == 14 15 JJY.py depends on PyAudio (>=0.2.14) and ntplib (>=0.4.0). Just install them 16 by running pip install -r requirements.txt from the project directory. Note 17 that installing PyAudio will also pull its PortAudio (>=v19) dependency. 18 19 The program has been primarily tested on Python 3.10. 20 21 == Usage == 22 23 JJY.py can be run like this: 24 25 python jjy.py [-t duration] [-d delta] [-s ntp_server] [-n ntp_version] \ 26 [-o tz_offset] [-r sample_rate] 27 28 All parameters are optional here: 29 30 * -h: display help screen 31 * -t: transmission duration in minutes (default 30) 32 * -d: manual delta correction in milliseconds (default 0, see below) 33 * -o: timezone offset from UTC (in hours, default 9, see below) 34 * -r: transmission sampling rate (in Hz, default 48000, only change if this 35 fails to work) 36 * -s: specify NTP server to fetch time from (if no server is specified, then 37 local system time is used) 38 * -n: specify NTP protocol version to use, default is 4, good for most cases 39 40 After running the command, you must enter the synchronization mode on your 41 watch/clock (making sure that JJY40 is selected if it's multiband) and put it 42 close enough to your (improvised) loop antenna, headphones or speakers. The 43 script will fetch the UTC time according to your source, apply the TZ offset, 44 then the manual delta offset and then will attempt to start the transmission 45 from the closest second. The TZ offset is set to +9 hours by default because 46 most JJY-enabled watches/clocks expect the JST time to be sent in order to 47 then apply their own timezone correction according to your settings. If your 48 watch/clock doesn't have such correction, you can always use this -o flag to 49 zero out this offset (with -o 0) and transmit the local time directly onto it. 50 In case your equipment, software or time source server introduce any delay to 51 the synchronization process, you can add a constant delta (in milliseconds) 52 with the -d flag. E.g. Citizens tend to lag behind an entire second with my 53 equipment (unlike Casios), so the -d 1000 parameter is usually helpful for me. 54 55 After the synchronization is successful, you can press the 56 Ctrl+C combination or wait until the entire sequence (which is 30 minutes long 57 by default, adjustable with -t flag) gets transmitted. 58 59 == FAQ == 60 61 - How is this even possible? 62 63 To put it simply, to emit any audio signal, electricity has to travel through 64 many wires and coils. This inevitably creates electromagnetic interference. If 65 we send the signal of a particular constant frequency with enough intensity 66 through audio circuits, this interference will turn into radio emission in the 67 longwave spectrum, which is exactly what we need for syncing radio-controlled 68 clocks and watches. This emission is too weak to cause any harm outside but 69 enough to be received by the watch or clock several centimeters apart. 70 71 - Which watches/clocks has this been tested on? 72 73 Some Casio and Citizen models, including Casio GW-B5600BC, GMW-B5000D and 74 Citizen PMD56-2951. 75 76 - Is my particular watch/clock model supported? 77 78 As long as it can receive JJY40 signal and you know how to make it do this, it 79 is automatically supported by JJY.py. At this point, I can surely say that if 80 anything goes wrong, it's not the fault of your watch or your emulator, but 81 something in between: audio setup, antenna setup or the placement of the watch 82 relative to the antenna. It might take some trial and error and a great deal 83 of patience to make sure everything works as expected. 84 85 For most digital Casio models, you can force JJY40 reception by entering one 86 of the test menus: press and hold first Light, then Receive and then Mode 87 button. Scroll through with the Receive button to ensure that "J 40" is on the 88 screen, then start the reception process with the Light button. You should get 89 a "JOK" message if the process is successful, or "JNG" if unsuccessful. 90 91 - Aren't there enough JJY emulation apps already? 92 93 In 2017, there were almost no cross-platform solutions for this, and this was 94 the primary reason the Fukushima project started. However, even in 2024, I 95 could not find any Python solution for this meant for normal desktop and not 96 for Raspberry Pi, Arduino and other embedded platforms. That's why a port of 97 the JJY.js library to Python was deemed necessary. 98 99 - Are there still any plans for implementing other longwave time protocols? 100 101 Maybe. DCF77 and WWVB are of the primary interest. 102 103 == Credits == 104 105 Original research, JS library and web demo application by Luxferre, 2017. 106 Ported to Python in 2024. Released into public domain with no warranties.