#include "stdafx.h"
#include "CommunicationWithPLC.h"
namespace cis
{
CommunicationWithPLC::CommunicationWithPLC()
{
mb = Modbus::getInstance();
}
CommunicationWithPLC::~CommunicationWithPLC()
{
}
bool CommunicationWithPLC::modbusConnect()
{
return mb->modbusConnect();
}
void CommunicationWithPLC::modbusClose()
{
mb->modbusClose();
}
void CommunicationWithPLC::floatToUnsignedShort(float f, unsigned short *value)
{
void *v;
v = &f;
for (int i = 0; i < 2; i++)
value[i] = *((unsigned short*)v + i);
}
void CommunicationWithPLC::unsignedCharToUnsignedShort(unsigned char c, unsigned short *value)
{
void *a;
unsigned char *b;
a = value;
b = (unsigned char*)a;
//little-endian representation
b[1] = 0;
b[0] = c;
}
float CommunicationWithPLC::unsignedShortToFloat(unsigned short *buffer)
{
void *v;
v = buffer;
return *((float*)v);
}
short CommunicationWithPLC::unsignedShortToShort(unsigned short *buffer)
{
void *v;
v = buffer;
return *((short*)v);
}
unsigned char CommunicationWithPLC::unsignedShortToUnsignedChar(unsigned short *buffer)
{
void *v;
v = buffer;
return *((unsigned char*)v);
}
bool CommunicationWithPLC::ConfigureSystem(unsigned char acquisitionMode, float startAngle, float endAngle, unsigned char speed, float targetSourceAxisDistanceA,
float targetSourceAxisDistanceB, float targetDetectorOffsetXA, float targetDetectorOffsetXB, float step)
{
unsigned short toSend[17];
unsignedCharToUnsignedShort(acquisitionMode, toSend);
floatToUnsignedShort(startAngle, toSend + 1);
floatToUnsignedShort(endAngle, toSend + 3);
unsignedCharToUnsignedShort(speed, toSend + 5);
floatToUnsignedShort(targetSourceAxisDistanceA, toSend + 7);
floatToUnsignedShort(targetSourceAxisDistanceB, toSend + 9);
floatToUnsignedShort(targetDetectorOffsetXA, toSend + 11);
floatToUnsignedShort(targetDetectorOffsetXB, toSend + 13);
floatToUnsignedShort(step, toSend + 15);
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return false;
}
mb->modbusWriteRegisters(12305, 17, toSend);
return true;
}
struct CurrentSystemStatus CommunicationWithPLC::GetCurrentSystemStatus()
{
unsigned short HoldingRegs[17];
unsigned char c1, c2;
float m_CurrentGantryAngle = 0;
float m_GantryAngleSync = 0;
unsigned short m_XrayExposureCountA = 0;
unsigned short m_XrayExposureCountB = 0;
unsigned char CurrentPLCStatus = 0;
/*
* SystemUnconfigured 0
* SystemConfigured 1
* SystemInPosition 2
* SystemImaging 3
* SystemHalt 4
*/
float m_CurrentSourceAxisDistenceA = 0;
float m_CurrentSourceAxisDistenceB = 0;
float m_CurrentDetectorOffsetXA = 0;
float m_CurrentDetectorOffsetXB = 0;
bool m_IsSystemInitialized = FALSE;
bool m_IsSystemConfigured = FALSE;
bool m_IsHVAXrayOnState = FALSE;
bool m_IsHVBXrayOnState = FALSE;
bool m_IsHVAXrayRunState = FALSE;
bool m_IsHVBXrayRunState = FALSE;
bool m_IsGantryMoving = FALSE;
bool m_IsEmergencyStop = FALSE;
bool m_IsShieldDoorClosed = FALSE;
bool m_IsMotorOverLoad = FALSE;
bool m_IsOutOfMotionRange = FALSE;
bool m_IsImagingSyncError = FALSE;
CurrentSystemStatus CSS = { m_CurrentGantryAngle, m_GantryAngleSync, m_XrayExposureCountA, m_XrayExposureCountB, CurrentPLCStatus, m_CurrentSourceAxisDistenceA,
m_CurrentSourceAxisDistenceB, m_CurrentDetectorOffsetXA, m_CurrentDetectorOffsetXB, m_IsSystemInitialized, m_IsSystemConfigured, m_IsHVAXrayOnState, m_IsHVBXrayOnState,
m_IsHVAXrayRunState, m_IsHVBXrayRunState, m_IsGantryMoving, m_IsEmergencyStop, m_IsShieldDoorClosed, m_IsMotorOverLoad, m_IsOutOfMotionRange, m_IsImagingSyncError };
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return CSS;
}
mb->modbusReadHoldingRegisters(12288, 17, HoldingRegs);
m_CurrentGantryAngle = unsignedShortToFloat(HoldingRegs);
m_GantryAngleSync = unsignedShortToFloat(HoldingRegs + 2);
m_XrayExposureCountA = unsignedShortToShort(HoldingRegs + 4);
m_XrayExposureCountB = unsignedShortToShort(HoldingRegs + 5);
CurrentPLCStatus = unsignedShortToUnsignedChar(HoldingRegs + 6);
m_CurrentSourceAxisDistenceA = unsignedShortToFloat(HoldingRegs + 8);
m_CurrentSourceAxisDistenceB = unsignedShortToFloat(HoldingRegs + 10);
m_CurrentDetectorOffsetXA = unsignedShortToFloat(HoldingRegs + 12);
m_CurrentDetectorOffsetXB = unsignedShortToFloat(HoldingRegs + 14);
//little-endian representation
c1 = (unsigned char)HoldingRegs[16];
c2 = (unsigned char)HoldingRegs[16] >> 8 ;
m_IsSystemInitialized = (c1 | 0xFE) == 0xFF;
m_IsSystemConfigured = (c1 | 0xFD) == 0xFF;
m_IsHVAXrayOnState = (c1 | 0xFB) == 0xFF;
m_IsHVBXrayOnState = (c1 | 0xF7) == 0xFF;
m_IsHVAXrayRunState = (c1 | 0xEF) == 0xFF;
m_IsHVBXrayRunState = (c1 | 0xDF) == 0xFF;
m_IsGantryMoving = (c1 | 0xBF) == 0xFF;
m_IsEmergencyStop = (c1 | 0x7F) == 0xFF;
m_IsShieldDoorClosed = (c2 | 0xFE) == 0xFF;
m_IsMotorOverLoad = (c2 | 0xFD) == 0xFF;
m_IsOutOfMotionRange = (c2 | 0xFB) == 0xFF;
m_IsImagingSyncError = (c2 | 0xF7) == 0xFF;
CSS = { m_CurrentGantryAngle, m_GantryAngleSync, m_XrayExposureCountA, m_XrayExposureCountB, CurrentPLCStatus, m_CurrentSourceAxisDistenceA,
m_CurrentSourceAxisDistenceB, m_CurrentDetectorOffsetXA, m_CurrentDetectorOffsetXB, m_IsSystemInitialized, m_IsSystemConfigured, m_IsHVAXrayOnState, m_IsHVBXrayOnState,
m_IsHVAXrayRunState, m_IsHVBXrayRunState, m_IsGantryMoving, m_IsEmergencyStop, m_IsShieldDoorClosed, m_IsMotorOverLoad, m_IsOutOfMotionRange, m_IsImagingSyncError };
return CSS;
}
bool CommunicationWithPLC::SystemConfigured()
{
unsigned short toSend[2];
unsigned char c = 1;
unsignedCharToUnsignedShort(c,toSend);
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return false;
}
mb->modbusWriteRegisters(12294, 1, toSend);
return true;
}
bool CommunicationWithPLC::SystemUnconfigured()
{
unsigned short toSend[2];
unsigned char c = 0;
unsignedCharToUnsignedShort(c, toSend);
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return false;
}
mb->modbusWriteRegisters(12294, 1, toSend);
return true;
}
bool CommunicationWithPLC::SystemInPosition()
{
unsigned short toSend[2];
unsigned char c = 2;
unsignedCharToUnsignedShort(c, toSend);
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return false;
}
mb->modbusWriteRegisters(12294, 1, toSend);
return true;
}
bool CommunicationWithPLC::SetEndAngle(float endAngle)
{
unsigned short toSend[4];
floatToUnsignedShort(endAngle, toSend);
if (!mb->getTCPStatus())
{
bool tmp;
tmp = mb->modbusConnect();
if (!tmp)
return false;
}
mb->modbusWriteRegisters(12308, 2, toSend);
}
bool CommunicationWithPLC::getTCPStatus()
{
return mb->getTCPStatus();
}
}//namespace CIS