Open APIREXGEN 1REXGEN 2REXGEN 2 IMU GNSSREXGEN AirDeveloper
REXGEN Open API: control a logger over USB from your own application
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.dlland 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.
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
0when the file is sent. -
Status
0means the logger accepted the configuration.1means 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.
- REXLIBRARY: convert RXD logs and XML configurations in your own code
- REXDESK: download and export your logs
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
- On Linux, use the logger as a CAN interface. See REXGEN SocketCAN driver: use a logger as a Linux CAN interface.
- To script configuration and conversion without writing code, use REXDESK from the command line. See REXDESK: convert, configure and reflash from the command line.
- For the configuration format, see REXGEN XML configuration: how it fits together.
Products in this guide
Still stuck?
Our engineers answer support questions on every Influx Technology product.