Suggestions for NTP to NMEA-0183?

Hey there,

unfortunately, I did not find any similar project.

I have some older Nixie clocks that support NMEA-0183 as time reference.
I would like to build some NTP to NMEA-0183 converters with an ESP or so.

Unfortunately I do not find anything about sending NMEA-0183 with such an device (just receiving).

Does anyone knows a referance for such ideas?

With kind regards,
Felix

Seen this one ?

https://docs.arduino.cc/learn/communication/gps-nmea-data-101/

Not familiar with NMEA-0183, but it seems pretty straighforward comma separated text.

How to gather all additional fields is a question as NTP only supplies the timestamp in field 2.

Furthermore Wikipedia gives a lot of details

I suppose your question is not about the format (although you need to know if the listener expects like RMC, ZDA...) but more about the hardware side of things.

with NMEA-0183 the talker is an RS-422 style differential line driver, and the listener as an opto-isolated differential receiver.

The receiver side is trivial, which is why you have no problems finding tutos to cover reading TTL serial into a microcontroller.

The transmit side is harder, since building a proper talker means adding real line driver hardware.

The minimum hardware for a talker is one small differential line driver chip between the microcontroller UART TX pin and the two wires going out to the bus (and a few extra components likely a cap or something - I'm a software guy but I'm sure you can find that out). A MAX3488E or SN65HVD3082E would probably do the job and both are 3.3V RS-422 or RS-485 transceivers that would work directly off an ESP32 logic level.

The driver enable pin needs to be tied high permanently as you’re only ever transmitting and never listening back. The chip’s A and B output pins become the NMEA-0183 pair.

If this is for boating, a shared ground wire alongside the 2 wires is worth adding too, since I think to remember old marine listener hardware expects one even though the differential signal does not strictly need it.

