Autor Tema: Hagamos un PLC con PIC!!  (Leído 103182 veces)

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

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Hagamos un PLC con PIC!!
« Respuesta #150 en: 06 de Noviembre de 2009, 22:38:44 »
Hola Claudio!!
Como no va a interesar!!
Tambien en mi caso mis ocupaciones y limitaciones personales me llevaron a dormir el tema, que como dice el titulo, era para hacerlo entre todos, pero no hubo gran quorum, parece que muchos prefieren tener un PLC comprado que hacerlo como proyecto en las escuelas... :oops: :oops:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Hagamos un PLC con PIC!!
« Respuesta #151 en: 07 de Noviembre de 2009, 01:03:54 »
Los Siemens, por lo menos los S7-200, también están compuestos por dos PCBs en donde la inferior es la de potencia (trafo, fuente de 24V y reles de salida ) y la superior tiene la lógica más comunicaciones.  En la de lógica tiene los optoacopladores de entrada, leds de visualización, etc. Cuando pueda le saco fotos y las subo.

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #152 en: 10 de Noviembre de 2009, 23:10:51 »
Hola a todos,
Les voy a comentar paso a paso lo que tengo desarrollado hasta el momento, es un PLC de 8 entradas y 8 salidas.
El hardware por el momento es, un PIC16F873 con cristal de 4 Mhz y otro de 32 Khz para implementar un reloj de tiempo real (RTC), conectado a una memoria serial I2C 24LC64 y un MAX232 para comunicarse con la PC.

Adjunto el diagrama esquematico y el programa completo que tengo hasta el momento.

El programa del PLC se divide en dos, un SISTEMA OPERATIVO que se encarga del control de las entradas/salidas, de los temporizadores, contadores y de las comunicaciones, tanto con la PC como con la memoria I2C, y el PROGRAMA DE USUARIO que es el que debe ejecutar el PLC. El SISTEMA OPERATIVO se encuentra grabado en el PIC, pero el PROGRAMA DE USUARIO está grabado en la memoria I2C externa. Elegi esto porque me permite expandir o aumentar el tamaño del programa de usuario por encima del tamaño de la memoria de programa del PIC. En futuras versiones pienso implementarlo en una o varias memorias RAM, debido a que son mas rápidas que las seriales. Sin embargo como prueba de concepto funciona perfectamente.

La idea era soportar la mayor cantidad posible de lenguajes de programación estándar IEC 61131, pero el desarrollo del software es todo un desafio en sí mismo. Volveremos sobre este tema luego. Por el momento se programa solo con Lista de Instrucciones desde un archivo de texto. Por comodidad utilize la nomenclatura de los PLCs Allen Bradley, pero por compatibilidad deberian ser como dice el estandar IEC-61131.

Ejemplo 1

LD  I0, 0   //Leer la entrada 0 del puerto I0 y ponerla en el acumulador.
AND I0, 1   //"Y logica" con la entrada 1 del puerto I0 y ponerla en el acumulador.
OTE Q0, 0   //Copiar el acumulador en la salida 0 del puerto Q0

Ejemplo 2

LD  I0, 0   //Leer la entrada 0 del puerto I0 y ponerla en el acumulador.
OR  I0, 1   //"O logica" con la entrada 1 del puerto I0 y ponerla en el acumulador.
OTE Q0, 0   //Copiar el acumulador en la salida 0 del puerto Q0

Como ven se trata de emular un automata con ACUMULADOR y PILA, muy parecido al funcionamiento interno del PIC, pero utilizando registros en la RAM. Ciertamente se trata de convertir al PIC en un microprocesador para permitir almacenar los programas fuera de el. Esta técnica es similar a la que utilizan los BASIC STAMP, transformando al PIC en un intérprete.
La ventaja obvia es que no se necesita reprogramar al pic, la desventaja es que las instrucciones se ejecutan de forma mas lenta. Seria muy bueno poder combinar ambas funciones compilando directamente el codigo de usuario y el sistema operativo y grabarlo en el pic (este era el deseo original de Hexapodo y MGLSOFT).

El ciclo de trabajo del PLC es:

