Autor Tema: Ayuda | Proyecto Final problema con maquina y PIC16F877A  (Leído 16051 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 #30 en: 22 de Diciembre de 2019, 18:58:57 »
También he pensado que sería mejor tener algunos pulsadores más:
   Botón de subir extrusora
   Botón de bajar extrusora

Adjunto los 3 grafcets:

 

* grafcet01.png.png
(74.85 kB, 1275x1753 - visto 528 veces)

 

* grafcet02.png.png
(75.93 kB, 1275x1753 - visto 572 veces)

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #31 en: 22 de Diciembre de 2019, 19:33:14 »
La parada de emergencia debe parar todo. Va aparte. Se puede añadir cuando lo demás funcione.

En el display yo mantendría una línea para temperatura y otra para el estado en el que está la máquina.

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #32 en: 22 de Diciembre de 2019, 20:42:28 »
También he pensado que sería mejor tener algunos pulsadores más:
   Botón de subir extrusora
   Botón de bajar extrusora

Adjunto los 3 grafcets:

  - Tienes que ingresar para ver archivos adjuntos -
  - Tienes que ingresar para ver archivos adjuntos -

Me agrada la idea de mostrar la temperatura constantemente en la pantalla junto al estado en que este la maquina, asi me "ahorraria" un boton dedicado solo a mostrar la temperatura, pienso implementar eso.

Por otro lado, si me di cuenta que el mio se ve complicado comparado con tus diagramas  :mrgreen:  ... en tus diagramas por ejemplo en el de extrusion hay una condicion luego de la etapa 0 ( boton inicio.grafcet de reposo), a que te refieres con grafcet de reposo?

Otra duda que tengo es que no veo las condiciones por ejemplo que se deben hacer 4 rondas de dispensados  extrusiones de churros para contar un freido, ya que los freidos indican cuando se debe drenar el aceite usado. Tambien si la extrusora toca el final de carrera bajo deberia proseguir a colocar todo en su estado inicial, ya que no se podria hacer mas extrusiones.


Asi con tus diagramas ya se podria comenzar a programar? o se requiere de un diagrama mas complejo? claro todo despues que se haya entendido completamente el funcionamiento de la maquina  :D

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #33 en: 23 de Diciembre de 2019, 05:25:52 »
... en tus diagramas por ejemplo en el de extrusion hay una condicion luego de la etapa 0 ( boton inicio.grafcet de reposo), a que te refieres con grafcet de reposo?
boton inicio y resto de grafcets en reposo (en la etapa cero)

Esto es porque son grafcets independientes. De esta manera se puede drenar a la vez que se carga la extrusora (acciones a la vez o concurrentes).
Sin embargo no se puede extrudir y freir a la vez que se carga la extrusora o a la vez que se drena. Por eso hay que poner la condición de que no se esté drenando o llenando la extrusora para empezar a extrudir.

Otra duda que tengo es que no veo las condiciones por ejemplo que se deben hacer 4 rondas de dispensados  extrusiones de churros para contar un freido, ya que los freidos indican cuando se debe drenar el aceite usado. Tambien si la extrusora toca el final de carrera bajo deberia proseguir a colocar todo en su estado inicial, ya que no se podria hacer mas extrusiones.
Si, esas condiciones falta completarlas. He tenido en cuenta que la extrusora se vaciaría en mitad de la extrusión, por lo que esa ronda de churros se deja friendo y luego habría que saltar a la etapa cero y no dejar que comience la extrusión de nuevo hasta que no se llene la extrusora.

Asi con tus diagramas ya se podria comenzar a programar? o se requiere de un diagrama mas complejo? claro todo despues que se haya entendido completamente el funcionamiento de la maquina  :D
Se puede empezar a programar, sólo hace falta poner en el diagrama las entradas y salidas (grafcet de nivel III):

 

* grafcets.png
(131.09 kB, 755x319 - visto 553 veces)


Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #34 en: 23 de Diciembre de 2019, 10:58:33 »
... en tus diagramas por ejemplo en el de extrusion hay una condicion luego de la etapa 0 ( boton inicio.grafcet de reposo), a que te refieres con grafcet de reposo?
boton inicio y resto de grafcets en reposo (en la etapa cero)

Esto es porque son grafcets independientes. De esta manera se puede drenar a la vez que se carga la extrusora (acciones a la vez o concurrentes).
Sin embargo no se puede extrudir y freir a la vez que se carga la extrusora o a la vez que se drena. Por eso hay que poner la condición de que no se esté drenando o llenando la extrusora para empezar a extrudir.

Otra duda que tengo es que no veo las condiciones por ejemplo que se deben hacer 4 rondas de dispensados  extrusiones de churros para contar un freido, ya que los freidos indican cuando se debe drenar el aceite usado. Tambien si la extrusora toca el final de carrera bajo deberia proseguir a colocar todo en su estado inicial, ya que no se podria hacer mas extrusiones.
Si, esas condiciones falta completarlas. He tenido en cuenta que la extrusora se vaciaría en mitad de la extrusión, por lo que esa ronda de churros se deja friendo y luego habría que saltar a la etapa cero y no dejar que comience la extrusión de nuevo hasta que no se llene la extrusora.

Asi con tus diagramas ya se podria comenzar a programar? o se requiere de un diagrama mas complejo? claro todo despues que se haya entendido completamente el funcionamiento de la maquina  :D
Se puede empezar a programar, sólo hace falta poner en el diagrama las entradas y salidas (grafcet de nivel III):

  - Tienes que ingresar para ver archivos adjuntos -

Ahhhh ahora si me quedo un poco mas claro esas condiciones del principio de cada grafcet (luego de la etapa 0), ahora mi duda es como se plasman esas concurrencias, me siento ciego con respecto a esto, tendras por alli algun programa de ejemplo? para echarle un vistazo de como se ve, porque he buscado en internet ejemplos de programas en C a partir de Grafcet y solo encuentro de grafcet a ladder o asm.


Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #36 en: 23 de Diciembre de 2019, 15:03:55 »
Cuando tenga tiempo pondré algo más.

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #37 en: 23 de Diciembre de 2019, 17:44:53 »
Cuando tenga tiempo pondré algo más.

Perfecto, muchas gracias amigo. Por lo pronto ire leyendo y analizando el link anterior  :mrgreen:

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #38 en: 23 de Diciembre de 2019, 19:00:07 »
Debería ser algo así:

Código: C
  1. typedef union  {
  2.   struct {
  3.     unsigned char estado0: 1;
  4.     unsigned char estado1: 1;
  5.     unsigned char estado2: 1;
  6.     unsigned char estado3: 1;
  7.     unsigned char estado4: 1;
  8.     unsigned char estado5: 1;
  9.     unsigned char estado6: 1;
  10.     unsigned char estado7: 1;
  11.   };
  12.   unsigned char estados;
  13. } tipo_grafcet;
  14.  
  15. tipo_grafcet grafcet[3], grafcet_siguiente[3];
  16.  
  17. unsigned char entradas[6], salidas[6];
  18.  
  19. main() {
  20.    grafcet_inicializar();
  21.  
  22.    while(1) {
  23.       leer_entradas();
  24.       grafcets();
  25.       escribir_salidas();
  26.       otros_controles();    
  27.    }
  28. }
  29.  
  30. leer_entradas() {
  31.    entrada[BOTON_INICIO] = read(PIN1);
  32.    ...
  33. }
  34.  
  35. escribir_salidas() {
  36.    write(PIN3, salidas[VALVULA_DRENAJE]);
  37.    ...
  38. }
  39.  
  40. grafcet_inicializar() {
  41.    grafcet_siguiente[0].estados = 0;
  42.    grafcet_siguiente[0].estado0 = 1;
  43. }
  44.  
  45.  
  46. grafcets() {
  47.    grafcets_copiar_transiciones();
  48.    grafcets_calcular_transiciones();
  49.    grafcets_calcular_acciones();
  50. }
  51.  
  52. grafcets_copiar_transiciones() {
  53.    grafcet[0].estados = grafcet_siguiente[0].estados;
  54.    grafcet[1].estados = ...
  55. }
  56.  
  57.  
  58. grafcets_calcular_transiciones() {
  59.    if (grafcet[0].estado0 && pulsador_inicio() && otras_condiciones()) {
  60.       grafcet_siguiente[0].estado0 = 0;
  61.       grafcet_siguiente[0].estado1 = 1;
  62.    }
  63.  
  64.    if (...)
  65. }
  66.  
  67. grafcets_calcular_acciones() {
  68.    if (grafcet[0].estado4 == 1) {
  69.       salidas[MOTOR_EXTRUSION] = 1;
  70.    }
  71.  
  72.    if (...)
  73.  
  74. }

Creo que por ahora tienes bastante.
« Última modificación: 23 de Diciembre de 2019, 19:04:19 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #39 en: 24 de Diciembre de 2019, 05:20:20 »
Voy a limpiar un poco el código para cambiar los números por constantes que tengan un nombre.

Código: C
  1. #define  NUMERO_DE_GRAFCETS   3
  2. #define  NUMERO_DE_ENTRADAS   6
  3. #define  NUMERO_DE_SALIDAS   8
  4.  
  5. enum NOMBRE_GRAFCETS {
  6.         EXTRUSION,
  7.         LLENADO,
  8.         DRENAJE };
  9.  
  10. enum ENTRADAS_FISICAS {
  11.         BOTON_INICIO,
  12.         BOTON_PARADA,
  13.         ... };
  14.  
  15. enum SALIDAS_FISICAS {
  16.         VALVULA_DRENAJE,
  17.         ... };
  18.  
  19. typedef union  {
  20.   struct {
  21.     unsigned char etapa0: 1;
  22.     unsigned char etapa1: 1;
  23.     unsigned char etapa2: 1;
  24.     unsigned char etapa3: 1;
  25.     unsigned char etapa4: 1;
  26.     unsigned char etapa5: 1;
  27.     unsigned char etapa6: 1;
  28.     unsigned char etapa7: 1;
  29.   };
  30.   unsigned char etapas;
  31. } tipo_grafcet;
  32.  
  33. tipo_grafcet grafcet[NUMERO_DE_GRAFCETS], grafcet_siguiente[NUMERO_DE_GRAFCETS];
  34.  
  35. unsigned char entradas[NUMERO_DE_ENTRADAS], salidas[NUMERO_DE_SALIDAS];
  36.  
  37. main() {
  38.    grafcet_inicializar();
  39.  
  40.    while(1) {
  41.       leer_entradas();
  42.       grafcets();
  43.       escribir_salidas();
  44.       otros_controles();
  45.    }
  46. }
  47.  
  48. leer_entradas() {
  49.    entrada[BOTON_INICIO] = read(PIN1);
  50.    ...
  51. }
  52.  
  53. escribir_salidas() {
  54.    write(PIN3, salidas[VALVULA_DRENAJE]);
  55.    ...
  56. }
  57.  
  58. grafcet_inicializar() {
  59.    grafcet_siguiente[EXTRUSION].etapas = 0;
  60.    grafcet_siguiente[EXTRUSION].etapa0 = 1;
  61. }
  62.  
  63.  
  64. grafcets() {
  65.    grafcets_copiar_transiciones();
  66.    grafcets_calcular_transiciones();
  67.    grafcets_calcular_acciones();
  68. }
  69.  
  70.  
  71. grafcets_copiar_transiciones() {
  72.    grafcet[EXTRUSION].etapas = grafcet_siguiente[EXTRUSION].etapas;
  73.    grafcet[LLENADO].etapas = ...
  74. }
  75.  
  76.  
  77. grafcets_calcular_transiciones() {
  78.    if (grafcet[EXTRUSION].etapa0 && pulsador_inicio() && otras_condiciones()) {
  79.       grafcet_siguiente[EXTRUSION].etapa0 = 0;
  80.       grafcet_siguiente[EXTRUSION].etapa1 = 1;
  81.    }
  82.  
  83.    if (...)
  84. }
  85.  
  86. grafcets_calcular_acciones() {
  87.    if (grafcet[EXTRUSION].etapa4 == 1) {
  88.       salidas[MOTOR_EXTRUSION] = 1;
  89.    }
  90.  
  91.    if (...)
  92.  
  93. }

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #40 en: 26 de Diciembre de 2019, 07:04:14 »
Hola hurtadoluisalex. Imagino que necesitas ayuda... No dudes en pedirla.

Un saludo.

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #41 en: 26 de Diciembre de 2019, 14:32:57 »
Hola hurtadoluisalex. Imagino que necesitas ayuda... No dudes en pedirla.

Un saludo.

Hola, muchas gracias por los ejemplos y todo lo que me has ayudado. Estos ultimos dos dias no he podido trabajar en el tema porque estaba ocupado con lo de las fiestas de esta epoca... a partir de mañana empezare a trabajar con todas las guias que me facilitaste, no dudare en pedir ayuda cualquier cosa  :-/  gracias de nuevo

Desconectado hurtadoluisalex

  • PIC10
  • *
  • Mensajes: 24
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #42 en: 30 de Diciembre de 2019, 23:35:51 »
Código: C
  1. void setup(void) {
  2.    output_A(0); //Configuracion de puertos
  3.    ...
  4. }
  5.  
  6.  
  7. void lcd_mensajes() {
  8.    lcd_putc("\f   BIENVENIDO   "); //pantallas de bienvenida
  9.    ...
  10. }
  11.  
  12. void main() {
  13.  
  14.    int estado_mecan = 1;
  15.  
  16.    setup();
  17.  
  18.    lcd_mensajes();
  19.  
  20.    // Bucle principal
  21.    while(1) {
  22.  
  23.       // Control de temperatura
  24.       T = sonda_temperatura_read();
  25.       if (T < 200) {
  26.          calefactor_on();
  27.       }
  28.       else {
  29.          calefactor_off();
  30.       }
  31.  
  32.       // Lectura de entradas
  33.       push_button_1 = read_pushbutton(1);
  34.       ...
  35.  
  36.       // Transiciones de la máquina de estados
  37.       if (estado_mecan == 1  && condición1) {
  38.          estado_mecan = 2;
  39.       }
  40.       ...
  41.  
  42.  
  43.       // Escritura de salidas
  44.       if (estado_mecan == 1)   salida1();
  45.       if (estado_mecan == 2)   salida2();
  46.       ...
  47.    }
  48.  
  49. }

Saludos, bueno por aca nuevamente para revivir el tema ya que he tenido cierto progreso con esto de los diagramas grafcet y su forma de implementarlos, hoy por fin tuve tiempo de terminar el programa utilizando el diagrama y ayudandome con el link que publicaste,  https://web.archive.org/web/20110905182033/http://edison.upc.edu/curs/grafcet/implem/general.html , tambien ayudandome de otras publicaciones aca del foro que consegui y un video de youtube donde explican un poco como usar grafcet con lenguaje c. Bueno en fin, he tratado de hacer lo mejor posible, sinceramente el nuevo programa se parece a algo como el codigo citado ya que, siendo honesto no entendi mucho como implementar varios grafcet en un solo codigo, supongo que me hace falta practica pero como no he tenido mucho tiempo aun no he podido entrar de lleno a todo el contenido de esta metodologia de grafcet, pero bueno lo importante es que pude comenzar con algo y ciertamente es mas eficiente y sencillo de entender trabajar de esta forma que como lo venia haciendo anteriormente :-/

Me gustaria que le pudieras echar un vistazo @Picuino , si no es mucha molestia claro esta  :oops: , aun me falta agregarle cosas como el boton de parada de emergencia, tambien queria acotar que he "eliminado" el boton para ver la temperatura y decidi mostrarla a un lado en la pantalla en cada etapa de proceso, asi siempre sera visible para el operador. Bueno procedo a adjuntar el nuevo codigo y el diagrama de grafcet de nivel III , el I y II los perdi por problemas en la red electrica que hicieron que mi computadora se apagara sin previo aviso, el diagrama es algo parecido al primer diagrama que publique solo que con algunas modificaciones y siendo mas detallado.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #43 en: 31 de Diciembre de 2019, 10:14:42 »
Copio tu programa para que se pueda ver:

Código: C
  1. #include <16F877A.h>
  2. #device ADC=10
  3. #fuses XT          //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
  4. #fuses NOWDT       //No Watch Dog Timer
  5. #fuses NOPUT       //No Power Up Timer
  6. #fuses NOBROWNOUT  //No brownout reset
  7. #fuses NOLVP       //No low voltage prgming, B3(PIC16) or B5(PIC18) used FOR I/O
  8. #fuses NOCPD       //No EE protection
  9. #fuses NOWRT       //Program memory not write protected
  10. #fuses NODEBUG     //No Debug mode FOR ICD
  11. #fuses NOPROTECT   //Code not protected from reading
  12. #use delay(crystal=4000000)
  13. #include <lcd.c>
  14. #include <math.h>
  15. #use standard_io(A)
  16. #use standard_io(B)
  17. #use standard_io(C)
  18. #use standard_io(D)
  19. #use standard_io(E)
  20.  
  21. int8 Y[10]; //Vector Y[] por lo tanto cuando la etapa 4 esté activa, lo estará Y[4].
  22. int8 Re[14]; //Vector Re[] por tanto cuando la transición 3 tenga cierta su receptividad, estará activo Re[3].
  23. int8 Va[14]; //El vector Va tendrá sus componentes activas cuando las transiciones que les correspondan estén validadas.
  24. //int8 Tiempo[]; //El vector T contiene el tiempo transcurrido desde la última activación de cada una de las etapas.
  25. //int8 I[]; //Los vectores I y Q contienen las entradas (I) y salidas (Q) físicas
  26. //int8 Q[]; //
  27. //int8 E[]; //Los vectores E y S guardan los estados de las entradas (E) y salidas (S) hasta que se acaba un ciclo.
  28. //int8 S[]; //
  29. int8 freidos=0,dispensados=0,listo;
  30. int16 X,desbordes0=0;                            
  31. float32 T,V,R,discriminante;
  32. float32 A=0.0039083;
  33. float32 B=-0.000000577;
  34. //*****************************************************************************
  35. //Funciones auxiliares*********************************************************
  36. void posicion_inicial(){ //funcion para posicionar los mecanismos de dispensado y extraccion
  37.    setup_timer_2(T2_DIV_BY_16,155,1); //seleccion de la frecuencia para PWM  *********OJO*********  aqui se modifica la velocidad de los motores pap
  38.    setup_ccp1(CCP_PWM);
  39.    set_pwm1_duty(64);
  40.    output_low(PIN_E0); //habilita el motor de dispensado
  41.    output_high(PIN_E1); //deshabilita el motor de corte
  42.    output_high(PIN_E2); //deshabilita el motor de extraccion
  43.    output_low(PIN_A4); //gira contrario al las agujas de reloj
  44.    while(input(PIN_C0)==0){ //mover el motor de dispensado hasta la posicion inicial            
  45.    }
  46.    output_high(PIN_E0); //una vez que toca el final de carrera superior el motor de dispensado se deshabilita
  47.    output_high(PIN_E1); //deshabilita el motor de corte
  48.    output_low(PIN_E2); //habilita el motor de extraccion
  49.    output_high(PIN_A5); //gira con las agujas de reloj
  50.    while(input(PIN_C7)==0){ //mover el motor de extraccion hasta la posicion inicial
  51.    }
  52.    output_high(PIN_E2); //una vez que toca el final de carrera inferior el motor de extraccion se deshabilita
  53.    set_pwm1_duty(0);
  54.    setup_ccp1(CCP_OFF);
  55. }
  56. //*****************************************************************************
  57. void lectura_pt100(){ //funcion para leer el valor de resistencia de la PT100 y activar o desactivar la resistencia de coccion
  58.     X=read_adc();
  59.     V=(X*(0.0048828125));
  60.     R=((150*V)/(5-V));
  61.     discriminante=(((100*A)*(100*A))-(4*100*B*(100-R)));
  62.     discriminante=sqrt(discriminante);    
  63.     T=(((-100*A)+discriminante)/(2*100*B));
  64.     if(T<200){
  65.        output_high(PIN_B1);      
  66.     }else{
  67.        output_low(PIN_B1);
  68.     }
  69. }
  70. //*****************************************************************************
  71. void setup(){ //configuracion de puertos, ADC y LCD
  72.     output_A(0); //Configuracion de puertos
  73.     input(PIN_A0);
  74.     output_B(0);
  75.     output_C(0);
  76.     output_D(0);
  77.     output_E(0);
  78.     delay_ms(10);
  79.     lcd_init(); //inicializacion de la LCD
  80.     SETUP_ADC(ADC_CLOCK_DIV_32); //configuracion del ADC
  81.     SETUP_ADC_PORTS(AN0);
  82.     SET_ADC_CHANNEL (0);
  83.     delay_us(50);
  84. }
  85. //*****************************************************************************
  86. void pantalla_bienvenida(){ //muestra la bienvenida y las instrucciones
  87.    lcd_putc("\f   BIENVENIDO   "); //pantallas de bienvenida
  88.       delay_ms(2000);
  89.       lcd_putc("\f   MAQUINA DE   \n    CHURROS     ");
  90.       delay_ms(2000);
  91.       lcd_putc("\fINSTRUCCIONES");
  92.       delay_ms(2000);
  93.       lcd_putc("\fPRESIONE 1 O 2\nPARA SELECCION");
  94.       delay_ms(2000);
  95. }
  96. //*****************************************************************************
  97. void lectura_T(){ //funcion para leer el valor de resistencia de la PT100 y temperatura
  98.    X=read_adc();
  99.    V=(X*(0.0048828125));
  100.    R=((150*V)/(5-V));
  101.    discriminante=(((100*A)*(100*A))-(4*100*B*(100-R)));
  102.    discriminante=sqrt(discriminante);    
  103.    T=(((-100*A)+discriminante)/(2*100*B));
  104. }
  105. //*****************************************************************************
  106. void activar_dispensar(){ //habilita el proceso de dispensado y corte de churros
  107.    printf(lcd_putc,"\fDISPENSANDO\nCHURROS    T:%3.0lf %cC",T,223);
  108.    delay_ms(10);
  109.    output_low(PIN_E0); //habilita el motor de dispensado
  110.    output_low(PIN_E1); //habilita el motor de corte
  111.    output_high(PIN_E2); //deshabilita el motor de extraccion
  112.    output_high(PIN_A4); //gira con las agujas de reloj
  113.    setup_timer_2(T2_DIV_BY_16,155,1); //seleccion de la frecuencia para PWM  *********OJO*********  aqui se modifica la velocidad de los motores pap
  114.    setup_ccp1(CCP_PWM);
  115.    set_pwm1_duty(64);
  116.    setup_ccp2(CCP_PWM);
  117.    set_pwm2_duty(64);
  118.    while((input(PIN_C5)==0)&&(desbordes0<1000)){ //mover el motor de dispensado hasta el 25% por tiempo, y verifica si se toco el final de carrera bajo (seguridad)
  119.       delay_ms(1);
  120.       lectura_pt100();
  121.       desbordes0++;        
  122.    }
  123.    desbordes0=0;  
  124. }
  125. //*****************************************************************************
  126. void desactivar_dispensar(){ //deshabilita el proceso de dispensado y corte de churros
  127.    output_high(PIN_E0); //una vez que toca el final de carrera superior el motor de dispensado se deshabilita
  128.    output_high(PIN_E1); //una vez que toca el final de carrera superior el motor de corte se deshabilita
  129.    setup_ccp1(CCP_OFF);
  130.    setup_ccp2(CCP_OFF);
  131. }
  132. //*****************************************************************************
  133. void freir_churros(){ //activa el proceso de freido de churros, haciendo lecturas constantes de la temperatura
  134.    printf(lcd_putc,"\fFRIENDO\nESPERE     T:%3.0lf %cC",T,223);                  
  135.    while(desbordes0<10000){ //espera de t para que los churros se cocinen correctamente
  136.       delay_ms(1);
  137.       lectura_pt100();
  138.       desbordes0++;
  139.    }
  140.    desbordes0=0;
  141. }
  142. //*****************************************************************************
  143. void extraer_churros(){ //proceso de extraccion de churros
  144.    output_high(PIN_E0); //deshabilita el motor de dispensado
  145.    output_high(PIN_E1); //deshabilita el motor de corte
  146.    output_low(PIN_E2); //habilita el motor de extraccion
  147.    output_low(PIN_A5); //gira con las contrario a las agujas de reloj
  148.    setup_timer_2(T2_DIV_BY_16,155,1); //seleccion de la frecuencia para PWM  *********OJO*********  aqui se modifica la velocidad de los motores pap
  149.    setup_ccp1(CCP_PWM);
  150.    set_pwm1_duty(64);            
  151.    printf(lcd_putc,"\fEXTRAYENDO\nCHURROS    T:%3.0lf %cC",T,223);
  152.    while(input(PIN_C6)==0){ //mover el motor de extraccion hasta arriba, y verifica si se toco el final de carrera superior
  153.    }
  154.    output_high(PIN_E2); //una vez que toca el final de carrera superior el motor de extraccion se deshabilita
  155.    setup_ccp1(CCP_OFF);
  156.    lcd_putc("\fPOR FAVOR RETIRE\n  Y PRESIONE 1  ");
  157.    while(input(PIN_C3)==0){
  158.    }
  159.    lcd_putc("\f   PREPARANDO   \nSIGUIENTE RONDA");
  160.    output_high(PIN_E0); //deshabilita el motor de dispensado
  161.    output_high(PIN_E1); //deshabilita el motor de corte
  162.    output_low(PIN_E2); //habilita el motor de extraccion
  163.    output_high(PIN_A5); //gira con las agujas de reloj
  164.    setup_ccp1(CCP_PWM);
  165.    set_pwm1_duty(64);
  166.    while(input(PIN_C7)==0){ //mover el motor de extraccion hasta abajo, y verifica si se toco el final de carrera inferior
  167.    }
  168.    output_high(PIN_E2); //una vez que toca el final de carrera inferior el motor de dispensado se deshabilita
  169.    setup_ccp1(CCP_OFF);
  170.    dispensados++;
  171. }
  172. //*****************************************************************************
  173.  
  174. void main(){
  175.       setup();
  176.       pantalla_bienvenida();
  177.       lcd_putc("\f1-INICIAR");
  178.       delay_ms(10);
  179.       while(input(PIN_C3)==0){ //pregunta si se quiere iniciar  
  180.       }
  181.       while(T<200){ //se enciende la resistencia hasta alcanzar los 200°C
  182.          lectura_pt100();
  183.          printf(lcd_putc,"\f   CALENTANDO   \n    T:%3.1lf %cC    ",T,223);
  184.          delay_ms(1000);
  185.       }
  186.       //ENABLE_INTERRUPTS (INT_RB);
  187.       //ENABLE_INTERRUPTS (GLOBAL); //se habilitan las interrupciones globales
  188.       lectura_pt100();
  189.       printf(lcd_putc,"\fPOSICIONANDO\nMECANISMOS T:%3.0lf %cC",T,223);
  190.       posicion_inicial();
  191.       printf(lcd_putc,"\fLISTO...\n           T:%3.0lf %cC",T,223);
  192.       delay_ms(2000);
  193.       lectura_pt100();
  194.       printf(lcd_putc,"\f   TEMPERATURA  \n    T:%3.1lf %cC    ",T,223);
  195.       delay_ms(2000);
  196.       lcd_putc("\f  SELECCION DE  \n      MODO      "); //seleccion del modo de trabajo
  197.       delay_ms(2000);
  198.       dispensados=0;
  199.       //**********************Inicializacion de grafcet
  200.       Y[0]=1;
  201.       Y[1]=0;
  202.       Y[2]=0;
  203.       Y[3]=0;
  204.       Y[4]=0;
  205.       Y[5]=0;
  206.       Y[6]=0;
  207.       Y[7]=0;
  208.       Y[8]=0;
  209.       Y[9]=0;
  210.      
  211.       //**********************Programa principal
  212.       while(1){ //El ciclo de programa se debe repetir indefinidamente.
  213.          Va[0]=Y[0]; //Ahora vamos a validar las transiciones. Una transición es válida cuando todas las etapas inmediatamente anteriores son activas.
  214.          Va[1]=Y[0];
  215.          Va[2]=Y[0];
  216.          Va[3]=Y[1];
  217.          Va[4]=Y[2];
  218.          Va[5]=Y[5];
  219.          Va[6]=Y[3];
  220.          Va[7]=Y[3];
  221.          Va[8]=Y[6];
  222.          Va[9]=Y[9];
  223.          Va[10]=Y[4];
  224.          Va[11]=Y[7];
  225.          Va[12]=Y[7];
  226.          Va[13]=Y[8];
  227.          //****************************************************************************************************************
  228.          //Después programaremos las acciones asociadas a las etapas.
  229.          if(Y[0]==1){ //Reposo
  230.             printf(lcd_putc,"\f1-FREIDO\n2-DRENAJE  T:%3.0lf %cC",T,223); //freido o drenaje
  231.             lectura_pt100();
  232.             listo=0;
  233.          }
  234.          if(Y[1]==1){ //Recomendacion de drenaje
  235.             lcd_putc("\fSE RECOMIENDA\nDRENAR ACEITE");
  236.                delay_ms(2000);
  237.             listo=1;
  238.          }
  239.          if(Y[2]==1){ //Llenado de extrusora
  240.             printf(lcd_putc,"\fMODO FREIDO\n           T:%3.0lf %cC",T,223);
  241.                delay_ms(2000);
  242.                printf(lcd_putc,"\fINSERTE MASA DE\nCHURROS    T:%3.0lf %cC",T,223);
  243.                delay_ms(2000);
  244.                lcd_putc("\fPRESIONE 1 PARA\nINICIAR PROCESO"); //espera a que el usuario presione 1 para iniciar el proceso
  245.                lectura_pt100();
  246.                while(input(PIN_C3)==0){
  247.                }
  248.          }
  249.          if(Y[3]==1){ //Dispensado
  250.             activar_dispensar();                  
  251.                desactivar_dispensar();
  252.          }
  253.          if(Y[4]==1){ //Freido
  254.             freir_churros();            
  255.          }
  256.          if(Y[5]==1){ //Enfriado de aceite
  257.             output_low(PIN_B1);
  258.                printf(lcd_putc,"\fMODO DRENAJE\n           T:%3.0lf %cC",T,223);
  259.                delay_ms(2000);
  260.                lcd_putc("\fENFRIANDO ACEITE");
  261.                delay_ms(2000);
  262.                while(T>50){ //se apaga la resistencia hasta alcanzar los 50°C, para proceder a drenar el aceite
  263.                   lectura_T();
  264.                    printf(lcd_putc,"\f   ENFRIANDO   \n    T:%3.1lf %cC    ",T,223);
  265.                    delay_ms(1000);
  266.                }
  267.          }
  268.          if(Y[6]==1){ //Drenaje de aceite
  269.             printf(lcd_putc,"\fDRENANDO ACEITE\n           T:%3.0lf %cC",T,223);
  270.             delay_ms(2000);
  271.             output_high(PIN_B2); //enciende valvula de drenaje
  272.             delay_ms(10000); //tiempo de activacion de valvula de drenaje
  273.             output_low(PIN_B2); //apaga valvula de drenaje
  274.             freidos=0;
  275.             printf(lcd_putc,"\f   SIN ACEITE   \n           T:%3.0lf %cC",T,223);
  276.             delay_ms(2000);
  277.             listo=1;
  278.          }
  279.          if(Y[7]==1){ //Extraccion
  280.             extraer_churros();
  281.          }
  282.          if(Y[8]==1){ //Tanda de churros lista
  283.             lectura_pt100();
  284.                dispensados=0;
  285.                printf(lcd_putc,"\fTANDA DE CHURROS\nLISTA   T:%3.0lf %cC",T,223);
  286.                delay_ms(2000);
  287.                lcd_putc("\fPOSICIONANDO\nMECANISMOS");
  288.                posicion_inicial();
  289.                freidos++;
  290.          }
  291.          if(Y[9]==1){ //Freido y extraccion de emergencia
  292.             freir_churros();
  293.                extraer_churros();
  294.          }
  295.          //****************************************************************************************************************
  296.          Re[0]=((input(PIN_C3)==1)&&(input(PIN_C4)==0)&&(input(PIN_B7)==0)&&(freidos>=3)); //Continuamos con las condiciones de transición.
  297.          Re[1]=((input(PIN_C3)==1)&&(input(PIN_C4)==0)&&(input(PIN_B7)==0)&&(freidos<3));
  298.          Re[2]=((input(PIN_C3)==0)&&(input(PIN_C4)==1)&&(input(PIN_B7)==0));
  299.          Re[3]=(Listo==1);
  300.          Re[4]=((input(PIN_C3)==1));
  301.          Re[5]=(T<=50);
  302.          Re[6]=((input_state(PIN_E0)==1)&&(input_state(PIN_E1)==1)&&(input(PIN_C5)==1));
  303.          Re[7]=((input_state(PIN_E0)==1)&&(input_state(PIN_E1)==1)&&(input(PIN_C5)==0));
  304.          Re[8]=(Listo==1);
  305.          Re[9]=(input_state(PIN_E2)==1);
  306.          Re[10]=(desbordes0==0);
  307.          Re[11]=((input_state(PIN_E2)==1)&&(dispensados>=4));
  308.          Re[12]=((input_state(PIN_E2)==1)&&(dispensados<4));
  309.          Re[13]=((input_state(PIN_E2)==1));
  310.          //****************************************************************************************************************
  311.          if ((Re[0]*Va[0])||(Re[1]*Va[1])||(Re[2]*Va[2])){Y[0]=0;} //Seguidamente programamos las desactivaciones de etapas. Cuando una transición es válida y la receptividad correspondiente es cierta se deben desactivar todas las etapas precedentes.
  312.          if ((Re[3]*Va[3])){Y[1]=0;}
  313.          if ((Re[4]*Va[4])){Y[2]=0;}
  314.          if ((Re[6]*Va[6])||(Re[7]*Va[7])){Y[3]=0;}
  315.          if ((Re[10]*Va[10])){Y[4]=0;}
  316.          if ((Re[5]*Va[5])){Y[5]=0;}
  317.          if ((Re[8]*Va[8])){Y[6]=0;}
  318.          if ((Re[12]*Va[12])||(Re[11]*Va[11])){Y[7]=0;}
  319.          if ((Re[13]*Va[13])){Y[8]=0;}
  320.          if ((Re[9]*Va[9])){Y[9]=0;}
  321.          //****************************************************************************************************************
  322.          if ((Re[13]*Va[13])||(Re[3]*Va[3])||(Re[8]*Va[8])){Y[0]=1;} //Y, a continuación, las activaciones. Cuando una transición es válida y la receptividad es cierta se deben activar todas las etapas posteriores.
  323.          if ((Re[0]*Va[0])){Y[1]=1;}
  324.          if ((Re[1]*Va[1])){Y[2]=1;}
  325.          if ((Re[4]*Va[4])||(Re[12]*Va[12])){Y[3]=1;}
  326.          if ((Re[7]*Va[7])){Y[4]=1;}
  327.          if ((Re[2]*Va[2])){Y[5]=1;}
  328.          if ((Re[5]*Va[5])){Y[6]=1;}
  329.          if ((Re[10]*Va[10])){Y[7]=1;}
  330.          if ((Re[11]*Va[11])||(Re[9]*Va[9])){Y[8]=1;}
  331.          if ((Re[6]*Va[6])){Y[9]=1;}
  332.          //****************************************************************************************************************
  333.  
  334.          
  335.              
  336.      }
  337.      
  338.  
  339. }

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5892
    • Picuino
Re:Ayuda | Proyecto Final problema con maquina y PIC16F877A
« Respuesta #44 en: 31 de Diciembre de 2019, 10:31:19 »
... siendo honesto no entendi mucho como implementar varios grafcet en un solo codigo,

Es sencillo. Solo tienes que programar las transiciones y las salidas del segundo grafcet después de las del primero y ya está.




Una cosa que falta es programar los temporizadores para que no bloqueen el programa. En este tipo de programa no se puede poner un delay porque se para todo lo demás.

Tienes que comenzar por hacer una rutina de interrupción que cuente milisegundos en una variable que se llame por ejemplo "milisegundos".
Luego tienes que contar los milisegundos de 100 en 100 para actualizar otra variable que se llame decisegundos.

Hay varias formas de programar los temporizadores. Adjunto una como ejemplo.


Código: C
  1. unsigned int decisegundos;  // Décimas de segundo. Actualizado por interrupciones
  2.  
  3.  
  4. typedef struct {
  5.    unsigned int contador;
  6.    unsigned char estado;
  7. } tipo_temporizador;
  8.  
  9. #define TEMPORIZADOR_REPOSO      0
  10. #define TEMPORIZADOR_CONTANDO  1
  11. #define TEMPORIZADOR_TERMINADO 2
  12. #define TEMPORIZADOR_UN_MINUTO  600
  13.  
  14. tipo_temporizador temp1, temp2;
  15.  
  16.  
  17. // Inicialización de temporizador. Reset inicial al comenzar el programa.
  18.    temp1.estado = TEMPORIZADOR_REPOSO;
  19.  
  20.  
  21. // Inicio de cuenta de tiempo. Se debe programar cuando se encuentre en el estado correspondiente
  22.    if (temp1.estado == TEMPORIZADOR_REPOSO) {
  23.       temp1.contador = decisegundos + TEMPORIZADOR_UN_MINUTO;
  24.       temp1.estado = TEMPORIZADOR_CONTANDO;
  25.    }
  26.  
  27.  
  28. // Comprobación de que el contador ha llegado al final de la cuenta
  29.  
  30.    if ((decisegundos - temp1.contador) < TEMPORIZADOR_UN_MINUTO) {
  31.       temp1.estado = TEMPORIZADOR_TERMINADO;
  32.    }
  33.  
  34.  
  35. // En la transición donde se utilice el temporizador o en otro estado, es necesario resetear de nuevo el temporizador
  36.    temp1.estado = TEMPORIZADOR_REPOSO;
« Última modificación: 31 de Diciembre de 2019, 10:36:45 por Picuino »