next up previous contents index
Next: pcontrol Up: Bus systems Previous: EIB-Bus   Contents   Index


SoftPLC in C++ using rllib

PLC's are normally programmed in a ladder language. But this is because hardware PLC's don't support hight level languages. And for historical reasons normal electricians are used to think in circuit plans. But to make a SoftPLC on a full grown computer does not have this limitations. I have made a small template for showing how this could be done in C++. Only very little or no knowledge of C++ is necessary. I think this kind of programming can be done by a lot of people even if they are not familiar with C or C++.

Figure 9.17: Template for a SoftPLC 1/3
//
// SoftPLC template                                       (C) Rainer Lehrig 2003
//
//
// Attention: this program must be run as super user
//
// ladder programming is a thing for hardware PLC's
// because they lack high level programming languages
// We have a real computer and do it in C++
//

#include <stdio.h>
#include "rlsharedmemory.h"
#include "rlmailbox.h"
#include "rlmodbus.h"

// todo: define your io's here
// inputs
#define STATUS1 1
// outputs
#define LED0    0

// Note:
// It could be advisable to do the complete io in a separate file
// E.g. modbusio.cpp modbusio.h
rlSharedMemory shm("/srv/automation/shm/modbus.shm",128*sizeof(int)); // todo: specify name of shm and size
rlMailbox      mbx("/srv/automation/mbx/modbus.mbx");                 // todo: specify name of mbx

int outBit[128];  // todo: write your outputs here

Figure 9.18: Template for a SoftPLC 2/3
int bit(int val) // read bit
{ // todo: adjust to your needs, this demo reads bits
  int ret;
  unsigned char buf[2],b;

  if(val > 128) return -1;
  shm.read(val/8,buf,2);
  b = buf[0];
  switch(val%8)
  {
    case 0:
      ret = b & BIT0;
      break;
    case 1:
      ret = b & BIT1;
      break;
    case 2:
      ret = b & BIT2;
      break;
    case 3:
      ret = b & BIT3;
      break;
    case 4:
      ret = b & BIT4;
      break;
    case 5:
      ret = b & BIT5;
      break;
    case 6:
      ret = b & BIT6;
      break;
    case 7:
      ret = b & BIT7;
      break;
    default:
      return -1;
  }
  if(ret > 0) return 1;
  return 0;
}

int writeSingleCoil(int adr, int value)
{ // todo: adjust to your needs
  unsigned char buf[128];

  buf[0] = 1;                 // slave
  buf[1] = rlModbus::ForceMultipleCoils;
  buf[2] = 0; buf[3] = adr;   // coil adr
  buf[4] = 0; buf[5] = 1;     // quantity of coils
  buf[6] = 1;                 // byte count
  buf[7] = value;             // force data
  return mbx.write(buf,8);
}

int writeOutputs()
{ // todo: adjust to your needs
  int ret,adr;

  for(adr=0; adr<10; adr++)
  {
    ret = writeSingleCoil(adr,outBit[adr]);
    if(ret < 0) return ret;
  }
  return 0;
}

Figure 9.19: Template for a SoftPLC 3/3
void cycle()
{
  // todo: write your logic here
  outBit[LED0] = bit(STATUS1); // stupid example
}

int main()
{
  while(1)
  {
    rlsleep(10); // milliseconds todo: adjust cycle time
    cycle();
    if(writeOutputs() < 0) break;
  }
  return 0;
}


next up previous contents index
Next: pcontrol Up: Bus systems Previous: EIB-Bus   Contents   Index
Rainer Lehrig 2004-02-17