Autor Tema: Ayuda | Proyecto Final problema con maquina y PIC16F877A  (Leído 16015 veces)

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

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #45 en: 31 de Diciembre de 2019, 10:42:55 »
Pero creo que deberías comenzar por hacer un programa muy sencillito de tipo encender y apagar una luz para entender cómo funciona el grafcet y luego comienzas con tu programa.

Aquí te dejo un grafcet sencillo que enciende y apaga una luz con un solo pulsador.



Te propongo que hagas un programa para manejar 2 grafcet, cada uno con un led y con un pulsador diferente y así puedes comprobar cómo pueden trabajar dos grafcet a la vez.
« Última modificación: 31 de Diciembre de 2019, 10:45:42 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #46 en: 01 de Enero de 2020, 14:38:29 »
Si tengo algo de tiempo lo programaré para que veas cómo se hace.

Otra idea es hacer las tareas que hace el grafcet con un RTOS, pero tal y como van las cosas hoy en día con los PIC antes te recomendaría que te pasaras a los microcontroladores ATmega (Los que traen las placas Arduino). Con un Arduino es muy sencillo utilizar un RTOS que es un sistema operativo en tiempo real con el que puedes programar varias tareas que se ejecutan todas al mismo tiempo.

En los PIC también hay sistemas operativos en tiempo real (RTOS) pero parece que están algo desfasados hoy en día.
El SALVO es de pago aunque tiene una versión gratuíta que permite hasta 3 tareas.
El RTOS OSA es libre pero igual que el anterior está un poco desfasado y hay que compilarle con compiladores antiguos.

Un saludo.
« Última modificación: 01 de Enero de 2020, 14:41:57 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #47 en: 02 de Enero de 2020, 08:28:27 »
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. }

Esquema:

 

* grafcets_dos_ledes_sch.png
(44.97 kB, 1203x696 - visto 587 veces)



Protoboard:

 

* grafcets_dos_ledes_bb.png
(148.7 kB, 918x1242 - visto 601 veces)
« Última modificación: 02 de Enero de 2020, 08:49:19 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #48 en: 02 de Enero de 2020, 16:55:23 »
Otro programa más.

El primer led (VERDE) se enciende y se apaga al presionar el pulsador 1.

El segundo led (ROJO) se enciende durante 10 segundos cuando se presiona el pulsador 2.

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

Adjunto grafcet del segundo led (ROJO).
 

* grafcet temporizado.png.png
(58.94 kB, 505x407 - visto 643 veces)
« Última modificación: 02 de Enero de 2020, 17:17:00 por Picuino »

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #49 en: 02 de Enero de 2020, 18:26:45 »
Otro programa más.

El primer led (VERDE) se enciende y se apaga al presionar el pulsador 1.

El segundo led (ROJO) se enciende durante 10 segundos cuando se presiona el pulsador 2.

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

Adjunto grafcet del segundo led (ROJO).
  - Tienes que ingresar para ver archivos adjuntos -

Gracias por los ejemplos  :-/ hace rato empece a analizar los otros programas y mas informacion que he ido encontrando, en un rato tratare de hacer estos que has compartido para entenderlos completamente, me intereso mucho el tema porque tambien se aplica en otras tecnologias. Muchas gracias de nuevo  :mrgreen:

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #50 en: 05 de Enero de 2020, 10:33:41 »
¿Cómo vas con el programa?
No puse en el programa la forma de hacer los cálculos. Hay que añadir una variable para que se ejecuten una sola vez.

Algo así como esto:
Código: C
  1. #define OPERACION_SIN_REALIZAR 0
  2. #define OPERACION_REALIZADA    1
  3.  
  4. // Declaración de variables
  5. unsigned char operacion1;
  6.  
  7.  
  8.  
  9. void grafcets_calcular_acciones(void) {
  10.  
  11.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1) {
  12.       if (operacion1 == OPERACION_SIN_REALIZAR) {
  13.          // Aquí se realizan los cálculos asociados a la etapa1 del grafcet del LED verde.
  14.          // Este código se ejecutará una sola vez, cada vez que se active la etapa1 del grafcet.
  15.       }
  16.       operacion1 = OPERACION_REALIZADA;
  17.    }
  18.    else  {
  19.       operacion1 = OPERACION_SIN_REALIZAR;
  20.    }
  21.  
  22.  
  23.  
  24. }
« Última modificación: 05 de Enero de 2020, 10:58:50 por Picuino »

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #51 en: 06 de Enero de 2020, 17:58:45 »
¿Cómo vas con el programa?
No puse en el programa la forma de hacer los cálculos. Hay que añadir una variable para que se ejecuten una sola vez.

