I am attempting to change the display of a Delcom USB 7-segment display in Unity (Mono framework) with C#. I am able to find the device and read the serial number, but I am unable to properly send control packets. I'm pretty positive that I am forming and/or sending the data incorrectly, but I have no experience with this type of communication and am at a loss as to what to do.
I cobbled together the following code from a couple of their example programs (both in C++). I'm using InteropServices to use the unmanaged DLL that they supply.
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
public class DelcomController : MonoBehaviour
{
[DllImport("DelcomDLL", EntryPoint="DelcomGetDeviceCount")]
public static extern int DelcomGetDeviceCount(uint ProductType);
[DllImport("DelcomDLL", EntryPoint="DelcomGetNthDevice")]
public static extern int DelcomGetNthDevice(uint ProductType, uint NthDevice, StringBuilder DeviceName);
[DllImport("DelcomDLL", EntryPoint="DelcomOpenDevice")]
public static extern uint DelcomOpenDevice(StringBuilder DeviceName, int Mode );
[DllImport("DelcomDLL", EntryPoint="DelcomCloseDevice")]
public static extern int DelcomCloseDevice(uint DeviceHandle);
[DllImport("DelcomDLL", EntryPoint="DelcomReadDeviceSerialNum")]
public static extern int DelcomReadDeviceSerialNum(StringBuilder DeviceName, uint DeviceHandle);
[DllImport("DelcomDLL", EntryPoint="DelcomSendPacket")]
public static extern int DelcomSendPacket(uint DeviceHandle, ref PacketStructure PacketOut);
[DllImport("DelcomDLL", EntryPoint="DelcomLEDControl")]
public static extern int DelcomLEDControl(uint DeviceHandle, int Color, int Mode);
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct PacketStructure
{
public byte Recipient;
public byte DeviceModel;
public byte MajorCmd;
public byte MinorCmd;
public byte DataLSB;
public byte DataMSB;
public byte Length;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst = 8 )]
public byte[] DATA ; //Data 1 .. 8
}
private uint hUSB;
private static int DisplaySize = 6;
PacketStructure packet = new PacketStructure ();
void Start ()
{
int Result = 0;
StringBuilder DeviceName = new StringBuilder (512);
// Serach for the first match USB device, For USB IO Chips use Delcom.USBIODS
// With Generation 2 HID devices, you can pass a TypeId of 0 to open any Delcom device.
try
{
Result = DelcomGetNthDevice (3, 0, DeviceName);
}
catch
{
print ("Error in DelcomGetNthDevice ().");
}
if (Result == 0)
{ // if not found, exit
print ("Device not found!\n");
return;
}
print ("Device found: "+ DeviceName); // This prints the GUID properly..
hUSB = DelcomOpenDevice(DeviceName, 0);
print ("Device opened: " + hUSB.ToString ()); // This prints the handle fine.
int serial = DelcomReadDeviceSerialNum (DeviceName, hUSB);
print ("Device serial: " + serial.ToString ()); // This prints the correct serial.
// Next, I'm attempting to turn on all of the digits using the example in NDHIDTEST as a reference.
// The device does nothing. I'm pretty sure I'm not forming the packet properly, but I'm not exactly
// sure of what changes to make.
// Enter 8-digit mode.
DisplaySizeSetup (8);
// Turn all digits on.
packet.MajorCmd = 101;
packet.MinorCmd = 81;
packet.DataLSB = 0;
packet.DataMSB = 0;
DelcomSendPacket (hUSB, ref packet);
packet.MajorCmd = 101;
packet.MinorCmd = 80;
packet.DataLSB = 1;
packet.DataMSB = 0;
DelcomSendPacket (hUSB, ref packet); // blink off
// I'm doing this just for our test program to make sure we keep the device open for long enough.
StartCoroutine (CloseDevice ());
}
private IEnumerator CloseDevice ()
{
yield return new WaitForSeconds (5f);
DelcomCloseDevice(hUSB);
print ("Device closed.");
}
}
So GetNthDevice finds the display, hUSB is populated with the identifier using the resulting DeviceName, and the correct serial is read. Next, I'm attempting to send over a data packet that is used in one of their test programs that is supposed to simply illuminate all of the LEDs on the display, but it doesn't do anything.
Ultimately, what I need is to know how to set each of the four digits on the display.