Code cleanup; Added release version to login screen

This commit is contained in:
Autonomy Server
2024-10-15 17:43:20 -04:00
parent a523b4928e
commit ea789c51db
18 changed files with 424 additions and 539 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -1,64 +0,0 @@
//-----------------------------------------------------------------------------
// DISCLAIMER: EDDITING THIS FILE CAN BREAK YOUR OPENPLC RUNTIME! IF YOU DON'T
// KNOW WHAT YOU'RE DOING, JUST DON'T DO IT. EDIT AT YOUR OWN RISK.
//
// PS: You can always restore original functionality if you broke something
// in here by clicking on the "Restore Original Code" button above.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// These are the ignored I/O vectors. If you want to override how OpenPLC
// handles a particular input or output, you must put them in the ignored
// vectors. For example, if you want to override %IX0.5, %IX0.6 and %IW3
// your vectors must be:
// int ignored_bool_inputs[] = {5, 6}; //%IX0.5 and %IX0.6 ignored
// int ignored_int_inputs[] = {3}; //%IW3 ignored
//
// Every I/O on the ignored vectors will be skipped by OpenPLC hardware layer
//-----------------------------------------------------------------------------
int ignored_bool_inputs[] = {-1};
int ignored_bool_outputs[] = {-1};
int ignored_int_inputs[] = {-1};
int ignored_int_outputs[] = {-1};
//-----------------------------------------------------------------------------
// This function is called by the main OpenPLC routine when it is initializing.
// Hardware initialization procedures for your custom layer should be here.
//-----------------------------------------------------------------------------
void initCustomLayer()
{
}
//-----------------------------------------------------------------------------
// This function is called by OpenPLC in a loop. Here the internal input
// buffers must be updated with the values you want. Make sure to use the mutex
// bufferLock to protect access to the buffers on a threaded environment.
//-----------------------------------------------------------------------------
void updateCustomIn()
{
// Example Code - Overwritting %IW3 with a fixed value
// If you want to have %IW3 constantly reading a fixed value (for example, 53)
// you must add %IW3 to the ignored vectors above, and then just insert this
// single line of code in this function:
// if (int_input[3] != NULL) *int_input[3] = 53;
}
//-----------------------------------------------------------------------------
// This function is called by OpenPLC in a loop. Here the internal output
// buffers must be updated with the values you want. Make sure to use the mutex
// bufferLock to protect access to the buffers on a threaded environment.
//-----------------------------------------------------------------------------
void updateCustomOut()
{
// Example Code - Sending %QW5 value over I2C
// If you want to have %QW5 output to be sent over I2C instead of the
// traditional output for your board, all you have to do is, first add
// %QW5 to the ignored vectors, and then define a send_over_i2c()
// function for your platform. Finally you can call send_over_i2c() to
// send your %QW5 value, like this:
// if (int_output[5] != NULL) send_over_i2c(*int_output[5]);
//
// Important observation: If your I2C pins are used by OpenPLC I/Os, you
// must also add those I/Os to the ignored vectors, otherwise OpenPLC
// will try to control your I2C pins and your I2C message won't work.
}

View File

@@ -1,66 +0,0 @@
#include "ladder.h"
//-----------------------------------------------------------------------------
// DISCLAIMER: EDDITING THIS FILE CAN BREAK YOUR OPENPLC RUNTIME! IF YOU DON'T
// KNOW WHAT YOU'RE DOING, JUST DON'T DO IT. EDIT AT YOUR OWN RISK.
//
// PS: You can always restore original functionality if you broke something
// in here by clicking on the "Restore Original Code" button above.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// These are the ignored I/O vectors. If you want to override how OpenPLC
// handles a particular input or output, you must put them in the ignored
// vectors. For example, if you want to override %IX0.5, %IX0.6 and %IW3
// your vectors must be:
// int ignored_bool_inputs[] = {5, 6}; //%IX0.5 and %IX0.6 ignored
// int ignored_int_inputs[] = {3}; //%IW3 ignored
//
// Every I/O on the ignored vectors will be skipped by OpenPLC hardware layer
//-----------------------------------------------------------------------------
int ignored_bool_inputs[] = {-1};
int ignored_bool_outputs[] = {-1};
int ignored_int_inputs[] = {-1};
int ignored_int_outputs[] = {-1};
//-----------------------------------------------------------------------------
// This function is called by the main OpenPLC routine when it is initializing.
// Hardware initialization procedures for your custom layer should be here.
//-----------------------------------------------------------------------------
void initCustomLayer()
{
}
//-----------------------------------------------------------------------------
// This function is called by OpenPLC in a loop. Here the internal input
// buffers must be updated with the values you want. Make sure to use the mutex
// bufferLock to protect access to the buffers on a threaded environment.
//-----------------------------------------------------------------------------
void updateCustomIn()
{
// Example Code - Overwritting %IW3 with a fixed value
// If you want to have %IW3 constantly reading a fixed value (for example, 53)
// you must add %IW3 to the ignored vectors above, and then just insert this
// single line of code in this function:
// if (int_input[3] != NULL) *int_input[3] = 53;
}
//-----------------------------------------------------------------------------
// This function is called by OpenPLC in a loop. Here the internal output
// buffers must be updated with the values you want. Make sure to use the mutex
// bufferLock to protect access to the buffers on a threaded environment.
//-----------------------------------------------------------------------------
void updateCustomOut()
{
// Example Code - Sending %QW5 value over I2C
// If you want to have %QW5 output to be sent over I2C instead of the
// traditional output for your board, all you have to do is, first add
// %QW5 to the ignored vectors, and then define a send_over_i2c()
// function for your platform. Finally you can call send_over_i2c() to
// send your %QW5 value, like this:
// if (int_output[5] != NULL) send_over_i2c(*int_output[5]);
//
// Important observation: If your I2C pins are used by OpenPLC I/Os, you
// must also add those I/Os to the ignored vectors, otherwise OpenPLC
// will try to control your I2C pins and your I2C message won't work.
}

