rllib  1
Public Member Functions | Public Attributes | Static Public Attributes | List of all members
rlState Class Reference

#include <rlstate.h>

Collaboration diagram for rlState:
Collaboration graph
[legend]

Public Member Functions

 rlState ()
 
 ~rlState ()
 
int startSteps (int cycletime)
 
int runSteps (int cycletime)
 
void gotoState (void(*funcPtr)(rlState *sm))
 

Public Attributes

void * user
 
int stepCounter
 
int cycletime
 
void(* nextStep )(rlState *sm)
 
void(* lastState )(rlState *sm)
 
rlThread thread
 

Static Public Attributes

static const long MAX_STEP = 1000*1000*1000
 

Detailed Description

This class is used to implement a statemachine.
Under pvbaddon/templates/statemachine/plc you find the statemachine consisting of several threads.
The main thread will read/write a Modbus PLC.
The statemachine stm2 will handle a small demo statemachine.
The statemachine stm1 will start stm2 if the user selects this function.
The data will be stored in a shared memory.
The shared memory contains a complex datastructure (typedef struct {...} USER_DEFINED_STRUCTURE;) which can be used to exchange values between several processes.
The pvbrowser visualization server is located under pvbaddon/templates/statemachine/pvs
There we use a SVG graphic (stm2.svg) showing the statemachine.
This graphic is generated by graphviz from stm2.dot
pvs and plc exchange data only via shared memory.
Please start both (plc and pvs) in a separate terminal and then start the pvbrowser client
Here is some sourcecode from the template:
// ***************************************************************************
//                          main.cpp  -  description
//                             ----------------—
//  begin            : Sa. Mai 4 09:29:07 2013
//  generated by     : pvdevelop (C) Lehrig Software Engineering
//  email            : lehri.nosp@m.g@t-.nosp@m.onlin.nosp@m.e.de
// ***************************************************************************
#include "plcapp.h"
SHM_DATA      *shm_data;
rlSharedMemory shm("/srv/automation/shm/plc.shm", sizeof(SHM_DATA));
rlSerial       tty;
rlModbus       mb;
rlMutex        mb_mutex;
rlState        sm1, sm2;
//// helper functions
int printBinByte(unsigned char val)
{
  if(val & BIT7) printf("1");
  else           printf("0");
  if(val & BIT6) printf("1");
  else           printf("0");
  if(val & BIT5) printf("1");
  else           printf("0");
  if(val & BIT4) printf("1");
  else           printf("0");
  printf(":");
  if(val & BIT3) printf("1");
  else           printf("0");
  if(val & BIT2) printf("1");
  else           printf("0");
  if(val & BIT1) printf("1");
  else           printf("0");
  if(val & BIT0) printf("1");
  else           printf("0");
  return 0;
}
int printBin(unsigned char *data)
{
  printf("BinData: ");
  printBinByte(data[0]);
  printf(" - ");
  printBinByte(data[1]);
  return 0;
}
//// Schneider PLC: first 4 bits are outputs then 6 bits input follow
static int readIO() 
{
  unsigned char data[256];
  int ret;
  MB_readInputStatus(1,0,10,data);          // read all IO values from modbus
  shm_data->plc.in.in1 = mb.data2int(data); // store data in shared memory
  if(trace)
  {
    printf("readIO:: ret=%d ", ret); 
    printBin(data);
    printf(" in1=%x\n", shm_data->plc.in.in1);
  }  

return 0; }
static int writeIO()
{
  unsigned char coils[8];
  int ret;
  coils[0] = shm_data->plc.out.out1 & 0x0ff;
  MB_forceMultipleCoils(1,0,4,coils);       // write the 4 output bits to modbus
  return 0;
}
int main()
{
  if(trace) printf("plc starting ...\n");
  if(trace) printf("shm.status=%d\n", shm.status);
  if(shm.status != rlSharedMemory::OK)
  {
    printf("ERROR: shared memory status is not ok\n");
    return -1;
  }
  shm_data = (SHM_DATA *) shm.getUserAdr();
  memset(shm_data,0,sizeof(SHM_DATA));
  if(tty.openDevice("/dev/ttyUSB0",B9600,1,1,8,1,rlSerial::NONE) < 0)
  {
    printf("ERROR: openDevice(\"/dev/tty/USB0")
"); } mb.registerSerial(&tty);
  startStepsStm1(&sm1, 100); // start statemachine 1
  startStepsStm2(&sm2, 100); // start statemachine 2
  printf("going to IO loop\n");
  while(1)
  {
    readIO();
    writeIO();
    rlsleep(10);
  }
  return 0;
}
// *****************************************************************************
//                          stm2.cpp  -  description
//                             ----------------—
//  begin            : Sa. Mai 4 09:29:07 2013
//  generated by     : pvdevelop (C) Lehrig Software Engineering
//  email            : lehri.nosp@m.g@t-.nosp@m.onlin.nosp@m.e.de
//                     A simple template for implementing your own statemachine
//                     See: pvbaddon/templates/statemachine
// *****************************************************************************
#include "plcapp.h"
////TODO: define our states
////      Your states are defined by static functions which get a pointer to the statemachine
////      The pointer sm->user might be used to transfer the address of a user defined datastructure
////      A transition from one state to the next is done by sm->gotoState(theNextState);
////      Your statemachine runs within a separate thread and the current state is called within "cycletime" intervals
static void stStart(rlState *sm);
static void stProcess(rlState *sm);
static void stFinish(rlState *sm);
////TODO: implement our states
static void stStart(rlState *sm)
{
  shm_data->plc.out.out1 = 1;                        // set output 1 in shared memory
  if(sm->stepCounter > 20) 
  {
    shm_data->plc.out.out1 = 2;                      // reset output 1 in shared memory
    strcpy(shm_data->plc.state.stm2_name,"Process"); // set next state name in shared memory 
    sm->gotoState(stProcess);                        // goto the next state
  }  

}
static void stProcess(rlState *sm)
{
  shm_data->plc.out.out1 = sm->stepCounter;          // set output 1 in shared memory
  if(sm->stepCounter > 30) 
  {
    strcpy(shm_data->plc.state.stm2_name,"Finish");  // set next state name in shared memory
    sm->gotoState(stFinish);                         // goto the next state
  }  

}
static void stFinish(rlState *sm)
{
  shm_data->plc.out.out1 = 1;                        // set output 1 in shared memory
  if(sm->stepCounter > 30) 
  {
    shm_data->plc.out.out1 = 0;                      // reset output 1 in shared memory
    strcpy(shm_data->plc.state.stm2_name,"NULL");    // set next state name NULL
    shm_data->plc.state.stm2_running = 0;            // reset running in shared memory 
    sm->gotoState(NULL);                             // goto NULL state
  }  

}
int startStepsStm2(rlState *sm, int cycletime)       // start our statemachine
{
  if(trace) printf("stm2 starting\n");
  shm_data->plc.state.stm2_running = 1;              // set running in shared memory
  strcpy(shm_data->plc.state.stm2_name,"Start");     // set next state name in shared memory
  sm->gotoState(stStart);                            // goto nextState
  sm->startSteps(cycletime);                         // start a thread which handles the statemachine
  return 0;
}
// ***************************************************************************
//                          stm1.cpp  -  description
//                             ----------------—
//  begin            : Sa. Mai 4 09:29:07 2013
//  generated by     : pvdevelop (C) Lehrig Software Engineering
//  email            : lehri.nosp@m.g@t-.nosp@m.onlin.nosp@m.e.de
// ***************************************************************************
#include "plcapp.h"
extern rlState sm2;
////TODO: define our states
static void stStart(rlState *sm);
////TODO: implement our states
static void stStart(rlState *sm)
{
  shm_data->plc.out.out2 = sm->stepCounter;
  if(shm_data->plc.state.stm2_running == 0)
  {
    if(shm_data->pvs.state.button_start_stm2 == 1)
    {
      startStepsStm2(&sm2, 100);               // start statemachine 2 thread
    }
    else if(shm_data->plc.in.in1 & BIT1)
    {
      startStepsStm2(&sm2, 100);               // start statemachine 2 thread
    }
  }  

}
int startStepsStm1(rlState *sm, int cycletime) // start our statemachine
{
  if(trace) printf("Start stm1\n");
  shm_data->plc.state.stm1_running = 1;        // set running within shared memory
  sm->gotoState(stStart);                      // goto nextState
  sm->startSteps(cycletime);                   // start a thread that will handle our statemachine
  return 0;
}
 

Definition at line 256 of file rlstate.h.

Constructor & Destructor Documentation

◆ rlState()

rlState::rlState ( )

Definition at line 18 of file rlstate.cpp.

19 {
20  user = NULL;
21  stepCounter = -1;
22  cycletime = 1000;
23  nextStep = NULL;
24  lastState = NULL;
25 }
void * user
Definition: rlstate.h:264
int cycletime
Definition: rlstate.h:266
void(* lastState)(rlState *sm)
Definition: rlstate.h:269
int stepCounter
Definition: rlstate.h:265
void(* nextStep)(rlState *sm)
Definition: rlstate.h:268

◆ ~rlState()

rlState::~rlState ( )

Definition at line 27 of file rlstate.cpp.

28 {
29 }

Member Function Documentation

◆ gotoState()

void rlState::gotoState ( void(*)(rlState *sm)  funcPtr)

Definition at line 31 of file rlstate.cpp.

32 {
33  stepCounter = -1;
35  nextStep = funcPtr;
36 }
void(* lastState)(rlState *sm)
Definition: rlstate.h:269
int stepCounter
Definition: rlstate.h:265
void(* nextStep)(rlState *sm)
Definition: rlstate.h:268

◆ runSteps()

int rlState::runSteps ( int  cycletime)

Definition at line 38 of file rlstate.cpp.

39 {
40  cycletime = _cycletime;
41  lastState = NULL;;
42  stepCounter = 0;
43 
44  while(nextStep != NULL)
45  {
46  (*nextStep)(this);
48  stepCounter++;
50  }
51 
52  return 0;
53 }
int cycletime
Definition: rlstate.h:266
void(* lastState)(rlState *sm)
Definition: rlstate.h:269
void rlsleep(long msec)
Definition: rlwthread.cpp:396
int stepCounter
Definition: rlstate.h:265
static const long MAX_STEP
Definition: rlstate.h:267
void(* nextStep)(rlState *sm)
Definition: rlstate.h:268

◆ startSteps()

int rlState::startSteps ( int  cycletime)

Definition at line 64 of file rlstate.cpp.

65 {
66  if(cycletime < 0) return 0;
67  cycletime = _cycletime;
69  return 0;
70 }
int create(void *(*func)(void *), void *argument)
Definition: rlthread.cpp:35
int cycletime
Definition: rlstate.h:266
rlThread thread
Definition: rlstate.h:270
static void * stepsThread(void *arg)
Definition: rlstate.cpp:55

Member Data Documentation

◆ cycletime

int rlState::cycletime

Definition at line 266 of file rlstate.h.

◆ lastState

void(* rlState::lastState) (rlState *sm)

Definition at line 269 of file rlstate.h.

◆ MAX_STEP

const long rlState::MAX_STEP = 1000*1000*1000
static

Definition at line 267 of file rlstate.h.

◆ nextStep

void(* rlState::nextStep) (rlState *sm)

Definition at line 268 of file rlstate.h.

◆ stepCounter

int rlState::stepCounter

Definition at line 265 of file rlstate.h.

◆ thread

rlThread rlState::thread

Definition at line 270 of file rlstate.h.

◆ user

void* rlState::user

Definition at line 264 of file rlstate.h.


The documentation for this class was generated from the following files: