Autor Tema: Controlador de luces y ventiladores con PIC  (Leído 3537 veces)

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

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Controlador de luces y ventiladores con PIC
« en: 09 de Febrero de 2015, 11:20:06 »
Buenas a todos los locos programadores. Luego de estudiar programar pics, y enseñar a hacerlo en un instituto, se me da la oportunidad de hacer mi primer proyecto. El objetivo del mismo es activar luces y ventilacion en un rack (como de servidores, pero yo lo uso para poner la electronica del play-room: htpc, ps3, router, roku...).
Proyecto:
con 2 botones de entrada, activar las luces o los ventiladores para iluminar o ventilar respectivamente el rack
lo que vaya a hacer con uno, hace lo mismo con el otro, asi que voy a explicar uno solo.
encendido del sistema: todo apagado
pulso el boton una vez y pasa a encendido manual: los ventiladores quedan prendidos.
pulso el boton nuevamente y pasan a modo automatico: con un termistor en el rack, controlo la temperatura. paso a una entrada de un 74xx14 (Schmitt Trigger para "jugar" con umbrales y no se la pase prendiendo y apagando), la salida la paso al PIC y a otra entrada del 74xx14 y esta salida a otra pata del PIC
exactamente lo mismo, pero con algun sensor de luz (ldr?) para la parte iluminacion.
estas cuatro entradas son las B4-B7 que me despertaran (eventualmete) al PIC.
como la otra forma de levantarlo que me queda es solo por B0 y no tengo mas (uso al querido 16f84), con un 74xx07 pongo al pulzador luz en dos entradas y al pulzador ventilador en otras dos, junto una salida de luz con una salida de ventilador y voy a B0 (para despertar al PIC) y la otra salida de luz ira a B2 y la otra de ventilador a B3 (analizare con programacion cual se activo)
hasta aca tengo ocupado casi todo el puerto B (solo me queda el B1 sin usar)
en el puerto A, activare 2 leds bicolores, que me mostraran el estado: apagado (no luz), manual (color 1) o automatico (color 2)
entonces, paso estas 4 salidas a A0-A3, dejandome libre el complicado A4 (T0CKI), que lo pondre (para que moleste menos) como salida.
Asi, A4 sera el encendido de los ventiladores y B1 el encendido de las luces.
Listo, todas las patas ocupadas.

Ahora viene mi pregunta. como dije, siempre he dado teoria, pero este es mi primer hecho real, asi que ahora vienen las preguntas:
pudo poner las patas de B4-B7 como salidas para que no molesten al PIC mientras duerme y no necesite sus entradas?
se entendera que son los casos:
1) si esta en manual, las patas correspondientes al automatico no deben molestar
2) si se activo una para prender los ventiladores, poner ESA MISMA en salida, para que no siga despertandolo, y solo lo despierte la otra (para apagarlos cuando baje la temperatura)

por las salidas, no me preocupo, van a las entradas de un juego arduino de reles directamente.

una vez terminado el proyecto, subire (POR SUPUESTO) la primera version que tenga (en assembler) para opinar, modificar, corregir, proponer, etc

Xakko

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Controlador de luces y ventiladores con PIC
« Respuesta #1 en: 09 de Febrero de 2015, 13:02:20 »
Bueno bastante confusa tu explicacion del proyecto.

Entiendo lo de modo automatico y manual,
4 pin sensores un ldr y un termistor (cada uno): Entiendo que usas un integrado externo para manejar un los umbrales.
2 pin leds
2 pin ventiladores
2 pin luces
2 pin switches

Citar
estas cuatro entradas son las B4-B7 que me despertaran

Por que ponerlo a dormir. Es necesario ?
En ves de usar esas interrupciones ( ojo no hace falta el GIE en 1 ) podrias usar la del WDT o la del TMR0. Asi cada tanto despierta y revisa las entradas.

Citar
pudo poner las patas de B4-B7 como salidas para que no molesten al PIC mientras duerme y no necesite sus entradas?

De poder, podes.. El problema es que tenes que tener cuidado de que el sensor no envie tension, o de poner una resistencia limitadora de corriente, sino imaginate el caso que el 74xx14 envie 5V y vos pones tu salida a 0V ( y sin resistencia ).

Citar
1) si esta en manual, las patas correspondientes al automatico no deben molestar

Eso depende de tu programa, si esta en manual tu programa no le interesaria el estado de las entradas asi que pueden tener cualquier valor que no te va a molestar.
Si te molesta que te puedan despertar el programa podrias desabilitar las interrupciones por cambio del portb y usar otra como el TMR0/WDT o con un circuito externo activar Rb0/INT.

Citar
2) si se activo una para prender los ventiladores, poner ESA MISMA en salida, para que no siga despertandolo, y solo lo despierte la otra (para apagarlos cuando baje la temperatura)

Tenes el problema que dije antes, directamente dejalo activo y cuando cambie se active el micro y vuelva a dormirse...

Resumiendo y agregando un par de cosas:

1. El tema de los sensores vas a tener que acondicionar la salida para que llegue al umbral del 74xx14 a la temperatura/luz deseada, y espero que quede un buen umbral.
2. Planteate si es realmente necesario el SLEEP del micro ( ya que estarias consumiendo como MAXIMO MAXIMO 100/150mA mientras que un rele consumiria mucho mas ). O si directamente bajas la frecuencia del oscilador a un cristal de 32768Hz  ( digo por si queres menor consumo y tu programa no necesita de gran velocidad, pero sigue siendo absurdo por lo mismo que plantee con anterioridad ). Un primer paso seria hacerlo sin el SLEEP
3. Si no compraste el PIC deberias de comprar otro mejor, el PIC16F84 a pesar que es muy simple y sirve para aprender termina siendo muy caro a comparacion de otros con muchos mas pines y prestaciones como un 16f628 o 16f887 (40 pines) que tengan A/D y te solucionas la circuiteria externa. Y si sabes programarlo y has enseñado con lo cual imagino que lo conoces a fondo, los demas no te van a ser complejos.
4. Mantenete simple. Si ves que existe muchas cosas ( integrados,AOs,resitencias,capacitores ) para algo, de seguro que hay una solucion que lo simplifica mucho mas. ( Me refiero al tema de los sensores, el uso del sleep y las implicaciones para que se despierte con cualquier entrada)
« Última modificación: 09 de Febrero de 2015, 13:35:54 por KILLERJC »

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #2 en: 09 de Febrero de 2015, 13:35:12 »
gracia killerjc por contestar.
el tema de dormirlo, es porque asi estaria la mayor parte del tiempo, pero si no hace falta hacerlo, le mando un bucle goto renglon anterior y listo.
el tema secundario justamente era ese (consecuencia de poder poner patas del B4-B7 como salidas): que no me molesten los valores externos en los puertos asignados como salidas. como decis, sera con una resistencia entre el 7414 y los puertos del PIC
ya voy avanzando algo en el codigo
ni bien tenga algo, lo subo

gracias otra vez

Xakko

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Controlador de luces y ventiladores con PIC
« Respuesta #3 en: 09 de Febrero de 2015, 13:49:20 »
el tema de dormirlo, es porque asi estaria la mayor parte del tiempo,
el tema secundario justamente era ese (consecuencia de poder poner patas del B4-B7 como salidas): que no me molesten los valores externos en los puertos asignados como salidas. como decis, sera con una resistencia entre el 7414 y los puertos del PIC

Si entiendo pero tenes que ver el consumo del micro, me refiero si es el micro el que consume la mayor energia o son las demas cosas, y si vale la pena hacerlo de esa forma ( me refiero si bajas mucho el consumo )
Ej:
tengo prendido 2 leds y me consumen 40mA y el micro me consume 5mA ( segun datasheet, maximo a 4Mhz y 5.5V, tipico 1.8mA ) si lo pongo a dormir solo ahorro esos 5mA/1.8mA ya que la mayor parte es de los leds..
De la misma forma un rele.

Y los valores externos no te van a molestar.. a no ser que uses para despertar los cambios de los puertos, por eso decia que podes usar el TMR0 para que cada 100ms por ejemplo, despierte revise si las entradas cambiaron y vuelva a dormir si nada cambio.
Tenes algunas ventajas y desventajas.
La ventaja es que no podes esa resistencia, si estas poniendo una resistencia es para limitar la corriente, por lo tanto significa que estas agregando consumo al ponerlo como salida. Con esto te ahorras de poner esa resistencia lo cual te simplifica el circuito, no tenes mas consumo,
Y la parte fea (desventaja) es que despertaria cada 100ms y no cuando uno presione la tecla, pero que funcione por unas 10 instrucciones ( 10us a 4Mhz ) no creo que te influya tanto en el consumo total.

Ademas solo estas pensando en el micro y deberias pensar en tu termistor, LDR, 74xx14 etc etc todo eso te consume tambien, y vos te preocupas por uno solo ( el PIC ).

Por eso opino que estas complicando mas que trayendo una solucion. Queres bajar el consumo del micro? usa un cristal de menos frecuencia. Pero sigue siendo ilogico tras los consumos que tenes por los demas componentes.

En fin eso queda a tu criterio, queres usar el SLEEP ya te di algunas soluciones, pero la aplicacion del mismo para un consumo menor depende de todo el circuito y no solo el PIC y solo estarias complicando las cosas si ese es tu objetivo.
« Última modificación: 09 de Febrero de 2015, 13:58:56 por KILLERJC »

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #4 en: 09 de Febrero de 2015, 13:54:02 »
en absoluto, no me preocupa el consumo... era por costumbre nomas. como dije, hasta ahora fui todo teoria, pero en la cancha se ven los pingos, y recien estoy saliendo....