(I’ve moved all my gears to NMEA-2000 so don't really remember all the details)

Have you got any code from your old clocks which is used to interpret the NMEA sentences ?
Mine look for such an example string:

$GPRMC,141715.00,A,3300.82667,N,00200.21356,E,3.587,58.89,231121,,,A*50

(lightly anonymized)

EDIT
I'm assuming that the existing GPS modules delivered a standard serial output, say at 9600 baud, to your clock and you are going to tap in there somehow with the ESP32.

To @Crix1990

Can you clarify if you are asking about the hardware circuit to send out a phrase which includes the time or if you are asking about formatting such a phrase ?

Yes, agreed. The line driver should have as a minimum an 0μ1 capacitor connected between the power and ground pins as close as physically possible.

https://www.analog.com/en/products/max3488e.html

Note this is a 3V3 device (not 5V) and is one transceiver.

This can work on 5V

You might also consider:

Which gives you 4 line drivers in one package. The corresponding receivers are AM26LS32. I use these for something similar to what you are proposing: Inspired by the GPS sentence idea with $xxyyy as the start I use $xxx as the start for conveying the time, temperature and other measurement, and and TLP2768 opto isolators to receive the data.

Of course this is all pure, but nevertheless interesting, speculation at the moment, until the OP provides further details, but if the nixie clocks have a module such as this: GPS Time Receiver For Nixie Clock [GPS7] - £29.95 - PV Electronics and, for reasons which I hope will become clear, the OP wants to replace it with an ESP32 then, as far as I can see, it should be quite straightforward. A bit of level shifting, perhaps, and sending a timestamp message in the form of an NMEA sentence at regular intervals.

Hey together,

thanks already for the input.

So to clear the situation up, I have several old Mr. Nixie clocks.
Till today I use just the internal clockwork to run them, but I would like to have them controlled by an external time signal.

They should work with an external GPS module like 6v6gt linked in his last post, since it has a headphone jack for this.

Since my clocks are not close to a window or so, I would prefer to use WiFi / NTP as a source.

Unfortunateley, the manual just says this (besides it needs NMEA0183):#

Radio Frequency Time or GPS Receiver
The clock can automatically synchronise time from DCF (Europe), MSF (UK) and WWVB (US).
The clock can also receive time from a GPS receiver that transmits information using NMEA-0183 protocol with $GPRMC
sentence; e.g. the wired BR-355 or the wireless GPS connection.
1. Set option 12 for: 1 = DCF, 2 = WWVB, 3 = MSF, 4 = GPS
• If using GPS, set the baud rate in option 13 (normally 4.8 kbps).
2. Set option 14 and 15 for the hours and minutes your time zone on standard time (no DST) is offset from the
synchronization source. This are usually only a whole hours:
• Germany is 1 hour plus offset (non DST) from UTC time transmitted by the GPS.
• UK is 1 hour minus offset from the time transmitted by the German DCF signal.
• France has no offset from the time transmitted by the German DCF signal.
3. Set option 16 to identify if your offset must be added or subtracted from the time source.
4. If you’re using WWVB source and you don’t need require automatic DST adjustment, set option 17 to “1”
5. Set option 23 to select between hourly seek and daily seek in DCF / WWVB / MSF modes. Daily seek is
recommended.
6. If you have selected daily seek, use option 24 to set the time of the daily seek.
7. Leave option 25 set to “1” to turn off the tubes during seek. This prevents interferences by the HV generator.
Set this option to “0” when using GPS source.

So my question was regarding general suggestions and examples how to go with it.

Since I am some kind with these signals (I worked as integrator for nautical Wempe network systems), I can summerise my PoV till now on this:

Yes, I need a RS422 signal as output.
I think this might be the easiest way for me:

The NMEA sentences rom post #4 looks exactly like what I would need.

So what I need to do is:
-Log into Wifi
-Grab NTP signal
-Parse it to NMEA sentences (I have no idea about that logic)
-Send it out via the module as RS422

I hope this makes it much more clear.

Regards,
Felix

then it's just a matter of getting the right time from NTP and building the sentence and send it out over Serial

Serial monitor will show

NTP to GPRMC demo
IP address obtained = 10.10.0.2
NTP synced
$GPRMC,170439.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*38
$GPRMC,170440.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*36
$GPRMC,170441.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*37
$GPRMC,170442.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*34
$GPRMC,170443.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*35
$GPRMC,170444.00,A,0000.0000,N,00000.0000,E,0.0,0.0,071126,,*32
...
click to see the code
#include <WiFi.h>
#include <esp_sntp.h>

const char *ssid = "Wokwi-GUEST";
const char *wifiPassword = "";

const char *ntpServer = "fr.pool.ntp.org";  // French one, use "pool.ntp.org" to be generic

bool ntpSyncDone = false;

void ntpSyncCallback(struct timeval *tv) {
  ntpSyncDone = true;
  Serial.println("NTP synced");
}

void wifiStationGotIp(WiFiEvent_t event, WiFiEventInfo_t info) {
  Serial.print("IP address obtained = ");
  Serial.println(WiFi.localIP());
}

void wifiStationDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
  Serial.println("Disconnected from network, attempting to reconnect");
  WiFi.begin(ssid, wifiPassword);
}

// builds and sends a $GPRMC sentence from the current system time
void sendGprmc() {
  time_t now = time(NULL);
  struct tm *utcTime = gmtime(&now);

  char sentence[96];
  char body[80];

  // position is not available from NTP, so a fixed null position is sent with a valid "A" status
  // you can also hard code your actual location here instead of the null one, if you want the sentence to carry it  

  snprintf(body, sizeof(body),
           "GPRMC,%02d%02d%02d.00,A,0000.0000,N,00000.0000,E,0.0,0.0,%02d%02d%02d,,",
           utcTime->tm_hour, utcTime->tm_min, utcTime->tm_sec,
           utcTime->tm_mday, utcTime->tm_mon + 1, utcTime->tm_year % 100);

  uint8_t checksum = 0;
  for (size_t i = 0; i < strlen(body); i++) {
    checksum ^= body[i];
  }

  snprintf(sentence, sizeof(sentence), "$%s*%02X\r\n", body, checksum);
  Serial.print(sentence);
}