1-Leer las entradas y actualizar las imagenes de las entradas en RAM.
2-Leer la siguiente instruccion del programa de usuario.
3-Decodificar las intruccion y ver si se necesitan leer mas parámetros de la memoria I2C.
3-Ejectuar la instruccion.
4-Si se llego a la ultima instruccion, actualizar las salidas y volver al paso 1, sino volver al paso 2.

Tratando de utilizar subrutinas para cada parte del programa, esta parte se implemento asi en el programa del PIC, que está hecho en assembler.

;**************************************************************************
;Rutina principal del PIC.
;**************************************************************************
Inicio
   call   LeerEntradas      ;Actualizar las imagenes de entrada.
Next_Inst   
   call   LeerInstruc      ;Leer la siguiente instruccion de la memoria eeprom.
   call   DecoInstruc      ;Decodificar la instruccion, de ser necesario leer mas datos de la memoria.
   call   EjecInstruc      ;Ejecutar la instruccion.
   movf   Reg_Inst, W      ;Ver si se deben actualizar las salidas.
   xorlw   Inst_END      ;
   btfss   STATUS, Z      ;Es la ultima instruccion ?
   goto   Next_Inst      ;No, Leer la proxima instruccion.
   call   EnviarSalidas      ;Si, Actualizar las salidas segun sus imagenes.
   goto   Inicio         ;Volver a repetir el ciclo.

Para saber cual es la proxima instruccion a leer utilize dos registros del PIC como CONTADOR DE PROGRAMA, es decir que cada vez que se lee una instruccion de la memoria este contador se incrementa en uno, apuntado a la proxima.

Supongamos la siguiente instruccion:

LD  I0, 0   //Leer la entrada 0 del puerto I0 y ponerla en el acumulador.

En la memoria se divide en tres bytes, primero el tipo de instruccion (en este caso LD), luego el nro del puerto (I0), y luego el nro de bit (0). Por lo que lo que se guarda en la memoria es 0x01 0x00 0x00. Es decir que esta instruccion tiene dos parametros adicionales. Por lo general este es el caso para la mayoria de las instrucciones, por lo que cada instruccion del programa de usuario consume tres bytes de la memoria serial.

La lista de instrucciones soportadas es esta:

;Instrucciones del PLC
Inst_LD      equ   0x01      ;LD, carga una entrada o salida en el acumulador.
Inst_OTE   equ   0x03      ;OTE, activa una salida.
Inst_OTL   equ   0x04      ;OTL, activa una salida y la deja memorizada.
Inst_OTU   equ   0x05      ;OTU, desactiva una salida y la deja memorizada.
Inst_OTT   equ   0x06      ;OTT, cambia el estado de una salida.
Inst_OSR   equ   0x07      ;OSR, deteccion de flanco ascendente.
Inst_OSF   equ   0x08      ;OSF, deteccion de flanco descendente.
Inst_AND   equ   0x09      ;AND, "Y logica".
Inst_OR      equ   0x0B      ;OR, "O logica".
Inst_TON   equ   0x0F      ;TON   Temporizador de retardo a la conexion.
Inst_TOF   equ   0x10      ;TOF   Temporizador de retardo a la desconexion.
Inst_TIP   equ   0x11      ;TIP   Temporizador de activacion durante impulso.
Inst_TFL   equ   0x12      ;TFL   Temporizador de activacion/desactivacion ciclica.
Inst_CTU   equ   0x13      ;CTU   Contador ascendente.
Inst_CTD   equ   0x14      ;CTD   Contador descendente.
Inst_RES   equ   0x15      ;RES   Reset de un temporizador o contador.
Inst_CTK   equ   0x16      ;CTK   Incrementa/Decrementa un contador segun DIR.
Inst_HOR        equ     0x17      ;HOR  Horario semanal.
Inst_END   equ   0xFF      ;END   Indica fin del programa.

El segundo byte de la instruccion me indica cual es el puerto, el nro del contador o el nro del temporizador que se quiere utilizar. Por ejemplo si el PLC tuviese dos puertos de 8 salidas cada uno, el primer puerto seria Q0 y el segundo puerto seria Q1, aqui el segundo byte seria 0x00 para Q0 y 0x01 para Q1.
Y finalmente el ultimo byte me indica el nro de bit del puerto, el bit del contador o del temporizador a utilizar.