gracias otra vez, sigo escribiendo

Xakko

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #5 en: 09 de Febrero de 2015, 15:00:21 »
bueno, ahi va la primera version. espero se entienda, sino mañana explico los saltos y sub-rutinas
aclaro que yo hago el programa en excel (asi me ubico las celdas) y de ahi lo paso a programa de programacion de pic.
asi que si quieren ver bien, copien y peguen en una planilla de calculo, y (supongo) se entendera mejor

   list   P=16F84A   
   include   "P16F84A.INC"   
         
   cblock   0x0C   
   ev      ; estado de ventiladores
   el      ; estado de luces
   endc      
         
   org   0   ; en el arranque
   goto   inicio   ; va a inicio
   org   4   ; si hay interrupcion
   goto   interrpuertob   ; va a interrpuertob
         
         
interrpuertob   bcf   INTCON,7   ; inhabilito momentaneamente las interrupciones, borrando el bit 7 de INTCON
   btfsc   INTCON,0   ; no fue interrupcion por entrada en PUERTO B4-B7 (RBIF)? Salta un renglon
   goto   sensores   ; entonces como fue por interrupcion de RBIF (B4-B7), anda a sensores
   btfsc   INTCON,1   ; no fue interrupcion por entrada en PUERTO B0 (RB0/INTF)? Salta un renglon
   goto   botones   ; entonces como fue por interrupcion de RB0/INTF (B0), anda a botones
   goto   dormir   
         
sensores   btfsc   PORTB,4   ; no fue boton 4 del puerto B el presionado? Entonces salta un renglon
   call   luzautoon   ; si, fue el 4. entonces anda a prender las luces
   btfsc   PORTB,5   ; no fue boton 5 del puerto B el presionado? Entonces salta un renglon
   call   luzautooff   ; si, fue el 5. entonces anda a apagar las luces
   btfsc   PORTB,6   ; no fue boton 6 del puerto B el presionado? Entonces salta un renglon
   call   venautoon   ; si, fue el 6. entonces anda a prender los ventiladores
   btfsc   PORTB,7   ; no fue boton 7 del puerto B el presionado? Entonces salta un renglon
   call   venautooff   ; si, fue el 7. entonces anda a apagar los ventiladores
   goto   finint   ; anda a finalizar interrupciones
         
luzautoon         ; inicializacion modo automatico, con luces encendidas
   bsf   PORTA,4   ; prendo las luces
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,4   ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bsf   TRISB,5   ; pongo a la pata 5 de B en 1 (entrada) para que active el sistema si hay que apagar las luces en modo automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
luzautooff         ; inicializacion modo automatico, con luces apagadas
   bcf   PORTA,4   ; apago las luces
   bsf   STATUS,RP0   ; paso al banco 1
   bsf   TRISB,4   ; pongo a la pata 4 de B en 1 (entrada) para que active el sistema si hay que encender las luces en modo automatico
   bcf   TRISB,5   ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
venautoon         ; inicializacion modo automatico, con ventiladores encendidos
   bsf   PORTB,1   ; prendo los ventiladores
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,6   ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bsf   TRISB,7   ; pongo a la pata 5 de B en 1 (entrada) para que active el sistema si hay que apagar las luces en modo automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
venaoutooff         ; inicializacion modo automatico, con ventiladores apagados
   bcf   PORTB,1   ; apago los ventiladores
   bsf   STATUS,RP0   ; paso al banco 1
   bsf   TRISB,6   ; pongo a la pata 4 de B en 1 (entrada) para que active el sistema si hay que encender las luces en modo automatico
   bcf   TRISB,7   ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
botones   btfsc   PORTB,2   ; no fue boton 2 del puerto B el presionado? Entonces salta un renglon
   call   luces   ; si, fue el 2 (JUNTO AL 0 que llamo al PIC). entonces vamos a maniobrar las luces
   btfsc   PORTB,3   ; no fue boton 3 del puerto B el presionado? Entonces salta un renglon
   call   ventis   ; si, fue el 3 (JUNTO AL 0 que llamo al PIC). entonces vamos a maniobrar los ventiladores
goto   finint      


luces         ; subrutinas de eventos según los estados de las luces
   incf   el,F   ; paso al proximo estado de las luces
   btfsc   el,0   ; si el bit 0 de el esta en 0, salta un renglon
   call   luzmanon   ; esta en 1; pasa a encendido (manual). Como solo toma valores 0, 1 o 2, el unico con el bit 0 en 1 es 1 (estado encendido-manual)
   btfsc   el,1   ; si el bit 1 de el esta en 0, salta un renglon
   call   luzauto   ; esta en 1 (de arriba, esta en 10 = 2); pasa a automatico. Como solo toma valores 0, 1 o 2, el unico con el bit 1 en 1 es 2 (estado automatico)
   clrf   el   ; ahora si el bit 0 no esta en 0, y el bit 1 tampoco lo esta, estan los 2 en 1 (estado = 3), debo poner el estado en 0, apagado
   call   luzmanoff   ; y voy a apagar las luces
   return      
         