Algo así como esto:
Código: C
  1. #define OPERACION_SIN_REALIZAR 0
  2. #define OPERACION_REALIZADA    1
  3.  
  4. // Declaración de variables
  5. unsigned char operacion1;
  6.  
  7.  
  8.  
  9. void grafcets_calcular_acciones(void) {
  10.  
  11.    if (grafcet[GRAFCET_LED_VERDE].etapa1 == 1) {
  12.       if (operacion1 == OPERACION_SIN_REALIZAR) {
  13.          // Aquí se realizan los cálculos asociados a la etapa1 del grafcet del LED verde.
  14.          // Este código se ejecutará una sola vez, cada vez que se active la etapa1 del grafcet.
  15.       }
  16.       operacion1 = OPERACION_REALIZADA;
  17.    }
  18.    else  {
  19.       operacion1 = OPERACION_SIN_REALIZAR;
  20.    }
  21.  
  22.  
  23.  
  24. }

Saludos, ahi voy aprendiendo, realice los ejemplos que compartiste aca en el tema, han funcionado bien. Incluso hize otros que encontre por alli en internet, tambien intente implementar eso de la concurrencia, dos grafcet al mismo tiempo, y va de maravilla.

Si me di cuenta que al hacer el de el led temporizado habia que implementar una forma para que se realizara una sola vez. Tambien utilize los timers para ayudarme con el tema del tiempo y evitar el uso de los delays (cosa que hize mucho en la maquina de churros  :oops: ) Pero bueno con la practica he ido aprendiendo como se debe aplicar correctamente el Grafcet.

Queria acotar que este libro me ayudo mucho a entender mas a fondo esta forma de trabajar por si a alguien le interesa: Automatización de Procesos Mediante la Guía GEMMA - Pere Ponsa, Ramon Vilanova - se encuentra facil en internet si alguien lo quiere, trae informacion util y ejemplos muy buenos para iniciar (cosa que me cayo perfecto  :-/)

Mas tarde en la noche seguire practicando para pulirme un poco mas, y ver si finalmente puedo hacer de nuevo la programacion de la maquina implementando correctamente los diagramas

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #52 en: 08 de Enero de 2020, 14:31:13 »
Gracias por el aporte. Es un libro interesante.

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #53 en: 14 de Enero de 2020, 22:13:24 »
Saludos, para actualizar el tema, he realizado ya el programa completo de la maquina de churros solo con grafcet (digamos que una version mas apegada a la programacion por medio de diagramas de grafcet). En la simulacion funciona muy bien, aparte de eso tendria que esperar esta semana que viene para poder probarlo en protoboard.  :lol:

He separado cada etapa del proceso en un diagrama de grafcet diferente para cada uno, asi solo tendria que "saltar" entre grafcet segun ciertas condiciones, haciendo que el programa sea mas entendible y si hay algun error en la parte fisica, si es un problema de programacion, se pueda identificar casi directamente sin empezar a buscar en cada parte del codigo, sino yendo direnctamente al grafcet y etapa correspondiente. De verdad que he aprendido mucho al trabajar de esta forma y me sera muy util para el futuro. Adjunto cada grafcet y el codigo completo por si alguien lo quiere ver y quiza dar un feedback  ;-)

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #54 en: 15 de Enero de 2020, 14:52:48 »
Me alegro de que todo vaya bien.

Por otro lado, a los grafcet les falta la transición en todas las etapas de abajo. Hay que poner una transición a otra etapa.

Fíjate en otros grafcet de ejemplo y verás que son circulares, la última etapa vuelve a enlazar con la primera.

Un saludo.

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #55 en: 24 de Enero de 2020, 12:15:33 »
Bueno, para actualizar el tema y finiquitar el area de la programacion, informo que el programa funciono en protoboard casi perfecto, un par de errores que ya fueron corregidos y funciona muy bien, sin reinicios no se queda pegado como me pasaba con el primer codigo. Definitivamente los diagramas grafcet son una herramienta muy util para este tipo de maquinas   ((:-))

Solo me falta implementar un mejor arreglo para la pt100 ya que con el divisor de tension es muy inestable y da lugar a lecturas erroneas, lo hare con un puente de wheatstone, un par de buffers y un amplificador diferencial, ya que da lecturas mucho mas exactas y facilitan la lectura de la temperatura en la programacion  :-/  , cuando este terminada la maquina colocare un video en funcionamiento  :mrgreen: pero sera un unas semanas  :oops:

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #56 en: 24 de Enero de 2020, 13:08:37 »
Enhorabuena.