Bueno, espero que se entienda, en la proxima explico la implementacion de los temporizadores y contadores, que considero lo mas interesante. Saludos.

Tec. Claudio J. Pérez

« Última modificación: 10 de Noviembre de 2009, 23:24:52 por Tec_Claudio_Perez »

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Hagamos un PLC con PIC!!
« Respuesta #153 en: 10 de Noviembre de 2009, 23:43:51 »
Muy buenos avances has tenido, Claudio.
Como pregunta solamente, no has pensado utilizar la memoria de programa para almacenar el programa de usuario??
No seria mas rapido??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #154 en: 11 de Noviembre de 2009, 00:04:31 »
Creo que la primer version usaba un PIC16F84 y la memoria se quedaba corta enseguida, tambien me quedé sin RAM. Pero cualquier mejora o modificacion será bien recibida. En realidad esa es la idea, que el proyecto siga avanzando con el aporte de todos. (Este proyecto estuvo estancado por seis años...)

Tec. Claudio J. Pérez
« Última modificación: 11 de Noviembre de 2009, 00:12:10 por Tec_Claudio_Perez »

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Hagamos un PLC con PIC!!
« Respuesta #155 en: 11 de Noviembre de 2009, 00:16:12 »
Es cierto, en ese tiempo tambien cambiaron las posibilidades y alternativas de nuevos PICs.
Tambien es cierto que es dificil encontrar puertos seriales en las PCs...

Siguenos contando sobre tus avances, no quise interrumpirte, sino alentarte a continuar...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #156 en: 17 de Noviembre de 2009, 16:06:18 »
Hola a todos,
Ahora voy a comentar sobre la implementacion de los temporizadores.

Todos sabemos como hacer una demora de una determinada cantidad de milisegundos, sin duda es lo primero que se aprende para encender y apagar un led :)
Normalmente se utiliza un enfoque donde mediante un bucle, se gastan ciclos de CPU. Pero que sucede si se necesitan contar varios intervalos de tiempo de forma independiente?
Supongamos que tenemos el siguiente problema, queremos encender y apagar ocho leds conectados al puerto B del pic, pero con diferentes intervalos de tiempo, por ejemplo:

RB0 cada  150 ms
RB1 cada  160 ms.
RB2 cada  170 ms.
RB3 cada  180 ms.
RB4 cada  190 ms.
RB5 cada  200 ms.
RB6 cada  210 ms.
RB7 cada  220 ms.

Una solucion seria usar un temporizador por hardware por cada salida, pero los PIC 16F873 solo disponen de tres timer internos. Por lo que hay que encontrar otra solucion.

Otro problema tambien es la resolucion variable. Los temporizadores cuentan invervalos de tiempo, la resolucion o base de tiempo del temporizador determina la duracion de cada intervalo. En algunos PLCs comerciales se asignan resoluciones fijas de acuerdo al nro del temporizador, por ejemplo para 100 temporizadores, el T0 al T3 tienen resolucion de 1ms, del T4 al T20 tienen 10ms de resolucion y el resto T21 al T99 tienen resolucion de 100ms. En los Siemens S7-200 es así, y de acuerdo a la aplicacion uno debe elegir el temporizador adecuado. Sin embargo los Allen Bradley Micrologix 1500 pueden asignar cualquier resolucion a todos los temporizadores, como lo hacen ? Esa sin duda es una buena caracteristica para nuestro PLC.

Cual es el rango de medicion de los temporizadores? Normalmente cuentan de 0 a 32767. Para poder almacenar este valor de cuenta se necesitan 15 bits (2^15=32768) es decir que se usan dos registros en RAM de ocho bits, en el primero se almacenan los 8 bits menos significativos (LSB) y en el segundo se almacenan los 7 restantes (MSB). Por lo general el bit 8 del MSB se utiliza para almacenar el signo. Es decir que el tipo de datos es int16.