View File

@@ -86,31 +86,25 @@ void initializeHardware()
//set pins as input
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), inBufferPinMask[i]))
{
gpioSetMode(inBufferPinMask[i], PI_INPUT);
gpioSetPullUpDown(inBufferPinMask[i], PI_PUD_UP); //pull up enabled
}
gpioSetMode(inBufferPinMask[i], PI_INPUT);
gpioSetPullUpDown(inBufferPinMask[i], PI_PUD_UP); //pull up enabled
}
//set pins as output
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), outBufferPinMask[i]))
gpioSetMode(outBufferPinMask[i], PI_OUTPUT);
gpioSetMode(outBufferPinMask[i], PI_OUTPUT);
}
//set PWM pins as output
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), analogOutBufferPinMask[i])){
gpioSetMode(analogOutBufferPinMask[i], PI_ALT5);
gpioSetPWMrange(analogOutBufferPinMask[i], 1024);
}
gpioSetMode(analogOutBufferPinMask[i], PI_ALT5);
gpioSetPWMrange(analogOutBufferPinMask[i], 1024);
}
// Modbus
rpi_modbus_rts_pin = MODBUS_RTS;
setModbusRtsPin(MODBUS_RTS);
// I²C?
@@ -138,8 +132,7 @@ void updateBuffersIn()
//INPUT
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), inBufferPinMask[i]))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = !gpioRead(inBufferPinMask[i]);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = !gpioRead(inBufferPinMask[i]);
}
pthread_mutex_unlock(&bufferLock); //unlock mutex
@@ -157,15 +150,13 @@ void updateBuffersOut()
//OUTPUT
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), outBufferPinMask[i]))
if (bool_output[i/8][i%8] != NULL) gpioWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) gpioWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
}
//ANALOG OUT (PWM)
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) gpioPWM(analogOutBufferPinMask[i], (*int_output[i] / 64));
if (int_output[i] != NULL) gpioPWM(analogOutBufferPinMask[i], (*int_output[i] / 64));
}
pthread_mutex_unlock(&bufferLock); //unlock mutex

View File

@@ -164,13 +164,11 @@ void updateBuffersIn()
pthread_mutex_lock(&bufferLock);
for (i=0; i<8; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[0][i] != NULL) sendBytes[1] = sendBytes[1] | (*bool_output[0][i] << i); //write each bit
if (bool_output[0][i] != NULL) sendBytes[1] = sendBytes[1] | (*bool_output[0][i] << i); //write each bit
}
for (i=8; i<16; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[1][i%8] != NULL) sendBytes[2] = sendBytes[2] | (*bool_output[1][i%8] << (i-8)); //write each bit
if (bool_output[1][i%8] != NULL) sendBytes[2] = sendBytes[2] | (*bool_output[1][i%8] << (i-8)); //write each bit
}
pthread_mutex_unlock(&bufferLock);
@@ -182,14 +180,12 @@ void updateBuffersIn()
for (i=0; i<8; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[0][i] != NULL) *bool_input[0][i] = (recvBytes[0] >> i) & 0x01;
if (bool_input[0][i] != NULL) *bool_input[0][i] = (recvBytes[0] >> i) & 0x01;
//printf("%d\t", DiscreteInputBuffer0[i]);
}
for (i=8; i<16; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[1][i%8] != NULL) *bool_input[1][i%8] = (recvBytes[1] >> (i-8)) & 0x01;
if (bool_input[1][i%8] != NULL) *bool_input[1][i%8] = (recvBytes[1] >> (i-8)) & 0x01;
//printf("%d\t", DiscreteInputBuffer0[i]);
}
//printf("\n");
@@ -211,13 +207,11 @@ void updateBuffersOut()
pthread_mutex_lock(&bufferLock);
for (i=0; i<8; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[0][i] != NULL) sendBytes[1] = sendBytes[1] | (*bool_output[0][i] << i); //write each bit
if (bool_output[0][i] != NULL) sendBytes[1] = sendBytes[1] | (*bool_output[0][i] << i); //write each bit
}
for (i=8; i<16; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[1][i%8] != NULL) sendBytes[2] = sendBytes[2] | (*bool_output[1][i%8] << (i-8)); //write each bit
if (bool_output[1][i%8] != NULL) sendBytes[2] = sendBytes[2] | (*bool_output[1][i%8] << (i-8)); //write each bit
}
pthread_mutex_unlock(&bufferLock);
@@ -229,14 +223,12 @@ void updateBuffersOut()
for (i=0; i<8; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[0][i] != NULL) *bool_input[0][i] = (recvBytes[0] >> i) & 0x01;
if (bool_input[0][i] != NULL) *bool_input[0][i] = (recvBytes[0] >> i) & 0x01;
//printf("%d\t", DiscreteInputBuffer0[i]);
}
for (i=8; i<16; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[1][i%8] != NULL) *bool_input[1][i%8] = (recvBytes[1] >> (i-8)) & 0x01;
if (bool_input[1][i%8] != NULL) *bool_input[1][i%8] = (recvBytes[1] >> (i-8)) & 0x01;
//printf("%d\t", DiscreteInputBuffer0[i]);
}
//printf("\n");

View File

