Autor Tema: Grafcets en Arduino. Encendido de dos ledes  (Leído 746 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Carlos

  • Moderador Global
  • ****
  • Mensajes: 325
Grafcets en Arduino. Encendido de dos ledes
« en: 02/Ene./2020, 12:55:39 p. m. »
TAGS:
Implementar Grafcets en c.
Implementar Grafcets en Arduino.
Programación concurrente en Arduino.

Introducción:
Adjunto un programa para Arduino, en C, que implementa dos grafcets para encender y apagar dos ledes con dos pulsadores. Cada grafcet es independiente uno del otro y se ejecutan en paralelo.

Código: C
  1. /*
  2.  * Implementación de Grafcet
  3.  * para encender dos ledes con dos pulsadores
  4.  */
  5.  
  6. // Definiciones
  7. #define NUMERO_DE_GRAFCETS  2
  8. #define NUMERO_DE_ENTRADAS  2
  9. #define NUMERO_DE_SALIDAS   2
  10.  
  11. #define PIN_LED_VERDE   2
  12. #define PIN_LED_ROJO    3
  13. #define PIN_PULSADOR_1  8
  14. #define PIN_PULSADOR_2  9
  15.  
  16. #define PULSADOR_PRESIONADO  0
  17. #define PULSADOR_REPOSO      1
  18. #define LED_ENCENDIDO        1
  19. #define LED_APAGADO          0
  20.  
  21.  
  22. enum NOMBRE_GRAFCETS {
  23.    GRAFCET_LED_VERDE,
  24.    GRAFCET_LED_ROJO,
  25. };
  26.  
  27. enum ENTRADAS_FISICAS {
  28.    PULSADOR_1,
  29.    PULSADOR_2,
  30. };
  31.  
  32. enum SALIDAS_FISICAS {
  33.    LED_VERDE,
  34.    LED_ROJO,
  35. };
  36.  
  37. typedef union  {
  38.   struct {
  39.     unsigned char etapa0: 1;
  40.     unsigned char etapa1: 1;
  41.     unsigned char etapa2: 1;
  42.     unsigned char etapa3: 1;
  43.     unsigned char etapa4: 1;
  44.     unsigned char etapa5: 1;
  45.     unsigned char etapa6: 1;
  46.     unsigned char etapa7: 1;
  47.   };
  48.   unsigned char etapas;
  49. } tipo_grafcet;
  50.  
  51.  
  52. // Declaración de variables
  53. tipo_grafcet grafcet[NUMERO_DE_GRAFCETS];
  54. tipo_grafcet grafcet_siguiente[NUMERO_DE_GRAFCETS];
  55. unsigned char entradas[NUMERO_DE_ENTRADAS];
  56. unsigned char salidas[NUMERO_DE_SALIDAS];
  57.  
  58.  
  59. // Programa principal
  60. void setup(void) {
  61.    setup_pines();
  62.    grafcet_inicializar();
  63.    while(1) {
  64.       print_estado();
  65.       leer_entradas();
  66.       grafcets_evoluciona();
  67.       escribir_salidas();
  68.       temporizadores();
  69.    }
  70. }
  71.  
  72. void loop(void) {
  73. }
  74.  
  75.  
  76. //
  77. // Funciones del programa principal
  78. //
  79.  
  80. void setup_pines(void) {
  81.    pinMode(PIN_LED_VERDE, OUTPUT);
  82.    pinMode(PIN_LED_ROJO, OUTPUT);
  83.    pinMode(PIN_PULSADOR_1, INPUT_PULLUP);
  84.    pinMode(PIN_PULSADOR_2, INPUT_PULLUP);
  85.  
  86.    Serial.begin(9600);
  87. }
  88.  
  89. void grafcet_inicializar(void) {
  90.    grafcet_siguiente[GRAFCET_LED_VERDE].etapas = 0;
  91.    grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 1;
  92.  
  93.    grafcet_siguiente[GRAFCET_LED_ROJO].etapas = 0;
  94.    grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 1;
  95. }
  96.  
  97.  
  98. void leer_entradas(void) {
  99.    entradas[PULSADOR_1] = digitalRead(PIN_PULSADOR_1);
  100.    entradas[PULSADOR_2] = digitalRead(PIN_PULSADOR_2);
  101. }
  102.  
  103.  
  104. void escribir_salidas(void) {
  105.    digitalWrite(PIN_LED_VERDE, salidas[LED_VERDE]);
  106.    digitalWrite(PIN_LED_ROJO, salidas[LED_ROJO]);
  107. }
  108.  
  109.  
  110. void grafcets_evoluciona(void) {
  111.    grafcets_copiar_transiciones();
  112.    grafcets_calcular_transiciones();
  113.    grafcets_calcular_acciones();
  114. }
  115.  
  116.  
  117. void grafcets_copiar_transiciones(void) {
  118.    grafcet[GRAFCET_LED_VERDE].etapas = grafcet_siguiente[GRAFCET_LED_VERDE].etapas;
  119.    grafcet[GRAFCET_LED_ROJO].etapas = grafcet_siguiente[GRAFCET_LED_ROJO].etapas;
  120. }
  121.  
  122.  
  123. void grafcets_calcular_transiciones(void) {
  124.  
  125.    // GRAFCET_LED_VERDE
  126.    if (grafcet[GRAFCET_LED_VERDE].etapa0 == 1 &&
  127.        entradas[PULSADOR_1] == PULSADOR_PRESIONADO) {
  128.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 0;
  129.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa1 = 1;
  130.    }
  131.  
  132.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1 &&
  133.        entradas[PULSADOR_1] == PULSADOR_REPOSO) {
  134.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa1 = 0;
  135.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa2 = 1;
  136.    }
  137.  
  138.    if (grafcet[GRAFCET_LED_VERDE].etapa2 == 1 &&
  139.        entradas[PULSADOR_1] == PULSADOR_PRESIONADO) {
  140.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa2 = 0;
  141.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa3 = 1;
  142.    }
  143.  
  144.    if (grafcet[GRAFCET_LED_VERDE].etapa3 == 1 &&
  145.        entradas[PULSADOR_1] == PULSADOR_REPOSO) {
  146.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa3 = 0;
  147.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 1;
  148.    }
  149.  
  150.    // GRAFCET_LED_ROJO
  151.    if (grafcet[GRAFCET_LED_ROJO].etapa0 == 1 &&
  152.        entradas[PULSADOR_2] == PULSADOR_PRESIONADO) {
  153.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 0;
  154.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa1 = 1;
  155.    }
  156.  
  157.    if (grafcet[GRAFCET_LED_ROJO].etapa1 == 1 &&
  158.        entradas[PULSADOR_2] == PULSADOR_REPOSO) {
  159.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa1 = 0;
  160.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa2 = 1;
  161.    }
  162.  
  163.    if (grafcet[GRAFCET_LED_ROJO].etapa2 == 1 &&
  164.        entradas[PULSADOR_2] == PULSADOR_PRESIONADO) {
  165.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa2 = 0;
  166.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa3 = 1;
  167.    }
  168.  
  169.    if (grafcet[GRAFCET_LED_ROJO].etapa3 == 1 &&
  170.        entradas[PULSADOR_2] == PULSADOR_REPOSO) {
  171.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa3 = 0;
  172.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 1;
  173.    }
  174. }
  175.  
  176.  
  177. void grafcets_calcular_acciones(void) {
  178.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1 ||
  179.        grafcet[GRAFCET_LED_VERDE].etapa2 == 1 ) {
  180.       salidas[LED_VERDE] = LED_ENCENDIDO;
  181.    }
  182.    else {
  183.       salidas[LED_VERDE] = LED_APAGADO;  
  184.    }
  185.  
  186.    if (grafcet[GRAFCET_LED_ROJO].etapa1 == 1 ||
  187.        grafcet[GRAFCET_LED_ROJO].etapa2 == 1 ) {
  188.       salidas[LED_ROJO] = LED_ENCENDIDO;
  189.    }
  190.    else {
  191.       salidas[LED_ROJO] = LED_APAGADO;  
  192.    }
  193. }
  194.  
  195.  
  196. void temporizadores(void) {
  197.  
  198. }
  199.  
  200. void print_estado(void) {
  201.    Serial.print("Etapas:");
  202.    Serial.print("  Grafcet led verde=");
  203.    Serial.print(grafcet[GRAFCET_LED_VERDE].etapas);
  204.    Serial.print("  Grafcet led rojo =");
  205.    Serial.print(grafcet[GRAFCET_LED_ROJO].etapas);
  206.    Serial.println();
  207. }
  208.  