Una solucion al problema anterior es la siguiente, queremos implementar ocho temporizadores T0 al T7, con una resolucion variable de 10ms, de 1seg y de 1 minuto. Para esto utilizo dos temporizador por hardware del PIC: el timer 0 configurado para que genere una interrupcion exactamente cada 10 ms y el timer 1 configurado para que genere una interrupcion exactamente cada 1 seg (1000 ms). (Sin duda esto se podría hacer con un solo temporizador y un contador, ademas no creo que la demora de un minuto se utilize muy seguido, pero bueno es solo una prueba de concepto y seguro se mejorará luego. Por otro lado aumentando la velocidad del cristal a 20 Mhz se podria hacer que la resolucion minima de 10ms baje a 1ms. Otra razon para usar la interrupcion de un segundo es que luego se agrego una rutina de Reloj de Tiempo Real usando el Timer2 del PIC y un cristal de 32.768 Khz, y para esto cada un segundo se debe actualizar el reloj. Seguro que esto tambien se puede hacer con un chip externo dedicado que ademas soportan el corte de energia mediante el uso de una pila).

Luego por cada temporizador asocie seis registros  en RAM que controlan su funcionamiento.

Asi para el T0 y el T1 tenemos:

Tim0Config                      ;Configuracion y banderas del T0.
Tim0Presc                       ;Prescaler del T0 (multiplicador).
Tim0LCount                      ;LSB de la Cuenta del T0.
Tim0HCount                      ;MSB de la Cuenta del T0.
Tim0LPreset                     ;LSB del Preset del T0.
Tim0HPreset                     ;MSB del Preset del T0.

Tim1Config                      ;Configuracion y banderas del T1.
Tim1Presc                       ;Prescaler del T1 (multiplicador).
Tim1LCount                      ;LSB de la Cuenta del T1.
Tim1HCount                      ;MSB de la Cuenta del T1.
Tim1LPreset                     ;LSB del Preset del T1.
Tim1HPreset                     ;MSB del Preset del T1.

y asi sucesivamente para el T2 al T7.

El primer registro TimXConfig es un registro de estado y configuracion, y utilizo los bits en forma individual.

;Bits del registro TimConfig:
;- Prescaler         (7-6) 00-10 ms, 01-1 seg, 10 10 seg.
;- Tipo de Timer  (5-4)  00-TON, 01-TOF, 10-TDR, 11-TAD.
;- Actualizando    (3) Se está modificando el temporizador.
;- PLC_AccAnt     (2) Almacena el valor anterior de la entrada del temporizador.
;- DN                  (1) Salida del temporizador.
;- TimerActivado (0) Se está usando el temporizador en el programa de usuario.

Funciona con dos partes, una rutina de servicio de interrupción generada por overflow de los temporizadores y otra rutina que se ejecuta en el programa normal del PIC.

Rutina de interrupción
Cada vez que ocurre una interrupción, se verifica si es la de 10ms, por overflow del timer 0 o la de 1 seg, por overflow del timer 1. Esto luego se marca mediante la variable BandBase10ms utilizada como bandera.

A continuacion, si corresponde, se incrementa el valor de la CUENTA de cada temporizador. Esto se hace en la subrutina "Inc_Timers".

Como la interrupcion puede ocurrir en cualquier momento, existe la posibilidad que justo en ese momento se estén actualizando los datos del temporizador, en el programa normal del PIC, por lo que utilizo el bit 3 de su registro TimConfig (Actualizando) como bandera para indicar esta situacion.
Si esta bandera está activada, significa que el temporizador se está actualizando y no se deben modificar sus datos, por lo que se pasa al siguiente temporizador. En cambio si esta bandera está desactivada se controla si se está utilizando en el programa de usuario, para esto se revisa el bit 0 de su registro TimConfig. Si el temporizador no se utiliza no tiene sentido revisarlo y se pasa al siguiente temporizador.
Si el bit 0 esta activado significa que el temporizador se está utilizando en el programa, por lo que se revisa la resolucion del temporizador.

La resolucion de cada temporizador se configura usando los bits 6 y 7 de su registro de estado TimConfig:

                       Bit 7   Bit 6
Resolucion  10 ms      0   0
Resolucion   1 seg      0   1
Resolucion 60 seg      1   0