@@ -309,9 +309,7 @@ void updateBuffersIn()
int i = 0;
while (digital_inputs[i][0] != '\0')
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = requestSYSFS(digital_inputs[i], "read");
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = requestSYSFS(digital_inputs[i], "read");
i++;
}
@@ -319,13 +317,12 @@ void updateBuffersIn()
i = 0;
while (analog_inputs[i][0] != '\0')
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL)
{
uint32_t value = (uint32_t)((float)requestSYSFS(analog_inputs[i], "read") * 6.5535);
if (value > 65535) value = 65535;
*int_input[i] = (uint16_t)value;
}
if (int_input[i] != NULL)
{
uint32_t value = (uint32_t)((float)requestSYSFS(analog_inputs[i], "read") * 6.5535);
if (value > 65535) value = 65535;
*int_input[i] = (uint16_t)value;
}
i++;
}
@@ -346,15 +343,12 @@ void updateBuffersOut()
int i = 0;
while (digital_outputs[i][0] != '\0')
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL)
{
if (bool_output[i/8][i%8] != NULL)
{
if (*bool_output[i/8][i%8])
requestSYSFS(digital_outputs[i], "write=1");
else
requestSYSFS(digital_outputs[i], "write=0");
}
if (*bool_output[i/8][i%8])
requestSYSFS(digital_outputs[i], "write=1");
else
requestSYSFS(digital_outputs[i], "write=0");
}
i++;
}
@@ -363,16 +357,13 @@ void updateBuffersOut()
i = 0;
while (analog_outputs[i][0] != '\0')
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL)
{
if (int_output[i] != NULL)
{
char value_fmt[100];
char value[100];
strcpy(value_fmt, "write=%f");
sprintf(value, value_fmt, ((float)*int_output[i]/6.5535));
requestSYSFS(analog_outputs[i], value);
}
char value_fmt[100];
char value[100];
strcpy(value_fmt, "write=%f");
sprintf(value, value_fmt, ((float)*int_output[i]/6.5535));
requestSYSFS(analog_outputs[i], value);
}
i++;
}

View File

@@ -73,25 +73,20 @@ void initializeHardware()
//set pins as input
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
{
pinMode(inBufferPinMask[i], INPUT);
}
pinMode(inBufferPinMask[i], INPUT);
}
//set pins as output
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
pinMode(outBufferPinMask[i], OUTPUT);
pinMode(outBufferPinMask[i], OUTPUT);
}
// pwmSetRange(1024);
// pwmSetClock(1);
// //set PWM pins as output
// for (int i = 0; i < MAX_ANALOG_OUT; i++)
// {
// if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), analogOutBufferPinMask[i])) {
// pinMode(analogOutBufferPinMask[i], PWM_OUTPUT);
// pinMode(analogOutBufferPinMask[i], PWM_OUTPUT);
// }
// }
@@ -117,8 +112,7 @@ void updateBuffersIn()
//INPUT
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = digitalRead(inBufferPinMask[i]);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = digitalRead(inBufferPinMask[i]);
}
pthread_mutex_unlock(&bufferLock); //unlock mutex
@@ -136,14 +130,12 @@ void updateBuffersOut()
//OUTPUT
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) digitalWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) digitalWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
}
//ANALOG OUT (PWM)
// for (int i = 0; i < MAX_ANALOG_OUT; i++)
// {
// if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
// if (int_output[i] != NULL) pwmWrite(analogOutBufferPinMask[i], (*int_output[i] / 64));
// if (int_output[i] != NULL) pwmWrite(analogOutBufferPinMask[i], (*int_output[i] / 64));
// }
pthread_mutex_unlock(&bufferLock); //unlock mutex

View File

@@ -844,8 +844,7 @@ void updateBuffersIn()
//DIGITAL INPUT
for (int i = 0; i < MAX_DIG_IN; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigIn, i);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigIn, i);
}
//ANALOG IN
@@ -853,8 +852,7 @@ void updateBuffersIn()
analogInputs = &InputData.wAi0;
for (int i = 0; i < MAX_ANALOG_IN; i++)
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
}
//unlock mutexes
@@ -878,13 +876,11 @@ void updateBuffersOut()
{
if (i < 6)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigOut, i, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigOut, i, *bool_output[i/8][i%8]);
}
else
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-6, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-6, *bool_output[i/8][i%8]);
}
}
@@ -897,13 +893,11 @@ void updateBuffersOut()
{
if (i < 2)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
}
else
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
}
}

View File

