Open APIREXGEN 1REXGEN 2REXGEN 2 IMU GNSSREXGEN AirDeveloper

REXGEN Open API: control a logger over USB from your own application

Updated

Call the REXGEN device library from your own Windows application. Over USB, it checks a logger, configures it, sets its clock, downloads its logs and reads live data.

What you need

  • A logger with a USB PC connection: REXGEN 1, REXGEN 2, REXGEN 2 IMU GNSS or REXGEN Air over its Micro USB port. REXGEN Pro connects over Wi-Fi and has no USB PC connection, so the library does not work with it.
  • The REXGEN USB driver. REXDESK installs it. See REXDESK: install the software and the REXGEN USB driver.
  • The demo application. It is a Visual Studio solution for .NET Framework 4.8. It holds RGUSBdrv.dll, RxLibrary.dll and the source of every call in this guide. Download the REXGEN Open API demo (ZIP, 3.1 MB).

The API has two libraries. This guide covers RGUSBdrv.dll, which talks to the logger over USB. RxLibrary.dll works on files: it compiles XML to the RXC configuration format and converts RXD logs. See REXLIBRARY: convert RXD logs and XML configurations in your own code.

Which library does what REXGEN OPEN API · TWO LIBRARIES Which library does what RxLibrary.dll works on files, on Windows or Linux XML file .xml RxLib.XmlToRxc compiles RXC file binary configuration RXD log from the logger RxLib.ConvertData converts MF4 BLF ASC TRC CSV MAT Parquet the output file's extension picks the format RGUSBdrv.dll the logger over USB, on Windows Your application on the PC REXGEN logger USB PC connection DeviceIsReady, GetFirmwareVersionExt is a logger ready, which firmware SendConfiguration sends an RXC file ReflashLogger writes a firmware file GetDateTime, SetDateTime reads or sets the clock, in UNIX time GetLogCount, GetSDLogInfo counts and describes the logs GetLogData copies a log to an RXD file on the PC FormatSDCard erases the internal storage InitLiveData, GetLiveData, StopLiveData live data, a 512-byte buffer at a time The RXC that RxLib.XmlToRxc writes is what SendConfiguration sends; the RXD that GetLogData writes is what RxLib.ConvertData reads. RGUSBdrv.dll needs the REXGEN USB driver (installed with REXDESK) and a logger with a USB PC connection; REXGEN Pro has none. Arrows point the way the data goes.

Build a wrapper

RGUSBdrv.dll is a native library with the cdecl calling convention. Copy it next to your executable and declare the calls you need with DllImport. These declarations match the demo's UsbDllWrapper.cs:

using System;
using System.Runtime.InteropServices;

public static class RexgenUsb
{
    const string Dll = "RGUSBdrv.dll";

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte DeviceIsReady();

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte GetFirmwareVersionExt(out ushort MajorVersion, out byte MinVersion, out byte BranchVersion, out byte FwType);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte SendConfiguration(char[] FileName, out short Status);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte ReflashLogger(char[] FileName, out short Status);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern UInt32 GetDateTime();

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte SetDateTime(uint DateTimeUNIX);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern UInt16 GetLogCount();

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte FormatSDCard(ushort FormatType, out short Status);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte GetSDLogInfo(ushort LogNumber,
        IntPtr StartLogDateTime, IntPtr EndLogDateTime,
        IntPtr LoggingTimeStart, IntPtr LoggingTimeEnd,
        IntPtr LogStartDataSector, IntPtr LogEndDataSector,
        IntPtr LogDataSize, IntPtr GUID, IntPtr FileName, IntPtr isEncrypted);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte GetLogData(IntPtr FileName, uint StartSector, uint EndSector);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte InitLiveData(byte Channel);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte GetLiveData(byte Channel, IntPtr LiveData);

    [DllImport(Dll, CallingConvention = CallingConvention.Cdecl)]
    public static extern byte StopLiveData(byte Channel);
}

The examples in this guide use this class. They also need using System.Text; and using System.Threading.Tasks;.

Check the logger

DeviceIsReady()

Returns a value above 0 when a logger is connected and ready. Call it before any other function.

public static bool Connected => RexgenUsb.DeviceIsReady() > 0;

GetFirmwareVersion()

Reads the logger's firmware version. The V2 demo calls it as GetFirmwareVersionExt. It returns four out values: major, minor, branch and release type (0 none, 1 A, 2 B, 3 RC).

static readonly string[] ReleaseType = { "", "A", "B", "RC" };

public static string FirmwareVersion()
{
    RexgenUsb.GetFirmwareVersionExt(out ushort major, out byte minor, out byte branch, out byte type);
    string suffix = type < ReleaseType.Length ? ReleaseType[type] : "";
    return $"{major}.{minor}.{branch} {suffix}".Trim();
}

Configure and update the logger

SendConfiguration()

Sends a compiled configuration (an RXC file, not XML) to the logger. Pass the full path as a null-terminated character array. Compile XML to RXC first with REXLIBRARY's RxLib.XmlToRxc or with REXDESK.

  • Returns 0 when the file is sent.
  • Status 0 means the logger accepted the configuration. 1 means the configuration is bad.
public static string Configure(string rxcPath)
{
    byte res = RexgenUsb.SendConfiguration((rxcPath + '\0').ToCharArray(), out short status);
    if (res != 0)
        return "Communication error";
    return status == 0 ? "Logger configured" : "Bad configuration";
}

The example returns one result for each call.

ReflashLogger()

