Thanks for the suggestion on updating the SDK to include that functionality. In case anyone else is interested, these are the modifications I made to the SDK to support this.
In O22SIOUT.h added the following definitions
#define SIOMM4096_POINT_CONFIG_UNIT_SIZE 0x00000010
#define SIOMM4096_POINT_CONFIG_UNIT_SIZE_NO_NULL 0x0000000F
In O22STRCT.h added the following struct
typedef struct SIOMM_PointConfigArea5 {
int nModuleType; ///< Read only.
int nPointType; ///< Read/Write
int nFeature; ///< Read/Write. Only used for digital points
float fOffset; ///< Read/Write. Only used for analog points
float fGain; ///< Read/Write. Only used for analog points
float fHiScale; ///< Read/Write. Only used for analog points
float fLoScale; ///< Read/Write. Only used for analog points
float fFilterWeight; ///< Read/Write. Only used for analog points
float fWatchdogValue; ///< Read/Write
int nWatchdogEnabled; ///< Read/Write
unsigned char byName[51]; ///< Read/Write
unsigned char byUnits[10]; ///< Read/Write
} O22_SIOMM_PointConfigArea5;
In O22SIOMM.h added the following function definitions
int SetPointConfigurationEx5(int nModule, int nPoint, SIOMM_PointConfigArea5 PtConfigData);
int GetPointConfigurationEx5(int nModule, int nPoint, SIOMM_PointConfigArea5 *pData);
And finally in O22SIOMM.cpp implemented the functions
int O22SnapIoMemMap::SetPointConfigurationEx5(int nModule, int nPoint, SIOMM_PointConfigArea5 PtConfigData)
//-------------------------------------------------------------------------------------------------
// Configure a digital or analog point
//-------------------------------------------------------------------------------------------------
{
check(nModule >= 0 && nModule < SIOMM4096_MAX_MODULES, SIOMM_ERROR);
check(nPoint >= 0 && nPoint < SIOMM4096_MAX_POINTS, SIOMM_ERROR);
int nResult;
uint8_t arrbyData[SIOMM4096_POINT_CONFIG_BOUNDARY]; // buffer for the data to be written
memset(arrbyData, 0, SIOMM4096_POINT_CONFIG_BOUNDARY);
// Build the data area
O22FILL_ARRAY_FROM_INT32(arrbyData, 0, PtConfigData.nPointType);
O22FILL_ARRAY_FROM_INT32(arrbyData, 4, PtConfigData.nFeature);
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 8, PtConfigData.fOffset);
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 12, PtConfigData.fGain);
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 16, PtConfigData.fHiScale);
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 20, PtConfigData.fLoScale);
// Bytes 24-27 are not used at this time.
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 28, PtConfigData.fFilterWeight);
O22FILL_ARRAY_FROM_FLOAT(arrbyData, 32, PtConfigData.fWatchdogValue);
O22FILL_ARRAY_FROM_INT32(arrbyData, 36, PtConfigData.nWatchdogEnabled);
memcpy(arrbyData + 44, PtConfigData.byName, SIOMM4096_POINT_CONFIG_NAME_SIZE_NO_NULL);
memcpy(arrbyData + 116, PtConfigData.byUnits, SIOMM4096_POINT_CONFIG_UNIT_SIZE_NO_NULL);
int nPointOffset = nModule * 64 + nPoint;
// Write the first section
nResult = WriteBlock(SIOMM4096_POINT_CONFIG_WRITE_TYPE_BASE +
(SIOMM4096_POINT_CONFIG_BOUNDARY * nPointOffset),
24, (uint8_t*)arrbyData);
// Check for error
if (SIOMM_OK != nResult)
return nResult;
// Write the second section
nResult = WriteBlock(SIOMM4096_POINT_CONFIG_WRITE_TYPE_BASE + 28 +
(SIOMM4096_POINT_CONFIG_BOUNDARY * nPointOffset),
12, (uint8_t*)(&(arrbyData[28])));
// Check for error
if (SIOMM_OK != nResult)
return nResult;
// Write the third section
nResult = WriteBlock(SIOMM4096_POINT_CONFIG_WRITE_TYPE_BASE + 44 +
(SIOMM4096_POINT_CONFIG_BOUNDARY * nPointOffset),
SIOMM4096_POINT_CONFIG_NAME_SIZE_NO_NULL, (uint8_t*)(&(arrbyData[44])));
// Check for error
if (SIOMM_OK != nResult)
return nResult;
// Write the fourth section (unit)
return WriteBlock(SIOMM4096_POINT_CONFIG_WRITE_TYPE_BASE + 116 +
(SIOMM4096_POINT_CONFIG_BOUNDARY * nPointOffset),
SIOMM4096_POINT_CONFIG_UNIT_SIZE_NO_NULL, (uint8_t*)(&(arrbyData[116])));}
int O22SnapIoMemMap::GetPointConfigurationEx5(int nModule, int nPoint, SIOMM_PointConfigArea5 pPtConfigData)
//-------------------------------------------------------------------------------------------------
// Get the configuration for a point
//-------------------------------------------------------------------------------------------------
{
check(nModule >= 0 && nModule < SIOMM4096_MAX_MODULES, SIOMM_ERROR);
check(nPoint >= 0 && nPoint < SIOMM4096_MAX_POINTS, SIOMM_ERROR);
check(pPtConfigData != NULL, SIOMM_ERROR);
int nResult;
uint8_t arrbyData[SIOMM4096_POINT_CONFIG_BOUNDARY]; // buffer for the data to be read
memset(arrbyData, 0, SIOMM4096_POINT_CONFIG_BOUNDARY);
// Read the data
nResult = ReadBlock(SIOMM4096_POINT_CONFIG_READ_MOD_TYPE_BASE +
(SIOMM4096_POINT_CONFIG_BOUNDARY * (nModule * 64 + nPoint)),
SIOMM4096_POINT_CONFIG_BOUNDARY, (uint8_t)arrbyData);
// Check for error
if (SIOMM_OK == nResult)
{
// If everything is okay, go ahead and fill the structure
pPtConfigData->nModuleType = O22MAKELONG2(arrbyData, 0);
pPtConfigData->nPointType = O22MAKELONG2(arrbyData, 4);
pPtConfigData->nFeature = O22MAKELONG2(arrbyData, 8);
pPtConfigData->fOffset = O22MAKEFLOAT2(arrbyData, 12);
pPtConfigData->fGain = O22MAKEFLOAT2(arrbyData, 16);
pPtConfigData->fHiScale = O22MAKEFLOAT2(arrbyData, 20);
pPtConfigData->fLoScale = O22MAKEFLOAT2(arrbyData, 24);
// Bytes 28-31 are not used at this time
pPtConfigData->fFilterWeight = O22MAKEFLOAT2(arrbyData, 32);
pPtConfigData->fWatchdogValue = O22MAKEFLOAT2(arrbyData, 36);
pPtConfigData->nWatchdogEnabled = O22MAKELONG2(arrbyData, 40);
memcpy(pPtConfigData->byName, arrbyData + 48, SIOMM4096_POINT_CONFIG_NAME_SIZE);
memcpy(pPtConfigData->byUnits, arrbyData + 120, SIOMM4096_POINT_CONFIG_UNIT_SIZE);
}
return nResult;}
Have only done light testing, but was able to verify setting and getting the units using those functions.