@@ -630,22 +630,19 @@ void updateBuffersIn()
//Read input pins 0-7
if (i < 7)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn0, i);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn0, i);
}
else
{
//Read input pins 8-15
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn1, i-(MAX_DIG_IN/2));
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn1, i-(MAX_DIG_IN/2));
}
}
//GPIO INPUT
for (int i = MAX_DIG_IN; i < MAX_DIG_IN+MAX_GPIO_IN; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byGPIOIn, i-MAX_DIG_IN);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byGPIOIn, i-MAX_DIG_IN);
}
// uint8_t byFirmware;
@@ -666,49 +663,44 @@ void updateBuffersIn()
{
if (i < MAX_ANALOG_IN)
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
}
if ((i >= MAX_ANALOG_IN) && ( i < MAX_ANALOG_IN+MAX_TEMP_IN))
{
if (i == MAX_ANALOG_IN){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp0;
if (i == MAX_ANALOG_IN)
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp0;
}
if (i == (MAX_ANALOG_IN+1)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp1;
if (i == (MAX_ANALOG_IN+1))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp1;
}
if (i == (MAX_ANALOG_IN+2)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp2;
if (i == (MAX_ANALOG_IN+2))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp2;
}
if (i == (MAX_ANALOG_IN+3)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp3;
if (i == (MAX_ANALOG_IN+3))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp3;
}
}
if ((i >= (MAX_ANALOG_IN+MAX_TEMP_IN)) && ( i < (MAX_ANALOG_IN+MAX_TEMP_IN+MAX_HUMID_IN)))
{
if (i == (MAX_ANALOG_IN+MAX_TEMP_IN))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid0;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid0;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+1))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid1;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid1;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+2))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid2;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid2;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+3))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid3;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid3;
}
}
}
@@ -738,13 +730,11 @@ void updateBuffersOut()
{
if (i < MAX_DIG_OUT-4)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut0, i, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut0, i, *bool_output[i/8][i%8]);
}
else
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut1, i - (MAX_DIG_OUT-4), *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut1, i - (MAX_DIG_OUT-4), *bool_output[i/8][i%8]);
}
}
}
@@ -754,8 +744,7 @@ void updateBuffersOut()
{
if ((i >= MAX_DIG_OUT) && (i < (MAX_DIG_OUT+MAX_REL_OUT)))
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-MAX_DIG_OUT, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-MAX_DIG_OUT, *bool_output[i/8][i%8]);
}
}
@@ -764,8 +753,7 @@ void updateBuffersOut()
{
if ((i >= MAX_DIG_OUT+MAX_REL_OUT) && (i < (MAX_DIG_OUT+MAX_REL_OUT+MAX_GPIO_OUT)))
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byGPIOOut, i-(MAX_DIG_OUT+MAX_REL_OUT), *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byGPIOOut, i-(MAX_DIG_OUT+MAX_REL_OUT), *bool_output[i/8][i%8]);
}
}
@@ -779,28 +767,23 @@ void updateBuffersOut()
if (i < 2)
{
//int_output[0] and int_output[1]
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
}
else
{
//int_output[2], 3, 4, 5, 6, 7
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
}
}
inum = MAX_ANALOG_OUT;
// PWM0Ctrl1L - PWM0Ctrl1H - 8
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), inum))
if (int_output[inum] != NULL) OutputData.wPWM0Ctrl1 = *int_output[inum];
if (int_output[inum] != NULL) OutputData.wPWM0Ctrl1 = *int_output[inum];
inum++;
// PWM1Ctrl1L - PWM1Ctrl1H - 9
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), inum))
if (int_output[inum] != NULL) OutputData.wPWM1Ctrl1 = *int_output[inum];
if (int_output[inum] != NULL) OutputData.wPWM1Ctrl1 = *int_output[inum];
inum++;
// PWM2Ctrl1L - PWM2Ctrl1H - 10
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), inum))
if (int_output[inum] != NULL) OutputData.wPWM2Ctrl1 = *int_output[inum];
if (int_output[inum] != NULL) OutputData.wPWM2Ctrl1 = *int_output[inum];
inum = 0;
// UCCtrl0 - 0
if (byte_output[inum] != NULL) OutputData.byUCCtrl0 = *byte_output[inum];

View File

@@ -564,15 +564,13 @@ void updateBuffersIn()
//DIGITAL INPUT
for (int i = 0; i < MAX_DIG_IN; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn, i);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byDigitalIn, i);
}
//GPIO INPUT
for (int i = MAX_DIG_IN; i < MAX_DIG_IN+MAX_GPIO_IN; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byGPIOIn, i-MAX_DIG_IN);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = bitRead(InputData.byGPIOIn, i-MAX_DIG_IN);
}
// uint8_t byFirmware;
@@ -593,49 +591,44 @@ void updateBuffersIn()
{
if (i < MAX_ANALOG_IN)
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
if (int_input[i] != NULL) *int_input[i] = analogInputs[i];
}
if ((i >= MAX_ANALOG_IN) && ( i < MAX_ANALOG_IN+MAX_TEMP_IN))
{
if (i == MAX_ANALOG_IN){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp0;
if (i == MAX_ANALOG_IN)
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp0;
}
if (i == (MAX_ANALOG_IN+1)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp1;
if (i == (MAX_ANALOG_IN+1))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp1;
}
if (i == (MAX_ANALOG_IN+2)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp2;
if (i == (MAX_ANALOG_IN+2))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp2;
}
if (i == (MAX_ANALOG_IN+3)){
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp3;
if (i == (MAX_ANALOG_IN+3))
{
if (int_input[i] != NULL) *int_input[i] = InputData.wTemp3;
}
}
if ((i >= (MAX_ANALOG_IN+MAX_TEMP_IN)) && ( i < (MAX_ANALOG_IN+MAX_TEMP_IN+MAX_HUMID_IN)))
{
if (i == (MAX_ANALOG_IN+MAX_TEMP_IN))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid0;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid0;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+1))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid1;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid1;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+2))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid2;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid2;
}
if (i == ((MAX_ANALOG_IN+MAX_TEMP_IN)+3))
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid3;
if (int_input[i] != NULL) *int_input[i] = InputData.wHumid3;
}
}
@@ -662,8 +655,7 @@ void updateBuffersOut()
{
if (i < MAX_DIG_OUT)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut, i, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byDigitalOut, i, *bool_output[i/8][i%8]);
}
}
@@ -672,8 +664,7 @@ void updateBuffersOut()
{
if ((i >= MAX_DIG_OUT) && (i < (MAX_DIG_OUT+MAX_REL_OUT)))
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-MAX_DIG_OUT, *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byRelayOut, i-MAX_DIG_OUT, *bool_output[i/8][i%8]);
}
}
@@ -682,8 +673,7 @@ void updateBuffersOut()
{
if ((i >= MAX_DIG_OUT+MAX_REL_OUT) && (i < (MAX_DIG_OUT+MAX_REL_OUT+MAX_GPIO_OUT)))
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byGPIOOut, i-(MAX_DIG_OUT+MAX_REL_OUT), *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) bitWrite(OutputData.byGPIOOut, i-(MAX_DIG_OUT+MAX_REL_OUT), *bool_output[i/8][i%8]);
}
}
@@ -696,18 +686,15 @@ void updateBuffersOut()
{
if (i < 2)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
if (int_output[i] != NULL) analogOutputs[i] = (*int_output[i] / 64);
}
else
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
if (int_output[i] != NULL) pwmOutputs[i-2] = *int_output[i];
}
}
// PWM0Ctrl1L - PWM0Ctrl1H
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), 4))
if (int_output[4] != NULL) OutputData.wPWM0Ctrl1 = *int_output[4];
if (int_output[4] != NULL) OutputData.wPWM0Ctrl1 = *int_output[4];
// UCCtrl0
if (byte_output[0] != NULL) OutputData.byUCCtrl0 = *byte_output[0];