luzmanon         ; inicializacion de encendido manual de luces
   bsf   PORTA,0   ;
   bcf   PORTA,1   ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido manual
   bsf   PORTA,4   ; prendo las luces
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,4   ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bcf   TRISB,5   ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
luzauto   bcf   PORTA,0   ;
   bsf   PORTA,1   ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido automatico
   btfsc   PORTB,4   ; solo me fijo si necesita luz, cualquier otro estado queda en automatico con las luces apagadas
   goto   luzonini   

luzoffini   call   luzautooff   
   goto   salluzauto   
         
luzonini   call   luzautoon   
salluzauto   return      
         
         
luzmanoff         ; inicializacion de apagado manual de luces
   bcf   PORTA,0   ;
   bcf   PORTA,1   ; junto al renglon anterior, apago el led bicolor: estado apagado manual
   bcf   PORTA,4   ; apago las luces
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,4   ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bcf   TRISB,5   ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
         
ventis         ; subrutinas de eventos según los estados de los ventiladores
   incf   ev,F   ; paso al proximo estado de las luces
   btfsc   ev,0   ; si el bit 0 de el esta en 0, salta un renglon
   call   venmanon   ; esta en 1; pasa a encendido (manual). Como solo toma valores 0, 1 o 2, el unico con el bit 0 en 1 es 1 (estado encendido-manual)
   btfsc   ev,1   ; si el bit 1 de el esta en 0, salta un renglon
   call   venauto   ; esta en 1 (de arriba, esta en 10 = 2); pasa a automatico. Como solo toma valores 0, 1 o 2, el unico con el bit 1 en 1 es 2 (estado automatico)
   clrf   ev   ; ahora si el bit 0 no esta en 0, y el bit 1 tampoco lo esta, estan los 2 en 1 (estado = 3), debo poner el estado en 0, apagado
   call   venmanoff   ; y voy a apagar los ventiladores
   return      
         
venmanon         ; inicializacion de encendido manual de ventiladores
   bsf   PORTA,2   ;
   bcf   PORTA,3   ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido manual
   bsf   PORTB,1   ; prendo los ventiladores
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,6   ; pongo a la pata 6 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bcf   TRISB,7   ; pongo a la pata 7 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
venauto   bcf   PORTA,2   ;
   bsf   PORTA,3   ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido automatico
   btfsc   PORTB,6   ; solo me fijo si necesita ventilacion, cualquier otro estado queda en automatico con los ventiladores apagados
   goto   venonini   

venoffini   call   venaoutooff   ; inicializacion modo automatico, con ventiladores apagados
   goto   salvenauto   
         
venonini   call   venaoutoon   ; inicializacion modo automatico, con ventiladores encendidos
salvenauto   return      
         
         
venmanoff         ; inicializacion de apagado manual de ventiladores
   bcf   PORTA,2   ;
   bcf   PORTA,3   ; junto al renglon anterior, apago el led bicolor: estado apagado manual
   bcf   PORTB,1   ; apago los ventiladores
   bsf   STATUS,RP0   ; paso al banco 1
   bcf   TRISB,6   ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
   bcf   TRISB,7   ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
   bcf   STATUS,RP0   ; vuelvo al banco 0
   return      
         
         
         
finint   bsf   INTCON,7   ; rehabilito las interrupciones, prendiendo el bit 7 de INTCON
   retfie      
         
inicio   bsf   STATUS,RP0   ; paso al banco 1
   movlw   b'11111101'   ; configuro al puerto b:EEEEEESE
   movwf   TRISB   ; configuro al puerto b
   clrf   TRISA   ; configuro al puerto a todo de salida
   bcf   STATUS,RP0   ; paso al banco 0
   clrf   PORTA   ; pongo en 0 al puerto a
   clrf   PORTB   ; pongo en 0 al puerto b
   movlw   b'10011000'   ; configuracion interrupciones. Habilita general y habilita por RB0 y PORT B (4-7)
   movwf   INTCON   ; configuracion interrupciones
   clrf   ev   ; estado inicial de los ventiladores: 0, apagados
   clrf   el   ; estado inicial de las luces: 0, apagadas
         
dormir   sleep      ; o el bucle

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #6 en: 09 de Febrero de 2015, 15:04:47 »
como dije, aca soy nuevo y no se como se pone para ver bien las columnas (todavia). mando adjunto un texto separado por tabulaciones
adjunto tambien una imagen-bosquejo de la idae del proyecto


Xakko
« Última modificación: 09 de Febrero de 2015, 15:32:43 por xakko »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Controlador de luces y ventiladores con PIC
« Respuesta #7 en: 09 de Febrero de 2015, 16:46:04 »
Creo que tenes un problema de concepto, a las interrupciones deberias entrar y salir lo mas rapido posible y de ahi activar flags
para que en tu programa principal actue segun las flags sino espera.

