Click here to show toolbars of the Web Online Help System: show toolbars
 

/******************************************************************************/
/*
* File name: McomModbusSlave.cpp
* Location: See Matrox Example Launcher in the MIL Control Center
 * 
*
* Synopsis:  This program allocates a MIL application and system.
*            Then allocate a MIL industrial communication context to an
*            Modbus slave instance.
*
* Notes:     This example is only available if you have the MIL Industrial Communication package,
*            or another relevant update installed.
*
* Copyright (C) Matrox Electronic Systems Ltd., 1992-2016.
* All Rights Reserved
*/
#include <mil.h>

MIL_ID MilApplication,  /* Application identifier.  */
MilSystem,              /* System identifier.       */
MilCom;                 /* Industrial communication identifier. */

/* Status register */
MIL_UINT8 TriggerACK;
MIL_UINT8 ResultReady;
MIL_UINT8 ResultValue;

/* Control register */
MIL_UINT8 Trigger;
MIL_UINT8 ResultACK;
MIL_UINT8 ResultCopy;

MIL_UINT8 value = 0;

void WriteStatus(MIL_UINT8 triggerACK, MIL_UINT8 resultReady, MIL_UINT8 resultValue);
void ReadControl(void);
void SetInitialData(void);
void WaitForTriggerFromPLC(void);
MIL_UINT8 DoProcessing(void);
void WriteResultToPLC(MIL_UINT8 result);

int MosMain(void)
{
   MIL_UINT8 processingResult;

   /* Allocate a default MIL application, system, display and image. */
   MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);

   McomAlloc(MilSystem, M_COM_PROTOCOL_MODBUS, MIL_TEXT(""), M_DEFAULT, M_DEFAULT, &MilCom);

   /* Set the data to the initial values. */
   SetInitialData();
   /* Wait for a key press. */
   MosPrintf(MIL_TEXT("Press <Enter> to end.\n"));
   while (!MosKbhit())
   {
      /* Wait that the PLC set the trigger bit */
      WaitForTriggerFromPLC();

      /* Do the requested processing */
      processingResult = DoProcessing();

      /* Write the result back to the PLC*/
      WriteResultToPLC(processingResult);
   }

   /* Free MIL objects*/
   McomFree(MilCom);
   MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
   return 0;
}

void WriteStatus(MIL_UINT8 triggerACK, MIL_UINT8 resultReady, MIL_UINT8 resultValue)
{
   MIL_UINT8 status[2];

   TriggerACK = triggerACK;
   ResultReady = resultReady;
   ResultValue = resultValue;
   status[0] = ((ResultReady & 0x01) << 1) | (TriggerACK & 0x01);
   status[1] = ResultValue;

   /* Write in the input module slot id 1 as specified in PLC configuration */
   McomWrite(MilCom, M_INPUT_REGISTER, 0, sizeof(status) / sizeof(MIL_UINT16), status);
}

void ReadControl(void)
{
   MIL_UINT8 control[2];

   /* Read in the output module slot id 2 as specified in PLC configuration */
   McomRead(MilCom, M_HOLDING_REGISTER, 0, sizeof(control) / sizeof(MIL_UINT16), control);

   Trigger = control[0] & 0x1;
   ResultACK = (control[0] & 0x2) >> 1;
   ResultCopy = control[1];
}

void SetInitialData(void)
{
   WriteStatus(0, 0, 0);
}

void WaitForTriggerFromPLC(void)
{
   do
   {
      /* Wait for the trigger from the PLC */
      ReadControl();
      MosSleep(10);
   } while (Trigger == 0 && !MosKbhit());

   MosPrintf(MIL_TEXT("Received Trigger!\n"));

   /* Set the TriggerACK and reset ResultReady */
   WriteStatus(1, 0, 0);
}

MIL_UINT8 DoProcessing(void)
{
   /* Do what need to be done when PLC send the trigger. */
   value++;
   return value;
}

void WriteResultToPLC(MIL_UINT8 result)
{
   /* Set the result value */
   WriteStatus(0, 1, result);

   /* Wait that the PLC acknowledge the result */
   do
   {
      ReadControl();
      MosSleep(10);
   } while (ResultACK == 0 && !MosKbhit());

   MosPrintf(MIL_TEXT("Received result ACK! Value:%d Copy:%d\n"), value, ResultCopy);

   /* Set the result value */
   WriteStatus(TriggerACK, 0, ResultValue);
}