View File

@@ -73,30 +73,24 @@ void initializeHardware()
//set pins as input
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), inBufferPinMask[i]))
gpioSetMode(inBufferPinMask[i], PI_INPUT);
if (i != 0 && i != 1) //pull down can't be enabled on the first two pins
{
gpioSetMode(inBufferPinMask[i], PI_INPUT);
if (i != 0 && i != 1) //pull down can't be enabled on the first two pins
{
gpioSetPullUpDown(inBufferPinMask[i], PI_PUD_DOWN); //pull down enabled
}
gpioSetPullUpDown(inBufferPinMask[i], PI_PUD_DOWN); //pull down enabled
}
}
//set pins as output
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), outBufferPinMask[i]))
gpioSetMode(outBufferPinMask[i], PI_OUTPUT);
gpioSetMode(outBufferPinMask[i], PI_OUTPUT);
}
//set PWM pins as output
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), analogOutBufferPinMask[i])) {
gpioSetMode(analogOutBufferPinMask[i], PI_ALT5);
gpioSetMode(analogOutBufferPinMask[i], PI_ALT5);
gpioSetPWMrange(analogOutBufferPinMask[i], 1024);
}
}
}
@@ -121,8 +115,7 @@ void updateBuffersIn()
//INPUT
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), inBufferPinMask[i]))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = gpioRead(inBufferPinMask[i]);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = gpioRead(inBufferPinMask[i]);
}
pthread_mutex_unlock(&bufferLock); //unlock mutex
@@ -140,15 +133,13 @@ void updateBuffersOut()
//OUTPUT
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), outBufferPinMask[i]))
if (bool_output[i/8][i%8] != NULL) gpioWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) gpioWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
}
//ANALOG OUT (PWM)
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) gpioPWM(analogOutBufferPinMask[i], (*int_output[i] / 64));
if (int_output[i] != NULL) gpioPWM(analogOutBufferPinMask[i], (*int_output[i] / 64));
}
pthread_mutex_unlock(&bufferLock); //unlock mutex

View File

@@ -74,28 +74,23 @@ void initializeHardware()
//set pins as input
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
pinMode(inBufferPinMask[i], INPUT);
if (i != 0 && i != 1) //pull down can't be enabled on the first two pins
{
pinMode(inBufferPinMask[i], INPUT);
if (i != 0 && i != 1) //pull down can't be enabled on the first two pins
{
pullUpDnControl(inBufferPinMask[i], PUD_DOWN); //pull down enabled
}
pullUpDnControl(inBufferPinMask[i], PUD_DOWN); //pull down enabled
}
}
//set pins as output
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
pinMode(outBufferPinMask[i], OUTPUT);
pinMode(outBufferPinMask[i], OUTPUT);
}
//set PWM pins as output
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
pinMode(analogOutBufferPinMask[i], PWM_OUTPUT);
pinMode(analogOutBufferPinMask[i], PWM_OUTPUT);
}
}
@@ -119,8 +114,7 @@ void updateBuffersIn()
//INPUT
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = digitalRead(inBufferPinMask[i]);
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = digitalRead(inBufferPinMask[i]);
}
pthread_mutex_unlock(&bufferLock); //unlock mutex
@@ -138,15 +132,13 @@ void updateBuffersOut()
//OUTPUT
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) digitalWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
if (bool_output[i/8][i%8] != NULL) digitalWrite(outBufferPinMask[i], *bool_output[i/8][i%8]);
}
//ANALOG OUT (PWM)
for (int i = 0; i < MAX_ANALOG_OUT; i++)
{
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), i))
if (int_output[i] != NULL) pwmWrite(analogOutBufferPinMask[i], (*int_output[i] / 64));
if (int_output[i] != NULL) pwmWrite(analogOutBufferPinMask[i], (*int_output[i] / 64));
}
pthread_mutex_unlock(&bufferLock); //unlock mutex

View File