Cosas a notar:

- No estas salvando el contexto al entrar a una interrupcion (Aunque poco importa ya que no estas haciendo nada en tu programa principal)
- No hay un bucle en el programa principal, el sleep no debe funcionar de esa forma, luego del Sleep deberia ir un NOP (lo pide el datasheet ya que carga PC+1 con el SLEEP)  y luego del NOP ahi si podes hacer un GOTO dormir para formar el bucle.
- Hay codigo que no tiene sentido:

Código: ASM
  1. luces         ; subrutinas de eventos según los estados de las luces
  2.    incf   el,F   ; paso al proximo estado de las luces
  3.    btfsc   el,0   ; si el bit 0 de el esta en 0, salta un renglon
  4.    call   luzmanon   ; esta en 1; pasa a encendido (manual). Como solo toma valores 0, 1 o 2, el unico con el bit 0 en 1 es 1 (estado encendido-manual)
  5.    btfsc   el,1   ; si el bit 1 de el esta en 0, salta un renglon
  6.    call   luzauto   ; esta en 1 (de arriba, esta en 10 = 2); pasa a automatico. Como solo toma valores 0, 1 o 2, el unico con el bit 1 en 1 es 2 (estado automatico)
  7.    clrf   el   ; ahora si el bit 0 no esta en 0, y el bit 1 tampoco lo esta, estan los 2 en 1 (estado = 3), debo poner el estado en 0, apagado
  8.    call   luzmanoff   ; y voy a apagar las luces
  9.    return

"el" solo se usa ahi... iniciemos el razonamiento.. el comienza en 0x00 pasa a 0x01 pregunta y obviamente va a ir al primer call, pero el segundo no..
Y luego  borras "el" dejandolo en 0 de nuevo. en fin el primer BTFSC nunca va a saltar , el segundo BTFSC siempre va a saltar. (no son condicionales si siempre van a hacer lo mismo, por ende son instrucciones de mas tal y cual estan escritas a no ser que cambies algo )

- Uso de GOTO sin razon alguna y me explico con una parte del codigo(por que poner un GOTO mas cuando lo podes reemplazar por un return, 2 ciclos agregados sin sentido + 1 bandera haciendo menos legible el codigo ; Compara con tu codigo):

Código: ASM
  1. venauto   bcf   PORTA,2   ;
  2.    bsf   PORTA,3   ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido automatico
  3.    btfsc   PORTB,6   ; solo me fijo si necesita ventilacion, cualquier otro estado queda en automatico con los ventiladores apagados
  4.    goto   venonini  
  5.    call   venaoutooff   ; inicializacion modo automatico, con ventiladores apagados
  6.    return
  7.  
  8. venonini   call   venaoutoon   ; inicializacion modo automatico, con ventiladores encendidos
  9.               return


- El hardware para lso botones es insuficiente asi como tenes el programa, tranquilamente podes reemplazar ese integrado por 2 diodos. A lo que me referia al comienzo es el uso de anti rebotes, no esta aplicado en HW y tampoco lo veo en el software
- Una cosa mas de las interrupciones, no podes hacer un GOTO dormir ( es decir sacarlo de la interrupcion y mandarlo directo al programa principal sin antes un return o algo asi, sino estarias con un problema de overflow de pila).. si entro a la interrupcion por algo es. y supuestamente no deberia llegar jamas al GOTO dormir, pero por las dudas mejor reemplazarlo por un RETFIE .
- Falta limpiar los flags de interrupcion
-  bcf   INTCON,7 y bsf   INTCON,7  no es necesario, ya que al entrar a la interrupcion se pone a 0. y el RETFIE lo pone nuevamente a 1.


Recomendaciones:

- Quitar el SLEEP hacer un simple loop
- Mover todo a una funcion principal
- Interrupcion solo para setear unos flags y salir asi poder atender a las demas interrupciones lo mas rapido posible. (Ejemplo se activa el LDR entras a interrupcion y mientras estas dentro se activa el termistor, leiste el PORTB,borraste flag y saliste. No vas a detectar el cambio del termistor)
- Olvidate de eso de andar poniendo como salidas las entradas. No tiene ningun sentido ya que no usas el SLEEP.
- Interrupcion solo para los botones. y lo demas pollear las entradas, si esta en manual no hace nada, si esta en automatico que este continuamente preguntando por las entradas. Si no te gusta que este activando una entrada ya activa podes guardar el estado de las variables y si es igual no hacer nada y salir sin activar nada mas.

Sigo sin entender por que queres usar el SLEEP cuando no te importa el consumo.
« Última modificación: 09 de Febrero de 2015, 17:12:31 por KILLERJC »

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #8 en: 09 de Febrero de 2015, 19:05:56 »
otra vez gracias. mañana a la mañana retomo el tema y veo de hacer las modificaciones sugeridas y subir el codigo modificado.