Si ocurrió la interrupcion de 10ms (BandBase10ms=1) y la resolucion del temporizador es de 10 ms, se incrementa su valor de CUENTA en uno.
Si ocurrió la interrupcion de 1seg (BandBase10ms=0) y la resolucion del temporizador es de 1seg, se incrementa su valor de CUENTA en uno.
En cambio si ocurrió la interrupcion de 1 seg (BandBase10ms=0), pero la resolucion del temporizador es de 10seg, se incrementa su valor de PRESCALER en uno. Si el valor de PRESCALER, es igual a 60, se vuelve a 0 y se incrementa su valor de CUENTA en uno. (Ya pasaron 60 segundos).

Luego se verifica si su valor de CUENTA es mayor o igual que su valor de PRESET, de ser asi se activa la salida del temporizador (bit DN del registro de estado TimConfig) y se desactiva el temporizador (esto ultimo no deberia ser asi, en futuras versiones, se deberia dejar el temporizador activado). Un caso especial ocurre si el temporizador esta configurado como Temporizador de Intermitencia TFL, aqui cuando la CUENTA es mayor o igual al PRESET se pone a cero el valor de CUENTA y se cambia de estado la salida (si estaba activada se desactiva y si estaba desactivada se activa).

Esto se realiza por cada temporizador. Se utiliza mucho el direccionamiento indirecto (FSR e INDF) para acceder a los registros individuales de cada temporizador. Una vez que se revisan todos, termina la subrutina y se sale de la interrupcion.

Programa normal del PIC.

Por ejemplo supongamos que el PLC debe ejecutar las siguientes sentencias en Lista de Instrucciones:

LD I0,0    // Leer la entrada I0,0 y copiar su valor al acumulador.
TON T0, 500 // Usar el temporizador T0 como retardo a la conexion con un preset de 500 milisegundos.
LD T0, DN  // Cargar el bit DN del temporizador T0 (la salida del temporizador)
OTE Q0, 1  // Si pasan los 500 milisegundos activar la salida Q0, 1

Es decir que si la entrada I0.0 queda activada durante medio segundo, recien se activa la salida Q0, 1.

En el programa de usuario cada vez que se encuentra una instruccion que utilice un temporizador se llama a la subrutina "ActTimers".
Siempre el valor que activa la entrada del temporizador se lee del acumulador, pero tambien es importante conocer si ocurrio un flanco ascendente o un flanco descendente sobre esta entrada. Para poder realizar esto se necesita conocer el valor anterior del acumulador y compararlo contra su valor actual.
Con este fin se utiliza el bit  2 de su registro de estado TimConfig que almacena el estado anterior del acumulador.

Es importante porque cada temporizador puede configurarse de diferente manera como:

TON Retardo a la conexion.
TOF Retardo a la desconexion.
TIP  Temporizador de impulso.
TFL Temporizador de intermitencia.

Esta configuracion se realiza usando los bits 5 y 4 del registro de estado TimConfig:
                      Bit 5   Bit 4
Temporizador TON      0   0
Temporizador TOF      0   1
Temporizador TIP      1   0
Temporizador TFL      1   1

Si el estado actual de la entrada del temporizador es uno y el estado anterior era 0, ocurrió un flanco ascendente. Si el estado actual de la entrada del temporizador es cero y el estado anterior era 1, ocurrio un flanco descendente. Si el estado actual es igual al estado anterior no hubo cambio en la entrada del temporizador. De acuerdo al tipo de temporizador se comporta de manera diferente.

Para un temporizador TON (Retardo a la conexion)
---------------------------------------------------------------------------------

-Si no hubo ningun cambio:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado).
   
-Si hubo un flanco ascendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 1)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Borrar la salida del temporizador DN (bit 1 del registro de estado=0).
   Activar el timer (bit 0 del registro de estado=1).
   Configurar el tipo de timer a TON (bits 5 y 4 del registro de estado=00)
   Configurar la base de tiempo (bits 6 y 7 del registro de estado) segun corresponda.
   Borrar la cuenta del PRESCALER (Registro TimPresc  = 0)
   Borrar la cuenta del temporizador (Registros TimLCount  y TimHCount).
   Setear el valor de PRESET del temporizador (Registros TimLPreset y TimHPreset)
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)

-Si hubo un flanco descendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 0)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Borrar la salida del temporizador DN (bit 1 del registro de estado=0).
   Desactivar el timer (bit 0 del registro de estado=0).
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)