@@ -172,21 +172,16 @@ void initializeHardware()
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
pinMode(DOUT_PINBASE + i, OUTPUT);
pinMode(DOUT_PINBASE + i, OUTPUT);
}
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
{
pinMode(inputPinMask[i], INPUT);
pullUpDnControl(inputPinMask[i], PUD_UP);
}
pinMode(inputPinMask[i], INPUT);
pullUpDnControl(inputPinMask[i], PUD_UP);
}
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), ANALOG_OUT_PIN))
pinMode(ANALOG_OUT_PIN, PWM_OUTPUT);
pinMode(ANALOG_OUT_PIN, PWM_OUTPUT);
pthread_t ADCthread;
pthread_create(&ADCthread, NULL, readAdcThread, NULL);
@@ -211,15 +206,13 @@ void updateBuffersIn()
pthread_mutex_lock(&bufferLock); //lock mutex
for (int i = 0; i < MAX_INPUT; i++)
{
if (pinNotPresent(ignored_bool_inputs, ARRAY_SIZE(ignored_bool_inputs), i))
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = !digitalRead(inputPinMask[i]); //printf("[IO%d]: %d | ", i, !digitalRead(inputPinMask[i]));
if (bool_input[i/8][i%8] != NULL) *bool_input[i/8][i%8] = !digitalRead(inputPinMask[i]); //printf("[IO%d]: %d | ", i, !digitalRead(inputPinMask[i]));
}
//printf("\nAnalog Inputs:");
for (int i = 0; i < 2; i++)
{
if (pinNotPresent(ignored_int_inputs, ARRAY_SIZE(ignored_int_inputs), i))
if (int_input[i] != NULL) *int_input[i] = mcp_adcRead(i); //printf("[AI%d]: %d | ", i, mcp_adcRead(i));
if (int_input[i] != NULL) *int_input[i] = mcp_adcRead(i); //printf("[AI%d]: %d | ", i, mcp_adcRead(i));
}
//printf("\n");
@@ -238,12 +231,10 @@ void updateBuffersOut()
//printf("\nDigital Outputs:\n");
for (int i = 0; i < MAX_OUTPUT; i++)
{
if (pinNotPresent(ignored_bool_outputs, ARRAY_SIZE(ignored_bool_outputs), i))
if (bool_output[i/8][i%8] != NULL) digitalWrite(DOUT_PINBASE + i, *bool_output[i/8][i%8]); //printf("[IO%d]: %d | ", i, digitalRead(DOUT_PINBASE + i));
if (bool_output[i/8][i%8] != NULL) digitalWrite(DOUT_PINBASE + i, *bool_output[i/8][i%8]); //printf("[IO%d]: %d | ", i, digitalRead(DOUT_PINBASE + i));
}
if (pinNotPresent(ignored_int_outputs, ARRAY_SIZE(ignored_int_outputs), 0))
if(int_output[0] != NULL) pwmWrite(ANALOG_OUT_PIN, (*int_output[0] / 64));
if(int_output[0] != NULL) pwmWrite(ANALOG_OUT_PIN, (*int_output[0] / 64));
pthread_mutex_unlock(&bufferLock); //unlock mutex
}

View File

@@ -109,24 +109,22 @@ void finalizeHardware();
void updateBuffersIn();
void updateBuffersOut();
//custom_layer.h
void initCustomLayer();
void updateCustomIn();
void updateCustomOut();
extern int ignored_bool_inputs[];
extern int ignored_bool_outputs[];
extern int ignored_int_inputs[];
extern int ignored_int_outputs[];
//main.cpp
//utils.cpp
void sleep_until(struct timespec *ts, long long delay);
void sleepms(int milliseconds);
void log(char *logmsg);
bool pinNotPresent(int *ignored_vector, int vector_size, int pinNumber);
extern uint8_t run_openplc;
void handleSpecialFunctions();
void timespec_diff(struct timespec *a, struct timespec *b, struct timespec *result);
void *interactiveServerThread(void *arg);
void disableOutputs();
void RecordCycletimeLatency(long cycle_time, long sleep_latency);
void setModbusRtsPin(uint8_t pin);
extern unsigned char log_buffer[1000000];
extern int log_index;
void handleSpecialFunctions();
//main.cpp
extern uint8_t run_openplc;
//server.cpp
void startServer(uint16_t port, int protocol_type);

View File