Adjunto grafcet de un solo pulsador y un led, esquema eléctrico y esquema de cableado en protoboard.
« Última modificación: 16/Ene./2020, 16:42:18 p. m. por Carlos »

Carlos

  • Moderador Global
  • ****
  • Mensajes: 325
Re:Grafcets en Arduino. Encendido de dos ledes
« Respuesta #1 en: 02/Ene./2020, 20:51:57 p. m. »
El segundo programa tiene el siguiente funcionamiento:

Código: C
  1. /*
  2.  * Implementación de Grafcet
  3.  * para encender dos ledes con dos pulsadores
  4.  *
  5.  * El primer led verde se enciende y se apaga
  6.  * al presionar el pulsador 1.
  7.  *
  8.  * El segundo led rojo se enciende durante
  9.  * 10 segundos al presionar el pulsador 2.
  10.  *
  11.  */
  12.  
  13. // Definiciones
  14. #define NUMERO_DE_ENTRADAS  2
  15. #define NUMERO_DE_SALIDAS   2
  16. #define NUMERO_DE_GRAFCETS  2
  17. #define NUMERO_DE_TEMPORIZADORES  1
  18.  
  19. #define PIN_LED_VERDE   2
  20. #define PIN_LED_ROJO    3
  21. #define PIN_PULSADOR_1  8
  22. #define PIN_PULSADOR_2  9
  23.  
  24. #define PULSADOR_PRESIONADO  0
  25. #define PULSADOR_REPOSO      1
  26. #define LED_ENCENDIDO        1
  27. #define LED_APAGADO          0
  28.  
  29. #define SEGUNDOS_EN_DECIMAS 10
  30.  
  31. enum ENTRADAS_FISICAS {
  32.    PULSADOR_1,
  33.    PULSADOR_2,
  34. };
  35.  
  36. enum SALIDAS_FISICAS {
  37.    LED_VERDE,
  38.    LED_ROJO,
  39. };
  40.  
  41. enum NOMBRE_GRAFCETS {
  42.    GRAFCET_LED_VERDE,
  43.    GRAFCET_LED_ROJO,
  44. };
  45.  
  46. enum NOMBRE_TEMPORIZADORES {
  47.    TEMPORIZADOR_1,
  48. };
  49.  
  50. enum TEMPORIZADOR_ESTADOS {
  51.    TEMPORIZADOR_REPOSO,
  52.    TEMPORIZADOR_CONTANDO,
  53.    TEMPORIZADOR_TERMINADO,
  54. };
  55.  
  56. typedef union  {
  57.   struct {
  58.     unsigned int etapa0: 1;
  59.     unsigned int etapa1: 1;
  60.     unsigned int etapa2: 1;
  61.     unsigned int etapa3: 1;
  62.     unsigned int etapa4: 1;
  63.     unsigned int etapa5: 1;
  64.     unsigned int etapa6: 1;
  65.     unsigned int etapa7: 1;
  66.     unsigned int etapa8: 1;
  67.     unsigned int etapa9: 1;
  68.     unsigned int etapa10: 1;
  69.     unsigned int etapa11: 1;
  70.     unsigned int etapa12: 1;
  71.     unsigned int etapa13: 1;
  72.     unsigned int etapa14: 1;
  73.     unsigned int etapa15: 1;
  74.   };
  75.   unsigned int etapas;
  76. } tipo_grafcet;
  77.  
  78. typedef struct {
  79.    unsigned char estado;
  80.    unsigned int tiempo;
  81. } tipo_temporizador;
  82.  
  83.  
  84. // Declaración de variables
  85. unsigned char entradas[NUMERO_DE_ENTRADAS];
  86. unsigned char salidas[NUMERO_DE_SALIDAS];
  87. tipo_grafcet grafcet[NUMERO_DE_GRAFCETS];
  88. tipo_grafcet grafcet_siguiente[NUMERO_DE_GRAFCETS];
  89. tipo_temporizador temporizador[NUMERO_DE_TEMPORIZADORES];
  90. unsigned int decisegundos;
  91. unsigned long cien_milisegundos;
  92.  
  93. // Programa principal
  94. void setup(void) {
  95.    setup_pines();
  96.    inicializar_grafcets();
  97.    inicializar_temporizadores();
  98.    
  99.    while(1) {
  100.       print_estado();
  101.       leer_entradas();
  102.       grafcets_evoluciona();
  103.       escribir_salidas();
  104.       temporizadores();
  105.    }
  106. }
  107.  
  108. void loop(void) {
  109. }
  110.  
  111.  
  112. //
  113. // Funciones del programa principal
  114. //
  115.  
  116. void setup_pines(void) {
  117.    pinMode(PIN_LED_VERDE, OUTPUT);
  118.    pinMode(PIN_LED_ROJO, OUTPUT);
  119.    pinMode(PIN_PULSADOR_1, INPUT_PULLUP);
  120.    pinMode(PIN_PULSADOR_2, INPUT_PULLUP);
  121.  
  122.    Serial.begin(9600);
  123. }
  124.  
  125.  
  126. void inicializar_grafcets(void) {
  127.    grafcet_siguiente[GRAFCET_LED_VERDE].etapas = 0;
  128.    grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 1;
  129.  
  130.    grafcet_siguiente[GRAFCET_LED_ROJO].etapas = 0;
  131.    grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 1;
  132. }
  133.  
  134.  
  135. void inicializar_temporizadores(void) {
  136.    unsigned char i;
  137.    for(i=0; i < NUMERO_DE_TEMPORIZADORES; i++) {
  138.       temporizador[i].estado = TEMPORIZADOR_REPOSO;
  139.    }
  140.  
  141.    decisegundos = 0;
  142.    cien_milisegundos = millis() + 100;
  143. }
  144.  
  145.  
  146. void leer_entradas(void) {
  147.    entradas[PULSADOR_1] = digitalRead(PIN_PULSADOR_1);
  148.    entradas[PULSADOR_2] = digitalRead(PIN_PULSADOR_2);
  149. }
  150.  
  151.  
  152. void escribir_salidas(void) {
  153.    digitalWrite(PIN_LED_VERDE, salidas[LED_VERDE]);
  154.    digitalWrite(PIN_LED_ROJO, salidas[LED_ROJO]);
  155. }
  156.  
  157.  
  158. void grafcets_evoluciona(void) {
  159.    grafcets_copiar_transiciones();
  160.    grafcets_calcular_transiciones();
  161.    grafcets_calcular_acciones();
  162. }
  163.  
  164.  
  165. void grafcets_copiar_transiciones(void) {
  166.    unsigned char i;
  167.    for(i=0; i < NUMERO_DE_GRAFCETS; i++) {
  168.       grafcet[i].etapas = grafcet_siguiente[i].etapas;
  169.    }
  170. }
  171.  
  172.  
  173. void grafcets_calcular_transiciones(void) {
  174.  
  175.    // GRAFCET_LED_VERDE
  176.    if (grafcet[GRAFCET_LED_VERDE].etapa0 == 1 &&
  177.        entradas[PULSADOR_1] == PULSADOR_PRESIONADO) {
  178.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 0;
  179.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa1 = 1;
  180.    }
  181.  
  182.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1 &&
  183.        entradas[PULSADOR_1] == PULSADOR_REPOSO) {
  184.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa1 = 0;
  185.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa2 = 1;
  186.    }
  187.  
  188.    if (grafcet[GRAFCET_LED_VERDE].etapa2 == 1 &&
  189.        entradas[PULSADOR_1] == PULSADOR_PRESIONADO) {
  190.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa2 = 0;
  191.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa3 = 1;
  192.    }
  193.  
  194.    if (grafcet[GRAFCET_LED_VERDE].etapa3 == 1 &&
  195.        entradas[PULSADOR_1] == PULSADOR_REPOSO) {
  196.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa3 = 0;
  197.       grafcet_siguiente[GRAFCET_LED_VERDE].etapa0 = 1;
  198.    }
  199.  
  200.    // GRAFCET_LED_ROJO TEMPORIZADO
  201.    if (grafcet[GRAFCET_LED_ROJO].etapa0 == 1 &&
  202.        entradas[PULSADOR_2] == PULSADOR_PRESIONADO) {
  203.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 0;
  204.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa1 = 1;
  205.    }
  206.  
  207.    if (grafcet[GRAFCET_LED_ROJO].etapa1 == 1 &&
  208.        temporizador[TEMPORIZADOR_1].estado == TEMPORIZADOR_TERMINADO) {
  209.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa1 = 0;
  210.       grafcet_siguiente[GRAFCET_LED_ROJO].etapa0 = 1;
  211.    }
  212. }
  213.  
  214.  
  215. void grafcets_calcular_acciones(void) {
  216.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1 ||
  217.        grafcet[GRAFCET_LED_VERDE].etapa2 == 1 ) {
  218.       salidas[LED_VERDE] = LED_ENCENDIDO;
  219.    }
  220.    else {
  221.       salidas[LED_VERDE] = LED_APAGADO;  
  222.    }
  223.  
  224.    if (grafcet[GRAFCET_LED_ROJO].etapa1 == 1 ) {
  225.       salidas[LED_ROJO] = LED_ENCENDIDO;
  226.    }
  227.    else {
  228.       salidas[LED_ROJO] = LED_APAGADO;  
  229.    }
  230. }
  231.  
  232.  
  233. void temporizadores(void) {
  234.    // Actualizar estado de los temporizadores
  235.    temporizador_actualizar(TEMPORIZADOR_1,
  236.                            grafcet[GRAFCET_LED_ROJO].etapa1,
  237.                            10*SEGUNDOS_EN_DECIMAS);
  238.  
  239.  
  240.    // Actualizar variable decisegundos
  241.    if (millis() - cien_milisegundos < 10000 ) {
  242.       cien_milisegundos += 100;
  243.       decisegundos += 1;
  244.    }
  245. }
  246.  
  247.  
  248. void temporizador_actualizar(unsigned char temporizador_id,
  249.                              unsigned int grafcet_etapas,
  250.                              unsigned int tiempo) {
  251.    if (grafcet_etapas == 0) {
  252.       temporizador[temporizador_id].estado = TEMPORIZADOR_REPOSO;
  253.    }
  254.  
  255.    if (grafcet_etapas != 0 &&
  256.        temporizador[temporizador_id].estado == TEMPORIZADOR_REPOSO) {
  257.       temporizador[temporizador_id].tiempo = decisegundos + tiempo;
  258.       temporizador[temporizador_id].estado = TEMPORIZADOR_CONTANDO;
  259.    }
  260.  
  261.    if (temporizador[temporizador_id].estado == TEMPORIZADOR_CONTANDO &&
  262.        decisegundos - temporizador[temporizador_id].tiempo < 10 * SEGUNDOS_EN_DECIMAS ) {
  263.       temporizador[temporizador_id].estado = TEMPORIZADOR_TERMINADO;  
  264.    }
  265. }
  266.  
  267.  
  268. void print_estado(void) {
  269.    Serial.print("Grafcet led verde=");
  270.    Serial.print(grafcet[GRAFCET_LED_VERDE].etapas);
  271.    Serial.print(" Grafcet led rojo=");
  272.    Serial.print(grafcet[GRAFCET_LED_ROJO].etapas);
  273.    Serial.print(" Temporizador=");
  274.    Serial.print(temporizador[TEMPORIZADOR_1].estado);
  275.    Serial.print(" ");
  276.    Serial.print(temporizador[TEMPORIZADOR_1].tiempo);
  277.    Serial.println();
  278. }
  279.  

Adjunto grafcet del segundo led (Led rojo).
« Última modificación: 03/Ene./2020, 18:48:27 p. m. por Carlos »