GPS time vs. UTC

 Delphi  Comments Off on GPS time vs. UTC
Jul 312019
 

If you have ever worked with GPSes you probably know about the NMEA protocol. Many of the sentences there have got a time stamp that is in UTC (universal time coordinated – thank the French for the odd word order). Like me, you might have assumed that GPS works with UTC, but that is not the case.

Internally GPS works with GPS time which is kept as weeks and seconds since the start of the GPS system at 00:00:00 on 1980-01-06. This time is kept by atomic clocks. The other GNSSes (Global Satellite Navigation Systems) also have their own internal clock.

UTC (formerly known as GMT) is the local time at longitude 0 (where the London district Greenwich is located, hence Greenwich Mean Time), without any fiddling with daylight savings time. Since UTC is meant to conform closely to the rotation of the earth and the latter is not stable, it needs the occasional leap second. At the time of this writing, there have been 18 of these since 1980. So UTC is 18 seconds behind GPS time by now.

Why do I write about this? I have recently started integrating an OXTS INS into one of our measurement vehicles. These devices can be configured to send NMEA data over a serial port, just like a conventional GPS. They can also send NCOM data, which is their internal binary format. While the NMEA data adheres to the NMEA specification of providing the times in UTC, the NCOM data does provide the “native” GPS time. So they do not match, which took me by surprise when I encountered it.

Of course I first assumed a bug in my own code, but it wasn’t. The first hint was that the times were always 18 seconds off. I still didn’t get it and had to actually call support. (Afterwards I googled it and found lots of references, so I guess I should have been able to figure it out myself.)

Since that offset is not constant – there might be yet another leap second soon – the NCOM format also contains the current UTC time offset. Look in Table 26 on the NCOM format documentation.

It’s sent in the Status Information as channel 15 and is stored in byte 7 of the BatchS structure. Just to make it difficult to read it is encoded as a 8 bit signed integer with a twist: Bits 1–7: UTC time offset, valid when Bit 0 = 1.

Here is some Delphi code to decode that particular value:

function TSTable26Rec.TryGetUtcTimeOffsetSecs(out _Offset: Integer): Boolean;
begin
  // only valid if Bit0 = 1
  Result := ((UtcTimeOffset and $01) <> 0);
  if Result then begin
    // the type cast to Smallint is necessary to get the sign correctly
    _Offset := Smallint(UtcTimeOffset shr 1);
  end;
end;
 Posted by on 2019-07-31 at 10:11

Common unit aliases for backwards compatibility to older Delphi versions

 Delphi  Comments Off on Common unit aliases for backwards compatibility to older Delphi versions
Jul 282019
 

Backwards compatibility to older Delphi versions is an issue mostly encountered by component and IDE plugin developers. Borland, Codegear and Embarcadero actually did quite a good job in that area. Many ancient projects (at least back to Delphi 6) can simply be loaded into a later IDE and they just compile. The IDE usually makes the necessary changes. That of course does not mean that there aren’t any hiccups 😉

One commonly encountered problem is that some declarations have moved to different or newly introduced units over the time. Two examples of that are

(I hope I got these right.)

This has two effects:

  1. Later IDEs automatically add the new unit names to the uses lists of forms that use these components. Unfortunately it ignores any {$IFDEF}s you might already have in place there, so the generated source code does not compile due to a duplicate in the uses list: “E2004 Identifier redeclared: ‘Actions'”.
  2. Older IDEs will no longer compile the code because these units are not available there: “F1026: File not found ‘Actions.dcu'”

Unit aliases can solve this problem. You add an entry “NewUnit=OldUnit” to the unit aliases list in the project options, in this case that would be:

Actions=ActnList;ImageList=Controls

You then simply add the new unit names to the uses list. This solves both issues: The IDE will find the unit it expects and will no longer try to add it. And older compilers will know that the new unit just maps to another one they can find.

If it’s just about backwards compatibility, an entry “NewUnit=System” would also do the trick.

btw: You can safely remove the pre defined aliases for the units Windows and BDE. They date back to ancient times (Delphi 3 in 1997?) when multiple units for each of these were merged into a single one.

btw: Apparently it is not possible to define a unit alias that starts with an underscore:

_Actions=ActnList

will result in the compiler error: “F1030: Invalid compiler directive: ‘-A_Actions=ActnList'” (at least in Delphi 2007). It’s allowed to end in an underscore though.

Edit: I already blogged about unit aliases and what they are good for in 2016 in Backwards compatibility of uses lists. So this is just some additional explanation and also gives me the list should I need it again.

 Posted by on 2019-07-28 at 14:19

Bugfix for Delphi IDE explorer in Delphi 10.3

 Delphi  Comments Off on Bugfix for Delphi IDE explorer in Delphi 10.3
Jul 272019
 

In December 2018 I found out that some of the functionality in my Delhi IDE explorer was broken in Delphi 10.3, namely the function to select the current active control or automatically follow the focus. The reason was that the IDE now used the Screen.ActiveControlChanged event itself, disabling it for to my plugin.

Today I finally found a way to fix it, so the current source code will work with Delphi 10.3 (all three releases).

 Posted by on 2019-07-27 at 14:49

GExperts and Delphi 10.3.2

 Delphi, GExperts  Comments Off on GExperts and Delphi 10.3.2
Jul 202019
 

Everybody and his brother – ahem – sister is blogging about the latest Update for Delphi 10.3 which has been announced two days ago. As always, Embarcadero’s servers are overloaded and have been down for hours. I have now started downloading the ISO and my browser is telling me it should be finished in 90 minutes. I’m not convinced yet…

The first feedback has been that GExperts seems to work with the new version but there is an access violation when exiting the IDE. I’ll give it a try once the download has finished and if I can actually install the new version.

edit: I’m impressed (not): Installing the update messed up my installation. The bds.exe is nowhere to be found. 🙁 Trying to un- and reinstall now.

edit2: Now it’s starting but tells me my update subscription has expired (I renewed it for a year back in May 2019.). Apparently something needs to be done with our license server. Don’t expect me to fix anything in GExperts for Delphi 10.3.2 until Monday. And then I will probably be too busy with work to do more than write an email to Embarcadero. Good thing I don’t need the latest and greatest Delphi version for work. I have a tight deadline already as it is. I don’t need the hassle of getting my primary tool to actually start on top of that.

Everybody else of course is welcome to get the GExperts sources and compile their own DLL to test. I’m interested in feedback about self compiled DLLs more than about the last release. If somebody can track down the AV and maybe even propose a fix that would be great.

 Posted by on 2019-07-20 at 11:17

Where does Delphi store the desktop settings? And what do they mean?

 Delphi  Comments Off on Where does Delphi store the desktop settings? And what do they mean?
Jul 142019
 

I keep forgetting this so this post is mostly so I can look it up:

Delphi uses DST files to store the desktops – that is the layout of the various parts of the IDE. Theses files are in INI format and are stored in

Delphi 2007 and later
[users]\[username]\AppData\Roaming\[Company]\BDS\[version]
e.g. c:\users\johndoe\AppdData\Roaming\Embarcadero\BDS 20.0
Delphi 2006 and older
[programfiles]\[company]\[Delphi X]\bin
e.g. c:\program files\Borland\Delphi 7\bin

Since AppData is a hidden directory, a search for *.dst in the Windows Explorer will not find these files. An easy way to get to AppData is opening an Explorer Window and typing %appdata% into its address field.

Why would you want to find these files?

Delphi 10.3 has a very annoying bug where it does not store the window position correctly. E.g. I move the IDE window to my secondary monitor and maximize it. When I exit and restart it, the Window will appear somewhere on my primary monitor and usually be very small. Editing the DST file fixed that for me.

NOTE: The following applies to Delphi 10.3 Rio. Old versions stored the size and position in pixels. I don’t know when exactly they switched to “percentages”.

WARNING: If you write invalid values into the file, the IDE will crash on startup (We call that “failing gracefully”. 😉 ) So be sure to always keep a backup of a working file (or copy one of the default files over your borked file if you run into problems).

I set the following entries:

[Main Windows]
PercentageSizes=1
State=0
Left=-10000
Top=0
Width=10000
Height=10000

PercentageSizes apparently means that the values are stored as percentages of the actual width and height of the monitor, for an appropriate meaning of “percentage”, in this case 1/10000, so 10000 means: Use the full width and height. The same goes for Top and Left. My secondary monitor is to the left of the primary one, that’s where the -10000 value for Left is coming from.

State=0 means that the window state is normal, that is: not maximized (and also not minimized, but who wants a minimized window for this?). State=2 means maximized and is what does not work for me at all.

 Posted by on 2019-07-14 at 11:26

Delphi Shortcut Finder for 10.x

 Delphi  Comments Off on Delphi Shortcut Finder for 10.x
Jul 132019
 

Nicholas Ring wrote a useful Delphi IDE plugin called Delphi Shortcut Finder and made it open source on GitHub.

Unfortunately he updated it last in 2015, so it has become yet another abandoned Delphi tool.

I had a need for something like this today and remembered the tool, but unfortunately not its name. So it took me a while to find it again.

Just in case somebody else needs it, here are precompiled packages for

Note that installing it requires Virtual Tree View to be installed already.

The sources I used are here

 Posted by on 2019-07-13 at 19:56

TStringGrid has Rows and Cols properties

 Delphi  Comments Off on TStringGrid has Rows and Cols properties
Jul 132019
 

From the “How could I have missed this for decades?” department:

The TStringGrid component in Delphi has got two interesting properties which I didn’t know about:

I found out about rows when I searched for code for sorting a StringGrid and found something at SwissDelphiCenter that uses this property. Then I looked it up in the online help and found that there is also a similar property for columns.

Now the question is: Did I really miss this or have I already forgotten? And if the latter, how many times? 😉

 Posted by on 2019-07-13 at 16:46

Troubleshooting FTDI driver installation

 Windows, Windows 7  Comments Off on Troubleshooting FTDI driver installation
Jul 042019
 

So I don’t forget:
If the drivers for an FTDI USB-serial adapter don’t install resulting in an "unknown device", try to remove all other USB connected devices.

In my case it was a PeakCAN USB adapter, connected via a rather long USB extension cable, that caused the problem (not sure whether it was the adapter itself or the extension cable, that caused it, but I assume the latter, because these adapters usually don’t cause any trouble).

Temporarily disconnecting the cable let me install those USB serial adapter drivers.

The problem was reproducible: It happened after each reboot.

Another unproductive hour spent troubleshooting a Windows driver problem. I just hate Windows and its opaque driver installation method. Give me real error messages Microsoft, so I at least get a clue what’s wrong!

 Posted by on 2019-07-04 at 11:16