@@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// Copyright 2018 Thiago Alves
// This file is part of the OpenPLC Software Stack.
// This file is part of the OpenPLC Runtime.
//
// OpenPLC is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -39,175 +39,11 @@
#define OPLC_CYCLE 50000000
extern int opterr;
//extern int common_ticktime__;
IEC_BOOL __DEBUG;
IEC_LINT cycle_counter = 0;
unsigned long __tick = 0;
pthread_mutex_t bufferLock; //mutex for the internal buffers
pthread_mutex_t logLock; //mutex for the internal log
uint8_t run_openplc = 1; //Variable to control OpenPLC Runtime execution
unsigned char log_buffer[1000000]; //A very large buffer to store all logs
int log_index = 0;
int log_counter = 0;
//-----------------------------------------------------------------------------
// Helper function - Makes the running thread sleep for the ammount of time
// in milliseconds
//-----------------------------------------------------------------------------
void sleep_until(struct timespec *ts, long long delay)
{
ts->tv_sec += delay / (1000*1000*1000);
ts->tv_nsec += delay % (1000*1000*1000);
if(ts->tv_nsec >= 1000*1000*1000)
{
ts->tv_nsec -= 1000*1000*1000;
ts->tv_sec++;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
}
//-----------------------------------------------------------------------------
// Helper function - Makes the running thread sleep for the ammount of time
// in milliseconds
//-----------------------------------------------------------------------------
void sleepms(int milliseconds)
{
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
}
/**
* @fn timespec_diff(struct timespec *, struct timespec *, struct timespec *)
* @brief Compute the diff of two timespecs, that is a - b = result.
* @param a the minuend
* @param b the subtrahend
* @param result a - b
*/
static inline void timespec_diff(struct timespec *a, struct timespec *b, struct timespec *result) {
result->tv_sec = a->tv_sec - b->tv_sec;
result->tv_nsec = a->tv_nsec - b->tv_nsec;
if (result->tv_nsec < 0) {
--result->tv_sec;
result->tv_nsec += 1000000000L;
}
}
//-----------------------------------------------------------------------------
// Helper function - Logs messages and print them on the console
//-----------------------------------------------------------------------------
void log(char *logmsg)
{
pthread_mutex_lock(&logLock); //lock mutex
printf("%s", logmsg);
for (int i = 0; logmsg[i] != '\0'; i++)
{
log_buffer[log_index] = (unsigned char)logmsg[i];
log_index++;
log_buffer[log_index] = '\0';
}
log_counter++;
if (log_counter >= 1000)
{
/*Store current log on a file*/
log_counter = 0;
log_index = 0;
}
pthread_mutex_unlock(&logLock); //unlock mutex
}
//-----------------------------------------------------------------------------
// Interactive Server Thread. Creates the server to listen to commands on
// localhost
//-----------------------------------------------------------------------------
void *interactiveServerThread(void *arg)
{
startInteractiveServer(43628);
}
//-----------------------------------------------------------------------------
// Verify if pin is present in one of the ignored vectors
//-----------------------------------------------------------------------------
bool pinNotPresent(int *ignored_vector, int vector_size, int pinNumber)
{
for (int i = 0; i < vector_size; i++)
{
if (ignored_vector[i] == pinNumber)
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Disable all outputs
//-----------------------------------------------------------------------------
void disableOutputs()
{
//Disable digital outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
for (int j = 0; j < 8; j++)
{
if (bool_output[i][j] != NULL) *bool_output[i][j] = 0;
}
}
//Disable byte outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (byte_output[i] != NULL) *byte_output[i] = 0;
}
//Disable analog outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (int_output[i] != NULL) *int_output[i] = 0;
}
}
//-----------------------------------------------------------------------------
// Special Functions
//-----------------------------------------------------------------------------
void handleSpecialFunctions()
{
//current time [%ML1024]
struct tm *current_time;
time_t rawtime;
time(&rawtime);
// store the UTC clock in [%ML1027]
if (special_functions[3] != NULL) *special_functions[3] = rawtime;
current_time = localtime(&rawtime);
rawtime = rawtime - timezone;
if (current_time->tm_isdst > 0) rawtime = rawtime + 3600;
if (special_functions[0] != NULL) *special_functions[0] = rawtime;
//number of cycles [%ML1025]
cycle_counter++;
if (special_functions[1] != NULL) *special_functions[1] = cycle_counter;
//comm error counter [%ML1026]
/* Implemented in modbus_master.cpp */
//insert other special functions below
}
//-----------------------------------------------------------------------------
// Using special_functions to store REAL-TIME variables
//-----------------------------------------------------------------------------
void RecordCycletimeLatency(long cycle_time, long sleep_latency)
{
if (special_functions[4] != NULL) *special_functions[4] = cycle_time;
if (special_functions[5] != NULL) *special_functions[5] = sleep_latency;
}
// pointers to IO *array[const][const] from cpp to c and back again don't work as expected, so instead callbacks
u_int8_t *bool_input_call_back(int a, int b){ return bool_input[a][b]; }
@@ -266,11 +102,8 @@ int main(int argc,char **argv)
#endif
initializeHardware();
initializeMB();
initCustomLayer();
updateBuffersIn();
updateCustomIn();
updateBuffersOut();
updateCustomOut();
//======================================================
// PERSISTENT STORAGE INITIALIZATION
@@ -358,11 +191,9 @@ int main(int argc,char **argv)
break;
}
#endif
updateCustomIn();
updateBuffersIn_MB(); //update input image table with data from slave devices
handleSpecialFunctions();
config_run__(__tick++); // execute plc program logic
updateCustomOut();
updateBuffersOut_MB(); //update slave devices with data from the output image table
pthread_mutex_unlock(&bufferLock); //unlock mutex
@@ -413,9 +244,8 @@ int main(int argc,char **argv)
#endif
printf("Disabling outputs\n");
disableOutputs();
updateCustomOut();
updateBuffersOut();
finalizeHardware();
printf("Shutting down OpenPLC Runtime...\n");
exit(0);
}
}

View File

