thiagoralves Show full post »
thiagoralves
Not yet, but it will be possible shortly. Check back here for more updates
Quote 0 0
rodrigo_rolle
Hello, Thiago!
OpenPLC v3 looks amazing, congratulations!
Let me ask you a quick question... I developed a hardware layer for running both Simulink and ESP8266 at the same time. I took a look at the v3 hardware layer folder and I noticed that these codes weren't changed, so I assume that I can reuse my code too, is it correct? If yes, how can I make my hardware layer appear on the hardware layer list?

Thank you!
Quote 0 0
thiagoralves
To have your hardware layer appear on the list is a bit complicated because it involves changing many files. Before you try to do that, I have a few options:
  1. Try to use the original Simulink layer and augment it with the esp code you need by using the hardware layer code box. The code that goes inside that box is executed alongside the selected driver. If you can manage to insert your logic in there, it would be the preferred solution.
  2. Replace one of the hardware layer files with your file, then you don't have to change anything. For example, you can replace the simulink.cpp file inside the /webserver/core/hardware_layers folder. Then, every time you select the Simulink layer on the hardware tab it will load your driver.
In any case, if you want to use your hardware layer from v2 you still need to make a small modification to it. You just need to check if the I/O you're working on is listed in one of the ignored vectors of the hardware layer code box. This little snippet from the simulink.cpp layer will show you exactly what I mean:

pthread_mutex_lock(&bufferLock); //lock mutex
for (int i = 0; i < ANALOG_BUF_SIZE; i++)
{
    if (pinNotPresent(ignored_int_inputs, i))
        if (int_input[i] != NULL) *int_input[i] = plc_data->analogIn[i];
    if (pinNotPresent(ignored_int_outputs, i))
        if (int_output[i] != NULL) plc_data->analogOut[i] = *int_output[i];
}
for (int i = 0; i < DIGITAL_BUF_SIZE; i++)
{
    if (pinNotPresent(ignored_bool_inputs, i))
        if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = plc_data->digitalIn[i];
        
    if (pinNotPresent(ignored_bool_outputs, i))
        if (bool_output[i/8][i%8] != NULL) plc_data->digitalOut[i] = *bool_output[i/8][i%8];
}
pthread_mutex_unlock(&bufferLock); //unlock mutex


If you still want to make your own hardware layer to appear on the list, you will need to modify the following files:
  • webserver/ webserver.py line 778: This piece of code draws the HTML portion of the interface. To make an additional entry on that popup, you will have to add it on this code.
  • webserver/scripts/change_hardware_layer.sh: This is an automated script that makes the necessary changes to load a different driver. You will have to create a new entry on this file with the required code to load your driver.
Just keep in mind that the script to change the current hardware layer also modifies two other files (openplc_platform and openplc_driver). Those files are important for OpenPLC to know what is the current loaded driver and on which platform it is supposed to run. The name you will write on the openplc_driver file must be the same name you used on the if/else comparison from webserver.py and also the same name under quotes on the value="" field. 
Quote 1 0
Stensig
Hi

How much space does the runtime require?
Im running a rpi with 8 gb sd card and noobs/raspbian installed which can’t succeed installing the runtime. When looking in the file explorer it seems that no free space is left after trying to install. 
It was not a problem running OpenPLC runtime v2.
Quote 0 0
thiagoralves
You need around 1.5GB free before installing OpenPLC v3. The reason for that is because, to avoid problems compiling the OpenDNP3 library, OpenPLC installer creates a 1GB temporary swap file. This was needed because I saw some platforms with little RAM failing while trying to compile the library. The swap file allows it to succeed to the cost of using the disk as RAM (file page). Once OpenPLC finishes installing, the swap file is disabled and removed.

You can manually disable the creation of the 1GB swap file by editing the ./ install.sh script. Just comment out lines 221, 222, and 223 (creation of the swap file) and then lines 234 and 235 (removal of the swap file)
Quote 0 0
kdkirmse
Don't see a good place to put a bug report.

loop will only test first element

OpenPLC_v3/webserver/core/main.cpp

bool pinNotPresent(int *ignored_vector, int pinNumber)

for (int i = 0; i < (sizeof(ignored_vector)/sizeof(ignored_vector[0])); i++)


Quote 0 0
thiagoralves
kdkirmse wrote:
Don't see a good place to put a bug report.

loop will only test first element

OpenPLC_v3/webserver/core/main.cpp

