User Tools

Site Tools

한국어

modularfaduino:managedcodebase

Description of Managed code base

Do you know which PLC is mainly used in industrial sites? PLC is a controller that has been used in automation fields for a very long time.

There are many reasons why PLC is widely used, but one of them is the unique operation process called scan programming method. This method has the advantage of generating robust software from noise.

PLC reads all input ports, stores them in a buffer, performs logic operations on the buffer, and then reflects the results to the output ports. And this situation repeats itself until the power goes off.

Even if an incorrect output is produced due to noise, it will be corrected as soon as the noise disappears due to the continuously executing scan structure.

Even in C language, you can code using the batch scan method used in PLC.

After receiving all inputs and storing them in the input array buffer (X[0] ~ X[127]). After performing logic operation/processing, simply reflect the contents in the output array buffer (Y[0]~Y[127]) to the output module.

As shown in the picture below, the source was created assuming that all 8 inputs and 8 outputs were connected. However, even if you do not connect everything like this, the source will work. However, the array corresponding to the unconnected I/O module does not operate and only takes up space. Don't let that reduce the array, you still need it.

Copy and paste this source into Arduino IDE.

#include "CFMEGA.h"
 
CFNET cfnet;
uint8_t X[128]; // Input Coil
uint8_t Y[128]; // Output Coil
 
void distribute_value(uint16_t val, uint8_t where) {
    for (int i = 0; i < 16; i++) {
        X[where++] = val & 1;
        val >>= 1;
    }
}
 
void input_proc() {
    for (int i = 0; i < 8; i++) {
        distribute_value(cfnet.digitalRead(i), i * 16);
    }
}
 
uint16_t collect_value(uint8_t where) {
    uint16_t tempV = 0;
    for (int i = 0; i < 16; i++) {
        tempV |= (Y[where++] & 1) << i;
    }
    return tempV;
}
 
void output_proc() {
    for (int i = 0; i < 8; i++) {
        cfnet.digitalWrite(i, collect_value(i * 16));
    }
}
 
void setup() { }
 
void loop() {
 
  input_proc();  
  Y[0] = X[0];  // Main Logic Program
  output_proc();
 
}

Only 1 bit (0 or 1) is stored in each array position. It is an array of bytes, but there is no choice because there is no bit array in the C language.

Source code description

The part between input_proc and output_proc at the bottom is where logic calculations and processing are performed, and it is like a formula.

 Y[0] = X[0]; // Main Logic Program

Ladder logic generally used in PLC can be replaced with formulas used in C language.

Ladder explanation: When X0 input is On, Y0 output is On. When X0 turns off, Y0 also turns off. OR and AND situations can also be converted to C language.

  • OR Ladder Description: If either X0 or X1 is On, Y0 output is On.
  • AND Ladder Description: When both X0 and X1 are On, Y0 output is On.

Managed Code Base

By using time interrupts, logic processing can be performed periodically.

Rather than calling the logic processing within the loop, the logic processing is called and executed using an interrupt that occurs every 20mS.

#include "CFMEGA.h"
CFNET cfnet;
 
uint8_t X[128]; // Input Coil
uint8_t Y[128]; // Output Coil
 
void distribute_value(uint16_t val, uint8_t where) {
    for (int i = 0; i < 16; i++) {
        X[where++] = val & 1;
        val >>= 1;
    }
}
 
void input_proc() {
    for (int i = 0; i < 8; i++) {
        distribute_value(cfnet.digitalRead(i), i * 16);
    }
}
 
uint16_t collect_value(uint8_t where) {
    uint16_t tempV = 0;
    for (int i = 0; i < 16; i++) {
        tempV |= (Y[where++] & 1) << i;
    }
    return tempV;
}
 
void output_proc() {
    for (int i = 0; i < 8; i++) {
        cfnet.digitalWrite(i, collect_value(i * 16));
    }
}
 
 
ISR(TIMER5_OVF_vect)
{
  TCNT5 = 198; // for 20mS
  sei(); // Enable Global Interrupt
  input_proc();  
  logic_proc();
  output_proc();
}
 
void setup() { 
  TCCR5B = 5; // Clock source from system clock/1024
  TIMSK5 |= 1;	//TOV interrupt set.
  sei(); // Enable Global Interrupt
}
 
void loop() {
  // User source
  // You can use delay() funtion here.
}
 
// execute every 20ms (don't use delay() function here)
 
void logic_proc()
{
  Y[0] = X[0];  // Main Logic Program
}

It's a bit complicated, but the reason for doing this is to run regular Arduino code inside loop(). Regular Arduino code often uses delay or Serial.print()1), which pauses the MCU for a moment. This breaks the smooth flow, because logic_proc() has to finish executing within 20mS.

Code with the following caution:

  • You can use delay or Serial functions in loop() . But do not disable global interrupts.
  • Don't hold time inside logic_proc(). Don't do delay() or serial communication here.

Notification

Please use this source at your own risk. If this source is applied to an actual project, we are not responsible for any errors or accidents. Please use this source only if you agree to this. We are not accepting technical inquiries regarding this source. Please understand this.

Modular FADUINO

1)
Serial communication commands are executed while waiting until all transmission data has been transmitted, so it is a kind of delay().
modularfaduino/managedcodebase.txt · Last modified: 2024/10/31 03:40 by COMFILE Technology