@@ -49,7 +49,7 @@ uint8_t bool_input_buf[MAX_MB_IO];
uint8_t bool_output_buf[MAX_MB_IO];
uint16_t int_input_buf[MAX_MB_IO];
uint16_t int_output_buf[MAX_MB_IO];
uint8_t rpi_modbus_rts_pin; // If <> 0, expect hardware RTS to be used with this pin
extern uint8_t rpi_modbus_rts_pin; // If <> 0, expect hardware RTS to be used with this pin
pthread_mutex_t ioLock;
@@ -650,8 +650,9 @@ void initializeMB()
mb_devices[i].rtu_parity, mb_devices[i].rtu_data_bit,
mb_devices[i].rtu_stop_bit);
// If hardware layer set modbus_rts_pin, enable Pi specific rts handling handling
if (rpi_modbus_rts_pin != 0) {
// If hardware layer set modbus_rts_pin, enable Pi specific rts handling
if (rpi_modbus_rts_pin != 0)
{
modbus_enable_rpi(mb_devices[i].mb_ctx,TRUE);
modbus_configure_rpi_bcm_pin(mb_devices[i].mb_ctx,rpi_modbus_rts_pin);
modbus_rpi_pin_export_direction(mb_devices[i].mb_ctx);

281
webserver/core/utils.cpp Normal file
View File

@@ -0,0 +1,281 @@
//-----------------------------------------------------------------------------
// Copyright 2024 Thiago Alves
// This file is part of the OpenPLC Runtime.
//
// OpenPLC is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenPLC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with OpenPLC. If not, see <http://www.gnu.org/licenses/>.
//------
//
// This is the main file for the OpenPLC. It contains the initialization
// procedures for the hardware, network and the main loop
// Thiago Alves, Oct 2024
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include "ladder.h"
pthread_mutex_t logLock; //mutex for the internal log
unsigned char log_buffer[1000000]; //A very large buffer to store all logs
int log_index = 0;
int log_counter = 0;
int64_t cycle_counter = 0;
uint8_t rpi_modbus_rts_pin; // If <> 0, expect hardware RTS to be used with this pin
/**
* @brief Makes the running thread sleep for the specified amount of time
*
* This function adjusts the given timespec structure by adding the specified delay,
* and then uses clock_nanosleep to make the thread sleep until the adjusted time.
*
* @param ts Pointer to a timespec structure representing the start time
* @param delay The amount of time to sleep in nanoseconds
*/
void sleep_until(struct timespec *ts, long long delay)
{
ts->tv_sec += delay / (1000*1000*1000);
ts->tv_nsec += delay % (1000*1000*1000);
if(ts->tv_nsec >= 1000*1000*1000)
{
ts->tv_nsec -= 1000*1000*1000;
ts->tv_sec++;
}
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
}
/**
* @brief Makes the running thread sleep for the specified amount of time in milliseconds
*
* This function creates a timespec structure based on the given milliseconds,
* and then uses nanosleep to make the thread sleep for the specified duration.
*
* @param milliseconds The amount of time to sleep in milliseconds
*/
void sleepms(int milliseconds)
{
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
}
/**
* @brief Compute the difference between two timespec structures
*
* This function calculates the difference between two timespec structures,
* where the result is (a - b). It handles cases where the nanosecond
* field may need to borrow from the second field.
*
* @param a Pointer to the minuend timespec
* @param b Pointer to the subtrahend timespec
* @param result Pointer to the timespec where the difference will be stored
*/
void timespec_diff(struct timespec *a, struct timespec *b, struct timespec *result)
{
// Calculate the difference in seconds
result->tv_sec = a->tv_sec - b->tv_sec;
// Calculate the difference in nanoseconds
result->tv_nsec = a->tv_nsec - b->tv_nsec;
// Handle borrowing if nanoseconds are negative
if (result->tv_nsec < 0)
{
// Borrow 1 second (1e9 nanoseconds)
--result->tv_sec;
result->tv_nsec += 1000000000L;
}
}
/**
* @brief Logs messages and prints them on the console
*
* This function logs messages to a global buffer and prints them to the console.
* It uses a mutex to ensure thread-safe access to the shared log buffer.
*
* @param logmsg Pointer to a null-terminated string containing the message to be logged
*/
void log(char *logmsg)
{
pthread_mutex_lock(&logLock); // lock mutex
printf("%s", logmsg);
size_t msg_len = strlen(logmsg);
if (log_index + msg_len >= sizeof(log_buffer) - 1)
{
// Buffer overflow protection: clear the buffer if it's nearly full
log_index = 0;
}
memcpy(&log_buffer[log_index], logmsg, msg_len);
log_index += msg_len;
log_buffer[log_index] = '\0';
log_counter++;
if (log_counter >= 1000)
{
// Clear log buffer
log_counter = 0;
log_index = 0;
}
pthread_mutex_unlock(&logLock); // unlock mutex
}
/**
* @brief Creates the server to listen to commands on localhost
*
* This function starts an interactive server on a specified port to handle
* incoming commands.
*
* @param arg Unused parameter (required for pthread creation)
* @return void* Always returns NULL
*/
void *interactiveServerThread(void *arg)
{
startInteractiveServer(43628);
return NULL;
}
/**
* @brief Disables all outputs
*
* This function sets all digital, byte, and analog outputs to zero,
* effectively disabling them.
*/
void disableOutputs()
{
//Disable digital outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
for (int j = 0; j < 8; j++)
{
if (bool_output[i][j] != NULL) *bool_output[i][j] = 0;
}
}
//Disable byte outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (byte_output[i] != NULL) *byte_output[i] = 0;
}
//Disable analog outputs
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (int_output[i] != NULL) *int_output[i] = 0;
}
}
/**
* @brief Handles special functions for the OpenPLC runtime
*
* This function manages various special functions, including:
* - Current time (stored in %ML1024)
* - UTC time (stored in %ML1027)
* - Number of cycles (stored in %ML1025)
* - Communication error counter (implemented elsewhere)
*
* @note The function assumes that the `special_functions` array is properly initialized
* and that indices 0, 1, and 3 are valid.
*/
void handleSpecialFunctions()
{
time_t rawtime;
struct tm *current_time;
time(&rawtime);
// Store the UTC clock in [%ML1027]
if (special_functions[3] != NULL)
{
*special_functions[3] = rawtime;
}
current_time = localtime(&rawtime);
// Adjust for local time
time_t localtime = rawtime - timezone;
if (current_time->tm_isdst > 0)
{
localtime += 3600; // Add one hour for daylight saving time
}
// Store local time in [%ML1024]
if (special_functions[0] != NULL)
{
*special_functions[0] = localtime;
}
// Increment and store number of cycles [%ML1025]
cycle_counter++;
if (special_functions[1] != NULL)
{
*special_functions[1] = cycle_counter;
}
// Communication error counter [%ML1026]
/* Implemented in modbus_master.cpp */
// Insert other special functions below
}
/**
* @brief Records cycle time and sleep latency in special function registers
*
* This function stores the cycle time and sleep latency values in the special
* function registers. These values are typically used for real-time performance
* monitoring and diagnostics.
*
* @param cycle_time The execution time of the PLC cycle in microseconds
* @param sleep_latency The latency between cycles in microseconds
*
* @note The function assumes that special_functions[4] and special_functions[5]
* are properly initialized and point to valid memory locations.
*/
void RecordCycletimeLatency(long cycle_time, long sleep_latency)
{
if (special_functions[4] != NULL)
{
*special_functions[4] = static_cast<IEC_LINT>(cycle_time);
}
if (special_functions[5] != NULL)
{
*special_functions[5] = static_cast<IEC_LINT>(sleep_latency);
}
}
/**
* @brief Sets the Modbus RTS (Request to Send) pin
*
* This function sets the GPIO pin number to be used for hardware RTS control
* in Modbus RTU over RS485.
*
* @param pin The GPIO pin number to be used for RTS control
*
* @note This function assumes that the external variable rpi_modbus_rts_pin
* is properly declared and accessible.
*/
void setModbusRtsPin(uint8_t pin)
{
rpi_modbus_rts_pin = pin;
}

View File

@@ -134,6 +134,7 @@ login_body = """
<button>login</button>
</form>
</div>
<h3 style="font-family:'roboto', sans-serif; font-size:14px; color:#ffffff;">Release: 2024-10-15</h3>
</div>
</div>
</body>