El nuevo Github Copilot es una herramienta revolucionaria que ha sido diseñada para ayudar a los programadores a escribir código de manera más rápida y eficiente. Esta herramienta, que utiliza la tecnología de inteligencia artificial para generar sugerencias de código en tiempo real, tiene el potencial de mejorar significativamente el proceso de programación de sistemas PLC.

En el caso específico de la programación de sistemas PLC, Github Copilot ofrece una serie de ventajas que hacen que la corrección de errores sea mucho más fácil. Por ejemplo, si el programador introduce un error en el código, Copilot puede sugerir automáticamente una corrección para el error, lo que reduce significativamente el tiempo que se necesita para resolver el problema.

Además, Copilot puede sugerir soluciones completas para problemas de programación de sistemas PLC, lo que puede ser especialmente útil para programadores nuevos en este campo. Esto puede acelerar significativamente el proceso de aprendizaje y reducir la cantidad de tiempo que los programadores tienen que dedicar a la resolución de problemas.

Otra ventaja de Github Copilot en la programación de sistemas PLC es que la herramienta puede generar código de manera más rápida y eficiente que los programadores humanos. Esto puede permitir a los programadores realizar tareas que normalmente tomarían mucho tiempo en mucho menos tiempo.

Veamos un ejemplo REAL: Le hemos pedido a Github Copilot que nos genere una FB en lenguaje SCL de Siemens para un S7-1200 que a partir de un array de 10 numeros reales, nos calcule el valor más alto, el más bajo y el valor medio del conjunto. Teniendo en cuenta que las posiciones con un valor 0, no cuentan para el valor medio. EL resultado es soprendente!!!

FUNCTION_BLOCK Calcular_Valores
TITLE = "Calcular valores de array"
VERSION : 0.1
AUTHOR : Tu nombre aquí

VAR_INPUT
    Array : ARRAY[1..10] OF REAL;
END_VAR

VAR_OUTPUT
    ValorMaximo : REAL;
    ValorMinimo : REAL;
    ValorMedio : REAL;
END_VAR

VAR
    Suma : REAL;
    Contador : INT := 0;
    Valor : REAL;
    i : INT;
END_VAR

BEGIN
    ValorMaximo := Array[1];
    ValorMinimo := Array[1];

    FOR i := 1 TO 10 DO
        Valor := Array[i];

        IF Valor > ValorMaximo THEN
            ValorMaximo := Valor;
        END_IF;

        IF Valor < ValorMinimo THEN
            ValorMinimo := Valor;
        END_IF;

        IF Valor <> 0 THEN
            Suma := Suma + Valor;
            Contador := Contador + 1;
        END_IF;
    END_FOR;

    IF Contador > 0 THEN
        ValorMedio := Suma / Contador;
    ELSE
        ValorMedio := 0;
    END_IF;
END_FUNCTION_BLOCK

Esta función bloque toma un array de 10 números reales como entrada, y calcula el valor máximo, el valor mínimo y el valor medio del conjunto. Si hay alguna posición con un valor de 0, no se cuenta para el valor medio. El valor máximo se almacena en la variable de salida “ValorMaximo”, el valor mínimo en “ValorMinimo” y el valor medio en “ValorMedio”.

Además, podemos pedirle que nos haga un ejemplo con números aleatorios….¿como? PIDIENDOSELO!!

PROGRAM Ejemplo
VAR
    ArrayDatos : ARRAY[1..10] OF REAL := [1.2, 5.6, 0, 7.8, 2.4, 0, 9.1, 3.5, 4.7, 6.3];
    ValorMaximo : REAL;
    ValorMinimo : REAL;
    ValorMedio : REAL;
END_VAR

Calcular_Valores(ArrayDatos, ValorMaximo, ValorMinimo, ValorMedio);

En este ejemplo, he creado un array de 10 números reales llamado “ArrayDatos”. He inicializado algunos de los valores a 0 para probar que la FB omite correctamente los valores de 0 al calcular el valor medio.

Luego, he declarado tres variables de salida: “ValorMaximo”, “ValorMinimo” y “ValorMedio”. He llamado a la función bloque “Calcular_Valores” y he pasado el array de datos como entrada y las variables de salida para almacenar los resultados.

Que pasa si por necesidades varias, tenemos que retocar el código, pues que Copilot nos lo hace por nosotros:

A Github Copilot: Debo pedirte que teniendo en cuenta el codigo que has escrito, realices dos modificaciones: la primera es que aumentes el numero de elementos del array de 10 a 100. La segunda que tambien calcules la suma de todos los numeros del array.

Y se hace la magia:

FUNCTION_BLOCK Calcular_Valores
TITLE = "Calcular valores de array"
VERSION : 0.2
AUTHOR : Tu nombre aquí

VAR_INPUT
    Array : ARRAY[1..100] OF REAL;
END_VAR

VAR_OUTPUT
    ValorMaximo : REAL;
    ValorMinimo : REAL;
    ValorMedio : REAL;
    Suma : REAL;
END_VAR

VAR
    Contador : INT := 0;
    Valor : REAL;
    i : INT;
END_VAR