void setup() {
  Serial.begin(115200);

  WiFi.onEvent(wifiStationGotIp, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP);
  WiFi.onEvent(wifiStationDisconnected, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);

  configTzTime("UTC0", ntpServer);  // GPRMC time is UTC, no timezone offset
  sntp_set_time_sync_notification_cb(ntpSyncCallback);

  WiFi.begin(ssid, wifiPassword, 6); // get rid of the 6 if not on wokwi
  Serial.println("NTP to GPRMC demo");
}

void loop() {
  static unsigned long lastSend = 0;

  if (ntpSyncDone && millis() - lastSend >= 1000) {
    sendGprmc();
    lastSend = millis();
  }
}

Thank you!

I think that is exactly what I was looking for!

Do I assume right, that I still need a RS422 module for this?

Regards,
Felix

That depends on the input requirements of your clock.
The module that 6v6gt posted a link to in post #7 does not have an RS422 output.

Do you have any further details about the clock that you can share with us?

I guess you would use the same jack socket if you use the DCF radio option and these modules sometimes output a very low voltage, say 1.5v, so it could well be that you need nothing special between the ESP32 and the jack socket, however, I'd start with a resistor of say 1k and a common ground.

Your serial output has to conform to whatever options you can set here:

If using GPS, set the baud rate in option 13 (normally 4.8 kbps)

Looking further, I found this for one model of the "Mr. Nixie" clock: https://www.manualslib.com/manual/1744380/Mr-Nixie-Sv410.html?page=10 . I'm not sure if this matches yours, though. The DCF/ GPS socket is on the left. There appears to be a solder jumper possibly for inverting the signal. The direct signal goes directly to a pin of a PIC microcontroller which is powered at 5v so here it looks like the ESP output would have to level shifted to 5v. Note that 5v appears also on that socket.

Or maybe also try to find some documentation which more closely matches your exact clock.

Incidentally, there are existing projects for generating a DCF77 time signal using an ESP, some of which can even generate the 77.5Khz radio signal. Googling for "dcf77 signal generation by esp" gets a number of hits. But I'm sure also that @J-M-L could also enhance his code to provide a DCF77 signal emulator to give you another option.

EDIT

Looking at the manual extract that the OP presented, the daylight saving time handling of the clock seems somewhat crude. There doesn't appear, for example, to be any way of adjusting the date and time of the DST switch/switch back. It may be better to do time zone conversion on the ESP32 and roll that into in the NMEA sentence . The clock would then be configured as if it were in a UTC timezone with a 0 dst offset.

Do you have access to the full Dow of your module ?

That would help clarify what’s expected electrically.

BR-355: Globalsat BR-355N5 Serieller RS232 GPS Maus/Empfänger (Galileo, QZSS, SBAS)

Conclusion (with all the usual caveats) is that a simple (maybe not even level shifted) serial output from the ESP32 should be enough. Either a hardware Serial port or software serial should do.

Here we go with all the manuals:

Both contain English as well.

Seems like the GPS module 6v6gt (btw. nice tube) linked would work natively:

ut I still would prefer to go with NTP / Wifi.

Regards,
Felix
B

It looks like the main part of the circuit you are interested in is here. The connection DCF is directly to a PIC pin:

I'm assuming that you want to use the existing jack socket and don't want to make invasive changes to the circuit board. I'd probably wire it like this and leave the polarity jumper connected between positions B and C. I'm also assuming that the optional module ASK-RXB2 is not installed.

This level shifts from 3v3 to the 5v used in the rest of the circuit. Of course, there are other ways of doing it but this should work. The connection ESP32_TX is from a second UART (or software serial pin) on the ESP32 and the primary UART should be reserved for debug output.

It looks like Daylight Saving Time (DST) change is not automatic and you must press a button to manually make the change. Is that so and do you want to keep it like this ?