bool pinNotPresent(int *ignored_vector, int pinNumber)

for (int i = 0; i < (sizeof(ignored_vector)/sizeof(ignored_vector[0])); i++)



I didn't get it. It looks to me that this loop will scan through the entire *ignored_vector array. What is the problem?
Quote 0 0
kdkirmse
sizeof(ignored_vector) == sizeof(int*), not the size of the array

for the raspberry pi the ignored vector is terminated by a -1

In my code I changed the loop to

for (int i = 0; ignored_vector[i] >= 0; i++)

Quote 0 0
thiagoralves

#include <stdio.h>
int main()
{
    int a[17];
    printf("Size of the array in bytes: %d\n", sizeof(a));
    printf("Number of elements on array: %d\n", sizeof(a)/sizeof(a[0]));
}

Compile and execute it:

g++ test.cpp -o test
./test
Size of the array in bytes: 68
Number of elements on array: 17

The array is not terminated by -1. By default all ignored vector arrays have -1 to indicate that no pin is ignored. Once you want a pin to be listed on the ignored vectors, you replace -1 by the pins you want. Therefore, those arrays can take different dimensions depending on the code written by the user at the hardware code box
Quote 0 0
kdkirmse
#include <stdio.h>
int main()
{
int a[17];
int *b = a;
printf("Size of the array in bytes: %d\n", sizeof(a));
printf("Size of the pointer in bytes: %d\n", sizeof(b));
printf("Number of elements on array: %d\n", sizeof(a)/sizeof(a[0]));
}

Size of the array in bytes: 68
Size of the pointer in bytes: 4
Number of elements on array: 17

bool pinNotPresent(int *ignored_vector, int pinNumber)

ignored_vector is a pointer to the first element of the array

The C interface does not push the size of the array onto the stack

sizeof() is a compile time operator
Quote 0 0
thiagoralves
You're right! I've just fixed it:  https://github.com/thiagoralves/OpenPLC_v3/commit/ef4e5a310a2ea187d93b6b436d71f309fad18a23
Quote 0 0
thiagoralves
Ops, it seems that I have just broke it. Sizeof can’t get the size of the array of it is not declared in the same file... I’ll try to fix that soon and push it back to git.
Quote 0 0
thiagoralves
It's all fixed now!
Quote 0 0
Stensig
You need around 1.5GB free before installing OpenPLC v3. The reason for that is because, to avoid problems compiling the OpenDNP3 library, OpenPLC installer creates a 1GB temporary swap file. This was needed because I saw some platforms with little RAM failing while trying to compile the library. The swap file allows it to succeed to the cost of using the disk as RAM (file page). Once OpenPLC finishes installing, the swap file is disabled and removed.

You can manually disable the creation of the 1GB swap file by editing the ./ install.sh script. Just comment out lines 221, 222, and 223 (creation of the swap file) and then lines 234 and 235 (removal of the swap file)


By removing one of the preinstalled programs included in "NOOBS" I was able to get 1,6 GB of free space on the SD-card on the RPI. This fixed the problem.
Thanks for helping out...
Quote 0 0
rodrigo_rolle

 * Debug mode: off
Traceback (most recent call last):
  File "webserver.py", line 1295, in <module>
    app.run(debug=False, host='0.0.0.0', threaded=True, port=8080)
  File "/usr/lib/python2.7/site-packages/flask/app.py", line 943, in run
    run_simple(host, port, self, **options)
  File "/usr/lib/python2.7/site-packages/werkzeug/serving.py", line 814, in run_simple
    inner()
  File "/usr/lib/python2.7/site-packages/werkzeug/serving.py", line 774, in inner
    fd=fd)
  File "/usr/lib/python2.7/site-packages/werkzeug/serving.py", line 660, in make_server
    passthrough_errors, ssl_context, fd=fd)
  File "/usr/lib/python2.7/site-packages/werkzeug/serving.py", line 577, in __init__
    self.address_family), handler)
  File "/usr/lib/python2.7/SocketServer.py", line 417, in __init__
    self.server_bind()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 108, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib/python2.7/SocketServer.py", line 431, in server_bind
    self.socket.bind(self.server_address)
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 112] Address already in use



Still struggling with this error on Cygwin64 (Windows 7, 64-bit processor). I also tried the Windows installer, the installation runs as usual but the application closes just after it starts, before I can get a screenshot. I tried the rebase procedure but the problem persists.
Quote 0 0