Xakko

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #9 en: 10 de Febrero de 2015, 08:11:14 »
bueno. aca algunas modificaciones sugeridas por killerjc
los goto son saltos de dos o tres renglones dentro de una misma subrutina, para que eluda alguna otra subrutina.
el tema de interrupciones por sensores o por boton, quedaron como debe ser en subrutinas (sin gotos)
efectivamente, al no haber rutina de principal, no me preocupo por almacenar estados ni W
dado que el sistema tiene que "dejar andando" (o no) no hago una rutina principal, sino directamente todo en las interrupciones
dormir pasa a ser un bucle
correccion de algunas subrutinas con nombres mal puestos


adjunto tambien foto actualizada del bosquejo, con el cambio de el 7407 por 2 diodos a cada entrada.
la parte del termistor no la hice todavia, porque no encuentro algo similar en el proteus, pero es lo mismo que con el ldr.

Código: [Seleccionar]
list P=16F84A
include P16F84A.INC

cblock 0x0C
ev ; estado de ventiladores
el ; estado de luces
endc

org 0 ; en el arranque
goto inicio ; va a inicio
org 4 ; si hay interrupcion
goto interrpuertob ; va a interrpuertob

interrpuertob ; subrutina de interrupciones
bcf INTCON,7 ; inhabilito momentaneamente las interrupciones, borrando el bit 7 de INTCON (SACAR)
btfsc INTCON,0 ; no fue interrupcion por entrada en PUERTO B4-B7 (RBIF)? Salta un renglon
call sensores ; entonces como fue por interrupcion de RBIF (B4-B7), anda a sensores
btfsc INTCON,1 ; no fue interrupcion por entrada en PUERTO B0 (RB0/INTF)? Salta un renglon
call botones ; entonces como fue por interrupcion de RB0/INTF (B0), anda a botones
fininit btfsc PORTB,0 ; espero la liberacion del boton
goto fininit ; vuelvo para seguir esperando la liberacion del boton RB0
bcf INTCON,0 ; limpieza de flags de salida
bcf INTCON,1 ; limpieza de flags de salida
bsf INTCON,7 ; rehabilito las interrupciones, prendiendo el bit 7 de INTCON (SACAR)
retfie ; salgo de las interrupciones

sensores ; subrutina de interrupcion por ingreso de sensores (RB4-RB7) para encender o apagar luces o ventiladores, según necesidad
btfsc PORTB,4 ; no fue boton 4 del puerto B el presionado? Entonces salta un renglon
call luzautoon ; si, fue el 4. entonces anda a prender las luces
btfsc PORTB,5 ; no fue boton 5 del puerto B el presionado? Entonces salta un renglon
call luzautooff ; si, fue el 5. entonces anda a apagar las luces
btfsc PORTB,6 ; no fue boton 6 del puerto B el presionado? Entonces salta un renglon
call venautoon ; si, fue el 6. entonces anda a prender los ventiladores
btfsc PORTB,7 ; no fue boton 7 del puerto B el presionado? Entonces salta un renglon
call venautooff ; si, fue el 7. entonces anda a apagar los ventiladores
return

botones ; subrutina de interrupcion por ingreso de boton RB0 (junto a RB2 o RB3), para alterar los estados de luces o ventiladores
btfsc PORTB,2 ; no fue boton 2 del puerto B el presionado? Entonces salta un renglon
call luces ; si, fue el 2 (JUNTO AL 0 que llamo al PIC). entonces vamos a maniobrar las luces
btfsc PORTB,3 ; no fue boton 3 del puerto B el presionado? Entonces salta un renglon
call ventis ; si, fue el 3 (JUNTO AL 0 que llamo al PIC). entonces vamos a maniobrar los ventiladores
return

luzautoon ; inicializacion modo automatico, con luces encendidas
bsf PORTA,4 ; prendo las luces
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,4 ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bsf TRISB,5 ; pongo a la pata 5 de B en 1 (entrada) para que active el sistema si hay que apagar las luces en modo automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

luzautooff ; inicializacion modo automatico, con luces apagadas
bcf PORTA,4 ; apago las luces
bsf STATUS,RP0 ; paso al banco 1
bsf TRISB,4 ; pongo a la pata 4 de B en 1 (entrada) para que active el sistema si hay que encender las luces en modo automatico
bcf TRISB,5 ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

venautoon ; inicializacion modo automatico, con ventiladores encendidos
bsf PORTB,1 ; prendo los ventiladores
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,6 ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bsf TRISB,7 ; pongo a la pata 5 de B en 1 (entrada) para que active el sistema si hay que apagar las luces en modo automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

venautooff ; inicializacion modo automatico, con ventiladores apagados
bcf PORTB,1 ; apago los ventiladores
bsf STATUS,RP0 ; paso al banco 1
bsf TRISB,6 ; pongo a la pata 4 de B en 1 (entrada) para que active el sistema si hay que encender las luces en modo automatico
bcf TRISB,7 ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