Para un temporizador TOF (Retardo a la desconexión)
--------------------------------------------------------------------------------------

-Si no hubo ningun cambio:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado).
   
-Si hubo un flanco ascendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 1)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Borrar la salida del temporizador DN (bit 1 del registro de estado=0).
   Desactivar el timer (bit 0 del registro de estado=0).
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)

-Si hubo un flanco descendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 0)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Borrar la salida del temporizador DN (bit 1 del registro de estado=0).
   Activar el timer (bit 0 del registro de estado=1).
   Configurar el tipo de timer a TOF (bits 5 y 4 del registro de estado=01)
   Configurar la base de tiempo (bits 6 y 7 del registro de estado) segun corresponda.
   Borrar la cuenta del PRESCALER (Registro TimPresc  = 0)
   Borrar la cuenta del temporizador (Registros TimLCount  y TimHCount).
   Setear el valor de PRESET del temporizador (Registros TimLPreset y TimHPreset)
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)

Para un temporizador TIP (Temporizador de Impulso)
-------------------------------------------------------------------------------------

-Si no hubo ningun cambio:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado).

-Si hubo un flanco ascendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 1)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Activar la salida del temporizador DN (bit 1 del registro de estado=1).
   Activar el timer (bit 0 del registro de estado=1).
   Configurar el tipo de timer a TOF (bits 5 y 4 del registro de estado=10)
   Configurar la base de tiempo (bits 6 y 7 del registro de estado) segun corresponda.
   Borrar la cuenta del PRESCALER (Registro TimPresc  = 0)
   Borrar la cuenta del temporizador (Registros TimLCount  y TimHCount).
   Setear el valor de PRESET del temporizador (Registros TimLPreset y TimHPreset)
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)
-Si hubo un flanco descendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 0)

Para un temporizador TFL (Temporizador de Impulso)
-------------------------------------------------------------------------------------

-Si no hubo ningun cambio:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado).

-Si hubo un flanco ascendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 1)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)   
   Desactivar la salida del temporizador DN (bit 1 del registro de estado=1).
   Activar el timer (bit 0 del registro de estado=1).
   Configurar el tipo de timer a TOF (bits 5 y 4 del registro de estado=11)
   Configurar la base de tiempo (bits 6 y 7 del registro de estado) segun corresponda.
   Borrar la cuenta del PRESCALER (Registro TimPresc  = 0)
   Borrar la cuenta del temporizador (Registros TimLCount  y TimHCount).
   Setear el valor de PRESET del temporizador (Registros TimLPreset y TimHPreset)
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)
-Si hubo un flanco descendente:
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 1)
   Desactivar la interrupcion mientras se configura el timer (bit 3 del registro de estado=1)
   Borrar la salida del temporizador DN (bit 1 del registro de estado=0).
   Desactivar el timer (bit 0 del registro de estado=0).
   Reactivar la interrupcion porque se termino de configurar el timer (bit 3 del registro de estado=0)
   Guardar el estado actual de la entrada del timer o sea el acumulador (bit 2 del registro de estado = 0)

Bueno, espero que se haya entendido algo, la verdad que me llevo bastante tiempo mejorar la redaccion. Como prueba de concepto y para fines educativos funciona  perfectamente logrando implementar ocho temporizadores (T0 al T7) completamente independientes, con resoluciones variables. El problema es el gran consumo de registros en RAM (Seis registros por cada temporizador) lo que nos limita la cantidad de temporizadores disponibles. En comparacion el Siemens S7-200 tiene 256 temporizadores, para poder llegar a esto hace falta conectar una RAM estática externa al PIC, por ejemplo una 62XXX. En realidad la mayoria de los PLC industriales hacen esto. Luego subo unas fotos para que vean.

Saludos a todos y se aprecia cualquier sugerencia.
Tec. Claudio J. Pérez

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Hagamos un PLC con PIC!!
« Respuesta #157 en: 18 de Noviembre de 2009, 09:38:04 »
Brillante explicacion!!
La verdad es que vas a completar un libro, Claudio!!

