First steps in C/C++

Programming the RevPi in C/C++

In the previous article, I set up the development environment and wrote the first small C program for the RevPi. But I could have executed the program on any computer.

In this article, I show how to access the process image of the RevPi via C++. For this, I use the files from the piTest demo program. The files piControlIf.hpp, piControlIf.cpp and piControl.h are required.

Probably, the most minimalist light show in the world

First I created a new program, of course again with RevPi as the build host. I named it RevPiTestOutput and added the three files from the piTest demo (piControlIf.hpp, piControlIf.cpp, piControl.h).

Now comes the moment when you have to take a closer look at the philosophy of RevPi. The RevPi is designed as a modular system. Accordingly, it is not known from the beginning which inputs and outputs are actually present. Furthermore, the RevPi is intended for industrial applications. Therefore, all inputs and outputs are transferred collectively in a so-called process image.

RevPi Connect already has an input, a relay output, and several LEDs on board, that can be freely switched by the user. So I do not have to deal with the configuration of the expansion modules yet.

In the first sample project RevPiTestOutput I use LED A1 to demonstrate how to access an output. To use the C++ version of the library, you must first include piControlIf.hpp in your program. Now, you need an instance of piControl, which I called piC. Then a structure of type SPIVariable has to be filled with the symbolic identifier of the output. The symbolic identifier for the LEDs on the RevPi is RevPiLED. This is then passed to piControl::GetVariableInfo. All in all, this looks like the following:

piControl piC;
SPIVariable spiVariableOut = {"RevPiLED", 0, 0, 0};

piC->GetVariableInfo(&spiVariableOut);

Now SPIVariable::i16uAddress contains the address of the LEDs in the process image. RevPiLED is one byte. The LEDs are represented by individual bits within the byte. The green LED A1 is on bit 0. You find the assignment of the LEDs in our tutorial Statusbytes RevPi Connect. To switch the LED, a structure SPIValue must be filled with the address and the data:

SPIValue spiValue = {0, 0, 0};
spiValue.i16uAddress = spiVariableOut.i16uAddress;
spiValue.i8uBit = 0;
spiValue.i8uValue = 1;

piC.SetBitValue(&spiValue);

In my sample program, I switch the LED on and off every second. The whole thing 10 times with a for loop. The entire relevant code will look like this:

piControl piC;
SPIVariable spiVariableOut = {"RevPiLED", 0, 0, 0};
    
piC.GetVariableInfo(&spiVariableOut);

SPIValue spiValue = {0, 0, 0};
spiValue.i16uAddress = spiVariableOut.i16uAddress;
spiValue.i8uBit = 0;
spiValue.i8uValue = 1;
    
for (int i = 0; i < 10; i++) {
    spiValue.i8uValue = spiValue.i8uValue^0x01;
    piC.SetBitValue(&spiValue);
    sleep(1);
}

The first time I ran the program I got an error because the compiler could not find “piControl.h” in “piControlIf.hpp”. If you replace the angle brackets in #include <piControl.h> with quotation marks, so #include “piControl.h” it works. I suppose the files were originally located in different directories at the developer colleagues. In piTest the C++ version is not used at all. Therefore the error was not noticed.

Reading an input

Reading an input works basically the same way as writing an output. First, the position in the process image must be determined. With GetBitValue(&spiValue) the corresponding position in the process image can then be read.

In the sample program RevPiTestInput I want to read the input IN of the RevPi Connect and display it on the console. The input IN is confusingly located at RevPiStatus and there in bit 6 (see Statusbytes RevPi Connect). Altogether the program looks as follows:

piControl piC;

SPIVariable spiVariableOut = {"RevPiStatus", 0, 0, 0};

piC.GetVariableInfo(&spiVariableOut);

SPIValue spiValue = {0, 0, 0};
spiValue.i16uAddress = spiVariableOut.i16uAddress;
spiValue.i8uBit = 6;
spiValue.i8uValue = 0;

piC.GetBitValue(&spiValue);
printf("IN: %i\n",(int)spiValue.i8uValue);

If the input is at 0V, the corresponding bit is false, so the output is 0 (zero). If the input is at 24V, a 1 is displayed. If the input is open, i.e. neither 0V nor 24V, the bit is also false. For testing, I simply plugged a cable into IN and connected it to the 0V or 24V terminal on the bottom of the Connect.

Picture of my RevPi setup with cable connected to input IN

If the input is at 0V or open, the output in SSH looks like this:SSH console showing the output of revpitestinput

A Symlink for the Path

As described in the last article, Netbeans places the programs in a somewhat bulky path. I made your work a bit easier by symlinking to the appropriate directory. You can do this with ln -s <path> <identifier>. For example, I have set a symlink in the home directory, called netbeansprojects.

ln -s ~/.netbeans/remote/<IP address RevPi>/<PC name>/<Path on 
PC>/NetBeansProjects netbeansprojects

The symlink can be used like a normal directory. The home directory looks like this:SSH console with output of comand "ls -l" after creating new symlink netbeansprojects