Writes a firmware file to the logger, which then restarts. Pass the full path as a null-terminated character array. Status 0 means the logger accepted the firmware. Use the firmware that ships with REXDESK. See REXGEN: update the firmware and set the clock.

public static async Task<bool> Reflash(string firmwarePath)
{
    byte res = RexgenUsb.ReflashLogger((firmwarePath + '\0').ToCharArray(), out short status);
    if (res != 0 || status != 0)
        return false;

    await Task.Delay(2000);                 // give the logger time to restart
    for (int i = 0; i < 60 && RexgenUsb.DeviceIsReady() == 0; i++)
        await Task.Delay(1000);             // wait up to a minute for it to reconnect
    return RexgenUsb.DeviceIsReady() > 0;
}

Do not disconnect the logger during a firmware update.

Set and read the clock

GetDateTime()

Returns the logger's real-time clock as UNIX time (seconds since 1 January 1970).

public static DateTime LoggerTime() =>
    DateTimeOffset.FromUnixTimeSeconds(RexgenUsb.GetDateTime()).UtcDateTime;

SetDateTime()

Sets the clock from a UNIX time. GetDateTime reads the value back as UTC, so pass UTC, not the PC's local time.

public static void SetLoggerTimeNow() =>
    RexgenUsb.SetDateTime((uint)DateTimeOffset.UtcNow.ToUnixTimeSeconds());

List and download logs

The "SD" in these names is historical. The logs are in the logger's internal storage (eMMC).

GetLogCount()

Returns the number of logs in the main partition.

ushort count = RexgenUsb.GetLogCount();

GetSDLogInfo()

Describes one log. Logs are numbered from 0 to the count minus 1. The call writes these values through pointers:

  • Start and end date and time (UNIX)
  • Logging start and end time
  • First and last data sector
  • Data size
  • The configuration GUID (16 bytes)
  • The configuration name (up to 256 bytes)
  • An encryption flag (1 byte)

Pin the buffers so they cannot move during the call.

public static (DateTime Start, uint FirstSector, uint LastSector, string Name, bool Encrypted) LogInfo(ushort logNumber)
{
    var values = new uint[7];      // start, end, logging start, logging end, first sector, last sector, size
    var guid = new byte[16];
    var name = new byte[256];
    var encrypted = new byte[1];
    var pins = new[] {
        GCHandle.Alloc(values, GCHandleType.Pinned), GCHandle.Alloc(guid, GCHandleType.Pinned),
        GCHandle.Alloc(name, GCHandleType.Pinned), GCHandle.Alloc(encrypted, GCHandleType.Pinned) };
    try
    {
        IntPtr v = pins[0].AddrOfPinnedObject();
        RexgenUsb.GetSDLogInfo(logNumber,
            IntPtr.Add(v, 0), IntPtr.Add(v, 4), IntPtr.Add(v, 8), IntPtr.Add(v, 12),
            IntPtr.Add(v, 16), IntPtr.Add(v, 20), IntPtr.Add(v, 24),
            pins[1].AddrOfPinnedObject(), pins[2].AddrOfPinnedObject(), pins[3].AddrOfPinnedObject());
        return (DateTimeOffset.FromUnixTimeSeconds(values[0]).UtcDateTime, values[4], values[5],
                Encoding.ASCII.GetString(name).TrimEnd('\0'), encrypted[0] == 1);
    }
    finally
    {
        foreach (var p in pins) p.Free();
    }
}

GetLogData()

Copies a log from the logger to a file on the PC. Pass the full path of the new file as null-terminated ASCII, ending in .rxd. Also pass the first and last data sector from GetSDLogInfo. Returns 0 on success.

public static bool Download(string rxdPath, uint firstSector, uint lastSector)
{
    var path = GCHandle.Alloc(Encoding.ASCII.GetBytes(rxdPath + '\0'), GCHandleType.Pinned);
    try { return RexgenUsb.GetLogData(path.AddrOfPinnedObject(), firstSector, lastSector) == 0; }
    finally { path.Free(); }
}

To read the RXD file, convert it with REXLIBRARY or REXDESK.

FormatSDCard()

Formats the logger's internal storage. Returns 0 on success and 1 on a USB communication problem. Status 0 means the format completed. The demo passes FormatType 1.

bool formatted = RexgenUsb.FormatSDCard(1, out short status) == 0 && status == 0;

Stream live data

InitLiveData()

Starts live data on a channel. The demo uses channel 0.

GetLiveData()

Fills a 512-byte buffer with the latest records. Each record names its source block by that block's UID in the active configuration. The configuration must therefore contain the blocks you want to see. See REXGEN XML reference: recording (SD) and USB outputs. The demo's FormLive.cs shows how to parse the buffer.

StopLiveData()

Stops live data on the channel.

RexgenUsb.InitLiveData(0);
var buffer = new byte[512];
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
    if (RexgenUsb.GetLiveData(0, handle.AddrOfPinnedObject()) == 0)
    {
        // parse buffer as FormLive.cs does
    }
}
finally
{
    handle.Free();
    RexgenUsb.StopLiveData(0);
}

Other ways to reach the logger

Products in this guide

REXGEN 1

Vehicle black box

View REXGEN 1 Ask an engineer

REXGEN 2

Evidence data logger

View REXGEN 2 Ask an engineer

REXGEN 2 IMU GNSS

Motion & location data logging

View REXGEN 2 IMU GNSS Ask an engineer

REXGEN Air

CAN to cloud

View REXGEN Air Ask an engineer

Still stuck?

Our engineers answer support questions on every Influx Technology product.