After digging into this a bit deeper, I realized the Kogna ADC and DAC values are indeed uploaded with the "GetStatus" command, they are just not parsed and exposed through the MainStatus structure in the Kmotion_dotNET dll (unless I am missing something).
To workaround this I have:
- made a C# structure to replicate the MAIN_STATUS struct in PC-DSP.h
- periodically request "GetStatus" to upload the binary data in Hex string format
- convert the hex string into a continuous byte array
- marshal the byte array into the C# KognaMainStatus structure
This seems to be working well. I have played with setting various parameters in the Kmotion.exe GUI and seeing the changes being marshalled correctly in my C# data structure.
I am sure I have a few bugs to work out yet, but in case it is of interest...
The marshalling code:
Code: Select all
//above this point the main_status_byte_array was populated by parsing the string returned from KM.WriteLine("GetStatus")
// Pin the managed memory, marshal it into the structure, and the free it back up
GCHandle handle = GCHandle.Alloc(main_status_byte_array, GCHandleType.Pinned);
KognaMainStatus KogMainStat = (KognaMainStatus)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(KognaMainStatus));
handle.Free();
My C# definition of the KognaMainStatus derived from PC-DSP.h
Code: Select all
public const int N_PC_COMM_PERSIST = 8;
public const int N_DACS = 8; // Kanalog
public const int N_ADCS = 8;
public const int N_PWMS = 8;
public const int N_ENCS = 8;
public const int N_ENCS_KOGNA = 20;
public const int N_DACS_KOGNA = 8; // referenced after Kanalog as 8-15
public const int N_ADCS_KOGNA = 4; // referenced after Kanalog as 8-11
public const int N_ADCS_SNAP= 8; // per snap amp
public const int N_PWMS_SNAP =4; // per snap amp
public const int N_ENCS_SNAP =4;
public const int N_CHANNELS_KOGNA = 16;
public const int N_IO_PWMS = 8;
public const int N_KOGNA_HRPWM = 4;
public struct KognaMainStatus
{
int VersionAndSize; //bits 16-23 = version, bits 0-15 = size in words
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_ADCS+2* N_ADCS_SNAP)] int[] ADC;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_DACS)] int[] DAC;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_PWMS + 2 * N_PWMS_SNAP)] int[] PWM;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_CHANNELS_KOGNA)] double[] Position;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_CHANNELS_KOGNA)] double[] Dest;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_CHANNELS_KOGNA)] byte[] OutputChan0;
int InputModes; // 4 bits for each axis (not sure why only using 16 of 32 bits)
int InputModes2; // 4 bits for each axis
int InputModes3; // 4 bits for each axis
int InputModes4; // 4 bits for each axis
int OutputModes; // 4 bits for each axis
int OutputModes2; // 4 bits for each axis
int OutputModes3; // 4 bits for each axis
int OutputModes4; // 4 bits for each axis
int Enables; // 1 bit for each axis
int AxisDone; // 1 bit for each axis
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] int[] BitsDirection; // KFLOP - 64 bits of I/O direction 1 = output
int BitsDirection200; // Kogna - 24 bits 200-223 of I/O direction 1 = output
int BitsDirection280; // Kogna - 10 bits 280-289 of I/O direction 1 = output
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] int[] BitsState; // KFLOP - 64 bits of state lsb=I/O bit0
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] int[] BitsState200; // Kogna - 90 bits 200-289 of state lsb=I/O bit200
int PinMuxModes; // Kogna - 10 Pin function modes 2 bits per pin 4 HRPWM + 6 SPI
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_ADCS_KOGNA)] short[] Kogna_ADC; // format 12 bits data (signed extended to 16 bits)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_DACS_KOGNA)] short[] Kogna_DAC; // format 12 bits data
byte Kogna_PWM_Prescale; // Prescale sets frequency of all 8 8-bit PWMs
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_IO_PWMS)] byte[] Kogna_PWM; // current pulse settings
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_IO_PWMS)] byte[] Kogna_PWM_Enables; // PWM Enables to control Pin?
UInt16 HRPWMPeriod01; // Kogna HRPWMs Periods
UInt16 HRPWMPeriod2;
UInt16 HRPWMPeriod3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_KOGNA_HRPWM)] UInt16[] HRPWM; // Kogna HRPWMs Pulse widths
int SnapBitsDirection0; // Snap - 32 bits of I/O direction 1=output 16-29 GPIO only, Card 0
int SnapBitsDirection1; // Snap - 32 bits of I/O direction 1=output 16-29 GPIO only, Card 1
int SnapBitsState0; // Snap - 32 bits of state 16-29 GPIO 0-7 Diff 8-15 OPTO, Card 0
int SnapBitsState1; // Snap - 32 bits of state 16-29 GPIO 0-7 Diff 8-15 OPTO, Card 1
int KanalogBitsStateInputs; // Kanalog - 16 bits 128-143
int KanalogBitsStateOutputs; // Kanalog - 24 bits 144-167
int RunOnStartUp; // word Bits 1-7 selects which threads to execute on startup
int ThreadActive; // one bit for each thread, 1=active, bit 0 - primary
int StopImmediateState; // Status of Stop Coordinated Motion Immediately
double TimeStamp; // Time in seconds (since KFlop boot) this status was aquired
[MarshalAs(UnmanagedType.ByValArray, SizeConst = N_PC_COMM_PERSIST)] int[] PC_comm;// 8 persist Variables constantly uploaded to send misc commands/data to PC
UInt32 VirtualBits; // Virtual I/O bits simulated in memory
UInt32 VirtualBitsEx0; // only upload 32 1024 Expanded Virtual Bits
}