luces ; subrutinas de eventos según los estados de las luces
incf el,F ; paso al proximo estado de las luces
movf el,W ; paso el valor de el a W
sublw 1 ; resto 1-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call luzmanon ; la resta fue cero, va a la subrutina luces manual encendido
movf el,W ; paso el valor de el a W
sublw 2 ; resto 2-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call luzauto ; la resta fue cero, va a la subrutina luces automatico
movf el,W ; paso el valor de el a W
sublw 3 ; resto 1-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call luzmanoff ; la resta fue cero, va a la subrutina ventilador manual apagado
return

luzmanon ; inicializacion de encendido manual de luces
bsf PORTA,0 ;
bcf PORTA,1 ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido manual
bsf PORTA,4 ; prendo las luces
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,4 ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bcf TRISB,5 ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

luzauto ; inicializacion de luces automaticas. Se fija en el estado en el que esta la solicitud de luz, y la enciende o apaga
bcf PORTA,0 ;
bsf PORTA,1 ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido automatico
btfsc PORTB,4 ; solo me fijo si necesita luz, cualquier otro estado queda en automatico con las luces apagadas
goto luzonini ; si  necesita (pata 4 del puerto B esta en 1, pidiendo luz), salto la llamada a la subrutina de encendido
luzoffini call luzautooff ; voy a la subrutina de apagado, por estar la pata 4 del puerto B en 0 (no esta pidiendo luz)
goto salluzauto ; apagados las luces, salto el renglon, donde se hace la llamada a encendido de luces
luzonini call luzautoon ; llego hasta aca con el goto de 3 renglones arriba, para encender las luces
salluzauto return


luzmanoff ; inicializacion de apagado manual de luces
bcf PORTA,0 ;
bcf PORTA,1 ; junto al renglon anterior, apago el led bicolor: estado apagado manual
bcf PORTA,4 ; apago las luces
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,4 ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bcf TRISB,5 ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
clrf el ; reinicio estado de las luces a 0
return


ventis ; subrutinas de eventos según los estados de los ventiladores
incf ev,F ; paso al proximo estado de las luces
movf ev,W ; paso el valor de ev a W
sublw 1 ; resto 1-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call venmanon ; la resta fue cero, va a la subrutina ventilador manual encendido
movf ev,W ; paso el valor de ev a W
sublw 2 ; resto 2-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call venauto ; la resta fue cero, va a la subrutina ventilador automatico
movf ev,W ; paso el valor de ev a W
sublw 3 ; resto 1-W (valor queda en W)
btfsc STATUS,2 ; si la resta no fue cero, salto un renglon
call venmanoff ; la resta fue cero, va a la subrutina ventilador manual apagado
return

venmanon ; inicializacion de encendido manual de ventiladores
bsf PORTA,2 ;
bcf PORTA,3 ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido manual
bsf PORTB,1 ; prendo los ventiladores
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,6 ; pongo a la pata 6 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bcf TRISB,7 ; pongo a la pata 7 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
return

venauto ; inicializacion de ventiladores automaticos. Se fija en el estado en el que esta la solicitud de ventilacion, y los enciende o apaga
bcf PORTA,2 ;
bsf PORTA,3 ; junto al renglon anterior, enciendo uno de los colores de led de salida: estado encendido automatico
btfsc PORTB,6 ; solo me fijo si necesita ventilacion, cualquier otro estado queda en automatico con los ventiladores apagados
goto venonini ; si  necesita (pata 6 del puerto B esta en 1, pidiendo ventilacion), salto la llamada a la subrutina de encendido
venoffini call venautooff ; voy a la subrutina de apagado, por estar la pata 6 del puerto B en 0 (no esta pidiendo ventilacion)
goto salvenauto ; apagados los ventiladores, salto el renglon, donde se hace la llamada a encendido de ventiladores
venonini call venautoon ; llego hasta aca con el goto de 3 renglones arriba, para encender los ventiladores
salvenauto return

venmanoff ; inicializacion de apagado manual de ventiladores
bcf PORTA,2 ;
bcf PORTA,3 ; junto al renglon anterior, apago el led bicolor: estado apagado manual
bcf PORTB,1 ; apago los ventiladores
bsf STATUS,RP0 ; paso al banco 1
bcf TRISB,6 ; pongo a la pata 4 de B en 0 (salida) para que no moleste el ingreso de encendido automatico
bcf TRISB,7 ; pongo a la pata 5 de B en 0 (salida) para que no moleste el ingreso de apagado automatico
bcf STATUS,RP0 ; vuelvo al banco 0
clrf ev ; reinicio estado de los ventiladores a 0
return