BEGIN
    ValorMaximo := Array[1];
    ValorMinimo := Array[1];

    FOR i := 1 TO 100 DO
        Valor := Array[i];

        IF Valor > ValorMaximo THEN
            ValorMaximo := Valor;
        END_IF;

        IF Valor < ValorMinimo THEN
            ValorMinimo := Valor;
        END_IF;

        IF Valor <> 0 THEN
            Suma := Suma + Valor;
            Contador := Contador + 1;
        END_IF;
    END_FOR;

    IF Contador > 0 THEN
        ValorMedio := Suma / Contador;
    ELSE
        ValorMedio := 0;
    END_IF;
END_FUNCTION_BLOCK

En esta versión actualizada, he modificado el tamaño del array de entrada de 10 a 100, como lo has solicitado. Además, he agregado una variable de salida adicional llamada “Suma” para almacenar la suma total de los elementos del array.

La lógica para calcular la suma total es bastante simple: agregamos cada valor no nulo en el array al acumulador “Suma”. Luego, el resultado se almacena en la variable de salida “Suma”.

Espero que esta versión actualizada sea útil para ti. Si tienes alguna pregunta, no dudes en preguntar.

BIEN ESTA CLARO QUE PARA PROBLEMAS MAS COMPLEJOS, SIEMPRE SE NECESITARA UN HUMANO…. O QUIZAS….

A Github Copilot: Podrias escribir un codigo para la plataforma Arduino para el control en lazo cerrado de un motor paso a paso? el motor tiene un encoder incremental acoplado en su eje que nos indica la posicion del mismo. El encoder nos entrega 2048 pulsos por vuelta. el codigo python debe permitir poner en marcha el motor o pararlo pulsando las teclas del teclado S y R respectivamente.

#include <AccelStepper.h>

// Definimos los pines de control del motor
#define motorPin1 8
#define motorPin2 9
#define motorPin3 10
#define motorPin4 11

// Definimos los pines de señal del encoder
#define encoderPinA 2
#define encoderPinB 3

// Configuramos los parámetros del motor y del encoder
#define STEPS_PER_REVOLUTION 2048
#define MICROSTEPS 16
#define ENCODER_STEPS_PER_REVOLUTION 2048

// Creamos una instancia de la clase AccelStepper para controlar el motor
AccelStepper motor(AccelStepper::FULL4WIRE, motorPin1, motorPin3, motorPin2, motorPin4);

// Variables para controlar la posición del motor y del encoder
long currentPosition = 0;
long targetPosition = 0;
long encoderPosition = 0;

// Variables para el control PID
float Kp = 1.0;
float Ki = 0.0;
float Kd = 0.0;
float pidOutput = 0.0;
float error = 0.0;
float lastError = 0.0;
float sumError = 0.0;
unsigned long lastTime = 0;

// Función para actualizar la posición del motor y del encoder
void updatePositions() {
  currentPosition = motor.currentPosition();
  encoderPosition = (long) (ENCODER_STEPS_PER_REVOLUTION * (currentPosition / (MICROSTEPS * STEPS_PER_REVOLUTION)));
}

// Función para calcular la salida del controlador PID
void calculatePID() {
  unsigned long now = millis();
  float deltaTime = (now - lastTime) / 1000.0;
  lastTime = now;

  error = targetPosition - encoderPosition;
  sumError += error * deltaTime;
  float dError = (error - lastError) / deltaTime;

  pidOutput = Kp * error + Ki * sumError + Kd * dError;

  lastError = error;
}

void setup() {
  // Configuramos los pines de control del motor
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  // Configuramos los pines de señal del encoder
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);

  // Configuramos la velocidad máxima y la aceleración del motor
  motor.setMaxSpeed(1000.0);
  motor.setAcceleration(100.0);

  // Movemos el motor a la posición inicial
  motor.moveTo(0);
  motor.setSpeed(500);
  motor.runToPosition();

  // Actualizamos las posiciones del motor y del encoder
  updatePositions();
}

void loop() {
  // Actualizamos las posiciones del motor y del encoder
  updatePositions();

  // Si se pulsa la tecla 'S', establecemos la posición objetivo
  if (Serial.available() > 0) {
    char c = Serial.read();
    if (c == 'S') {
      targetPosition = currentPosition + (MICROSTEPS * STEPS_PER_REVOLUTION);
    }
  }
  // Si se pulsa la tecla 'R', detenemos el motor
  if (c == 'R') {
    motor.stop();
  }
}

// Calculamos la salida del controlador PID calculatePID();

// Movemos el motor a la posición objetivo motor.setSpeed(pidOutput); motor.moveTo((long) (targetPosition / (MICROSTEPS * ENCODER_STEPS_PER_REVOLUTION))); motor.run();

// Imprimimos la posición actual del motor y del encoder Serial.print("Current position: “); Serial.print(currentPosition); Serial.print(”, Encoder position: “); Serial.print(encoderPosition); Serial.print(”, Target position: "); Serial.println(targetPosition); }

Os aseguramos que no hemos tocado ni una sola letra del codigo que Copilot ha generado. Si lo copiais a un sistema IDE Arduino os funcionará a la primera.