Acerca de los timers, el valor del preset puede ser modificado con el timer funcionando??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #158 en: 19 de Noviembre de 2009, 15:03:17 »
Gracias MGLSOFT, si parece un libro es que quedo entendible. Ja ja.
Creo que si se podria, con la precaucion de deshabilitar la interrupcion sobre el mismo antes de comenzar la modificacion y luego habilitarla luego. Esto lo podria hacer automaticamente el sistema operativo y que sea invisible para el usuario.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Hagamos un PLC con PIC!!
« Respuesta #159 en: 19 de Noviembre de 2009, 23:51:58 »
Buenas, me demoré un poco pero seguro, led dejo imagenes de las placas del S7-212.

Placa de control:


Placa de potencia:



Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Hagamos un PLC con PIC!!
« Respuesta #160 en: 20 de Noviembre de 2009, 08:04:33 »
Buenas, me demoré un poco pero seguro, led dejo imagenes de las placas del S7-212.

Placa de control:


Placa de potencia:



Saludos!

Tuvo un corto en la fuente ese PLC o simplemente es polvo lo que se ve sobre varios componentes??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Hagamos un PLC con PIC!!
« Respuesta #161 en: 20 de Noviembre de 2009, 09:08:05 »
No, es polvo! Aunque como es de la facu, es sufrido el pobrecito y no me extrañaría que tenga un par de cortos en su vida  :mrgreen:

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #162 en: 23 de Noviembre de 2009, 22:45:31 »
Muy buenas fotos,

Lo primero que veo es la ram estatica, en la segunda foto abajo a la izquierda, dice SHARP LH5164AN-10L.
Segun la hoja de datos http://kr.ic-on-line.cn/IOL/datasheet/lh5164ahn-10l_200507.pdf es una ram de 64 Kbits (8 Kbytes). Por lo que para direccionarla en forma directa se usan 13 lineas de direccion (A0 a A12), 8 de datos y tres de control CE, WE y OE. Seria bueno comparar con otros PLCs  a ver que Rams usan.

Otra cosa interesante de los Siemens S7-200 es que siempre usan un microcontrolador ATMEL, aparte del micro principal, tambien lo llevan en los modulos de expansion por lo que creo que lo usan para el protocolo de comunicacion en el bus. Será que con un solo microcontrolador no alcanza ?

Saludos a todos.
« Última modificación: 23 de Noviembre de 2009, 23:05:23 por Tec_Claudio_Perez »

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Hagamos un PLC con PIC!!
« Respuesta #163 en: 23 de Noviembre de 2009, 23:13:42 »
Lo primero que veo es la ram estatica, en la segunda foto abajo a la izquierda, dice SHARP LH5164AN-10L.
Segun la hoja de datos http://kr.ic-on-line.cn/IOL/datasheet/lh5164ahn-10l_200507.pdf es una ram de 64 Kbits (8 Kbytes). Por lo que para direccionarla en forma directa se usan 13 lineas de direccion (A0 a A12), 8 de datos y tres de control CE, WE y OE. Seria bueno comparar con otros PLCs  a ver que Rams usan.

Dentro de 1 o 2 semanas voy a tener un S7-214, haber si tengo posibilidad de apropiármelo para sacarle unas fotos  :mrgreen:

Otra cosa interesante de los Siemens S7-200 es que siempre usan un microcontrolador ATMEL, aparte del micro principal, tambien lo llevan en los modulos de expansion por lo que creo que lo usan para el protocolo de comunicacion en el bus. Será que con un solo microcontrolador no alcanza ?

Puede ser, para trabajar las comunicaciones independientemente a las tareas de control y hacerlo más robusto  :huh:

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
Re: Hagamos un PLC con PIC!!
« Respuesta #164 en: 03 de Diciembre de 2009, 19:51:53 »
Hola a todos, navegando por ahi encontré esto:

http://host.nigde.edu.tr/muzam/UZAM_PLC_with_PIC16F648A.htm

Está basado en el PICBIT, es decir un PLC con macros, pero mas completo. Aparentemente es de un Prof. en Turquia y es tan bueno que viene saliendo en la revista inglesa de electronica "Electronics World" como una serie de articulos. Echenle una mirada. Me pregunto como hace cuando tenes varios temporizadores...

Saludos.