inicio bsf STATUS,RP0 ; paso al banco 1
movlw b'11111101' ; configuro al puerto b:EEEEEESE
movwf TRISB ; configuro al puerto b
clrf TRISA ; configuro al puerto a todo de salida
bcf STATUS,RP0 ; paso al banco 0
clrf PORTA ; pongo en 0 al puerto a
clrf PORTB ; pongo en 0 al puerto b
movlw b'10011000' ; configuracion interrupciones. Habilita general y habilita por RB0 y PORT B (4-7)
movwf INTCON ; configuracion interrupciones
clrf ev ; estado inicial de los ventiladores: 0, apagados
clrf el ; estado inicial de las luces: 0, apagadas

dormir nop ; bucle esperando interrupciones
goto dormir
end

« Última modificación: 10 de Febrero de 2015, 11:59:42 por xakko »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Controlador de luces y ventiladores con PIC
« Respuesta #10 en: 10 de Febrero de 2015, 11:46:29 »
Citar
los goto son saltos de dos o tres renglones dentro de una misma subrutina, para que eluda alguna otra subrutina.

Lo se.. pero vos estas agregando un GOTO cuando podes reemplazarlo por un RETURN listo, por eso dije que compares el codigo.
Esto no va a afectar en nada el funcionamiento del programa solo es que estas usando mas ciclos del procesador que necesitas.


Tema HW:

En la imagen, D1 y D4 no los necesitarias (ya que d2 y d3 funcionan como un circuito abierto para el caso que un solo switch este presionado), y las resistencia de pull-down solas no te van a servir de antirebote, dejale la resistencia de pull-down luego de D2 y D3 ( asi tiene un estado definido) y ante de los diodos (o si sacas D1 y D4 en el mismo lugar) un circuito antirebote para cada switch ( resistencia + condensador en paralelo, si sacas los diodos que dije, solo agregale el condesador en paralelo a los del switch ).
Para que cuando presiones el capacitor se carga rapidamente ( pero no se descarga tan rapido ) asi ante un rebote ( cuando el switch este en off ) el capacitor es el que de la tension y se mantenga ese 1 en el pin. Como solo se dispara en los flancos va a ingresar una sola ves nomas.

En fin... sos libre, cuando tengas un problema me paso de nuevo.
« Última modificación: 10 de Febrero de 2015, 11:51:35 por KILLERJC »

Desconectado xakko

  • PIC10
  • *
  • Mensajes: 8
Re: Controlador de luces y ventiladores con PIC
« Respuesta #11 en: 10 de Febrero de 2015, 13:10:21 »
gracias otra vez por opinar
el tema de los goto en vez de return directamente, es porque me gusta volver de una subrutina con un solo return (mañas mias nomas). se que los gotos no son muy lindos, pero prefiero ese movimiento a regresar de una subrutina de distintos lugares

tema hard: no me queda muy en claro por que sacar diodos. uso dos entradas, ya que una es interrupcion y la otra informa "quien" interrumpe, y no tienen que mezclarse las señales (RB2 con RB3). sino, si estas tratando de decirme otra cosa, no capto bien el punto.

ahi puse un par de capacitores de 100 nf a masa en la entrada directa de los switches

nuevamente gracias

Xakko

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Controlador de luces y ventiladores con PIC
« Respuesta #12 en: 10 de Febrero de 2015, 15:08:43 »
Te decia por lo siguiente...

Supongamos por un momento que los diodos son ideales y no poseen caida de tension. Y tambien que quitamos los diodos que te dije antes (D1 y D4). Acanalicemos el caso que se presionen uno u otro de los switches

Si presionas el switch de abajo. Vas a tener tension VCC en RB2 y RB0, y D2 queda inversamente polarizado por lo tanto no hay tension hacia RB3 (por lo tanto no se van a mezclar)
Si presionas el switch de arriba. Vas a tener VCC en RB3 y RB0 pero no tension en RB2 por el diodo D3 que queda en inversa.
Si presionas ambos, vas a tener VCC en RB0,RB3 y RB2.

Los demas diodos estan de mas.
La idea del antirebote:



Es decir de la salida de ambos circuitos anti rebotes (el de la izquierda es tu caso), esa salida va a ir a 2 lados 1 va a una entrada del PIC (RB2 o RB3) y el otro con un diodo a RB0 (los diodos forman una compuerta OR con una caida de tension por supuesto)

De tu diagrama, no haria falta nada mas que quitar D1 y D4 y queda exactamente como te digo.
Y sigo pensando que poner en salida los pines que tenes de entrada es mala idea. Lo podes resolver de otra forma. Pero bueno ahi lo dejo a tu criterio.

Citar
efectivamente, al no haber rutina de principal, no me preocupo por almacenar estados ni W
dado que el sistema tiene que "dejar andando" (o no) no hago una rutina principal, sino directamente todo en las interrupciones

Eso es otra cosa mala que estas haciendo... Nuevamente todo depende de vos.
« Última modificación: 10 de Febrero de 2015, 15:13:33 por KILLERJC »